From peter.levart at gmail.com Fri May 1 00:03:57 2015 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 01 May 2015 02:03:57 +0200 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <55423F39.6060304@oracle.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> Message-ID: <5542C2ED.1090100@gmail.com> On 04/30/2015 04:42 PM, Daniel Fuchs wrote: > On 28/04/15 17:46, Peter Levart wrote: >> >> >> On 04/28/2015 04:57 PM, Daniel Fuchs wrote: >>>> Here's my attempt at simplifying this: >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.01/ >>>> >>>> >>> >>> LogManager can be subclassed, and subclasses may override reset() for >>> different purposes. >>> So I'm afraid the Cleaner thread still needs to call te public >>> reset() method. The same unfortunately applies to >>> readConfiguration(). >>> >>> best regards, >>> >>> -- daniel >> >> Um, yes of course. This can be fixed: >> >> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.02/ >> > > Hi Peter, > > Sorry for the late reply. > > My gut feeling is that I dislike multi-state ints. > But I guess that's a matter of taste - so I could probably > overcome it ;-) Isn't that a simplification (of reasoning)? In particular if individual boolean flags are read and/or written without holding any lock. > > What makes me less happy is that I had managed to > remove the explicit synchronized() { } block in the > Cleaner thread - and I now see it's back. > > Could we maybe keep the imminentDeath boolean and remove > the explicit locking in the Cleaner thread? > > I mean... imminentDeath should be checked from within > the lock - before doing anything. But it does not need > to be set from within a locked section. > > best regards, > > -- daniel > Hi Daniel, Mandy, Explicit locking in Cleaner is something that is performed in reset() anyway, so getting rid of it is not actually getting rid of it, as Cleaner is calling reset() anyway. The lock is reentrant. But If you want get rid of it so that reset() is not called under lock held because reset() might be overridden, then imminentDeath must return. @Mandy: In webrev.01 we had a private reset(int newState), called from reset(), Cleaner and readConfiguration(), but Daniel then spotted that reset() is an overridable method, so it has to be called from Cleaner and readConfiguration() too, unfortunately. The STATE_XXX names are best depicted if looking at code in initializeGlobalHandlers() method. Let me prepare a changed webrew... Regards, Peter From chris.hegarty at oracle.com Fri May 1 09:54:22 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Fri, 01 May 2015 10:54:22 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> Message-ID: <55434D4E.1080305@oracle.com> This latest version addresses all comments so far: /** * Reads some bytes from the input stream into the given byte array. This * method blocks until {@code len} bytes of input data have been read, end * of stream is detected, or an exception is thrown. The number of bytes * actually read, possibly zero, is returned. This method does not close * the input stream. * *

In the case where end of stream is reached before {@code len} bytes * have been read, then the actual number of bytes read will be returned. * When this stream reaches end of stream, further invocations of this * method will return zero. * *

If {@code len} is zero, then no bytes are read and {@code 0} is * returned; otherwise, there is an attempt to read up to {@code len} bytes. * *

The first byte read is stored into element {@code b[off]}, the next * one in to {@code b[off+1]}, and so on. The number of bytes read is, at * most, equal to {@code len}. Let k be the number of bytes actually * read; these bytes will be stored in elements {@code b[off]} through * {@code b[off+}k{@code -1]}, leaving elements {@code b[off+}k * {@code ]} through {@code b[off+len-1]} unaffected. * *

In the case where {@code off > 0}, elements {@code b[0]} through * {@code b[off-1]} are unaffected. In every case, elements * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. * *

In every case, elements {@code b[0]} through {@code b[off-1]} and * elements {@code b[off+len]} through {@code b[b.length-1]} are unaffected. * *

The behavior for the case where the input stream is asynchronously * closed, or the thread interrupted during the read, is highly input * stream specific, and therefore not specified. * *

If an I/O error occurs reading from the input stream, then it may do * so after some, but not all, bytes of {@code b} have been updated with * data from the input stream. Consequently the input stream and {@code b} * may be in an inconsistent state. It is strongly recommended that the * stream be promptly closed if an I/O error occurs. * * @param b the buffer into which the data is read * @param off the start offset in {@code b} at which the data is written * @param len the maximum number of bytes to read * @return the actual number of bytes read into the buffer * @throws IOException if an I/O error occurs * @throws NullPointerException if {@code b} is {@code null} * @throws IndexOutOfBoundsException If {@code off} is negative, {@code len} * is negative, or {@code len} is greater than {@code b.length - off} * * @since 1.9 */ public int readNBytes(byte[] b, int off, int len) throws IOException { Objects.requireNonNull(b); if (off < 0 || len < 0 || len > b.length - off) throw new IndexOutOfBoundsException(); int n = 0; while (n < len) { int count = read(b, off + n, len - n); if (count < 0) break; n += count; } return n; } -Chris. On 24/04/15 09:44, Chris Hegarty wrote: > On 23 Apr 2015, at 22:24, Roger Riggs wrote: > >> Hi Pavel, >> >> On 4/23/2015 5:12 PM, Pavel Rappo wrote: >>> Hey Roger, >>> >>> 1. Good catch! This thing also applies to java.io.InputStream.read(byte[], int, int): > > Yes, good catch indeed. > >>> *

In every case, elements b[0] through >>> * b[off] and elements b[off+len] through >>> * b[b.length-1] are unaffected. >>> >>> I suppose the javadoc for the method proposed by Chris has started its life as a >>> copy of the javadoc read(byte[], int, int) which was assumed to be perfectly >>> polished. Unfortunately it was a false assumption. >> it happens... many many people have read those descriptions (or didn't because >> it was too obvious or thought to be redundant). > > I propose this small amendment. > > *

In the case where {@code off > 0}, elements {@code b[0]} through > * {@code b[off-1]} are unaffected. In every case, elements > * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. > >>> >>> 2. About awkward sentences. This paragraph also has to be rephrased for the same reason: >>> >>> *

The first byte read is stored into element {@code b[off]}, the next >>> * one in to {@code b[off+1]}, and so on. The number of bytes read is, at >>> * most, equal to {@code len}. Let k be the number of bytes actually >>> * read; these bytes will be stored in elements {@code b[off]} through >>> * {@code b[off+}k{@code -1]}, leaving elements {@code b[off+}k >>> * {@code ]} through {@code b[off+len-1]} unaffected. >>> >>> If k == 0 then spec claims to store values in b[off]... b[off - 1]. > > Reading the whole method description leads to be believe that 'k' cannot equal 0 at this point. The previous paragraph handles the case where len is 0. The previous paragraph to that handles the EOF case. This paragraph implicitly implies that k is greater than 0, ?The first byte read?, and ?the number of actual bytes read?, neither of which can be 0 at this point. > > I included below [*] the latest version of this method, including all comments so far. > >> If one concludes that's an empty interval then its ok; it just reads oddly and can >> make the reader think its wrong. >> In some cases it is easier if the upper bound is defined to be exclusive. >> Then if lower == upper, its empty. >> >> If better language were constructed for the new method then perhaps it could >> be worked back into methods with similar behavior later. If the wording changes >> in any significant way, the conformance team will have to go back and re-evaluate >> it in detail to see if it really has changed. So I'd leave it alone. >> >> Roger > > -Chris. > > [*] > > /** > * Reads some bytes from the input stream into the given byte array. This > * method blocks until {@code len} bytes of input data have been read, end > * of stream is detected, or an exception is thrown. The number of bytes > * actually read, possibly zero, is returned. This method does not close > * the input stream. > * > *

In the case where end of stream is reached before {@code len} bytes > * have been read, then the actual number of bytes read will be returned. > * When this stream reaches end of stream, further invocations of this > * method will return zero. > * > *

If {@code len} is zero, then no bytes are read and {@code 0} is > * returned; otherwise, there is an attempt to read up to {@code len} bytes. > * > *

The first byte read is stored into element {@code b[off]}, the next > * one in to {@code b[off+1]}, and so on. The number of bytes read is, at > * most, equal to {@code len}. Let k be the number of bytes actually > * read; these bytes will be stored in elements {@code b[off]} through > * {@code b[off+}k{@code -1]}, leaving elements {@code b[off+}k > * {@code ]} through {@code b[off+len-1]} unaffected. > * > *

In the case where {@code off > 0}, elements {@code b[0]} through > * {@code b[off-1]} are unaffected. In every case, elements > * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. > * > *

In every case, elements {@code b[0]} through {@code b[off-1]} and > * elements {@code b[off+len]} through {@code b[b.length-1]} are unaffected. > * > *

The behavior for the case where the input stream is asynchronously > * closed, or the thread interrupted during the read, is highly input > * stream specific, and therefore not specified. > * > *

If an I/O error occurs reading from the input stream, then it may do > * so after some, but not all, bytes of {@code b} have been updated with > * data from the input stream. Consequently the input stream and {@code b} > * may be in an inconsistent state. It is strongly recommended that the > * stream be promptly closed if an I/O error occurs. > * > * @param b the buffer into which the data is read > * @param off the start offset in {@code b} at which the data is written > * @param len the maximum number of bytes to read > * @return the actual number of bytes read into the buffer > * @throws IOException if an I/O error occurs > * @throws NullPointerException if {@code b} is {@code null} > * @throws IndexOutOfBoundsException If {@code off} is negative, {@code len} > * is negative, or {@code len} is greater than {@code b.length - off} > * > * @since 1.9 > */ > public int readNBytes(byte[] b, int off, int len) throws IOException { > Objects.requireNonNull(b); > if (off < 0 || len < 0 || len > b.length - off) > throw new IndexOutOfBoundsException(); > int n = 0; > while (n < len) { > int count = read(b, off + n, len - n); > if (count < 0) > break; > n += count; > } > return n; > } > From aleksey.shipilev at oracle.com Fri May 1 14:09:06 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Fri, 01 May 2015 17:09:06 +0300 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <553A85EA.5090603@oracle.com> References: <553A85EA.5090603@oracle.com> Message-ID: <55438902.4000307@oracle.com> Anyone? -Aleksey On 04/24/2015 09:05 PM, Aleksey Shipilev wrote: > Hi, > > This seems to be a simple one-liner fix, but the background is more > complicated. See the bug: > https://bugs.openjdk.java.net/browse/JDK-8076759 > > The bottom line is that our current resizing policy in ASB is hostile > for long appends. There is a heuristics that extends the capacity to > match the *exact* length of append if doubling the array would not help. > > This heuristics has a nasty corner case: if there is an upcoming append > after a large one, then we are guaranteed to re-size again. If an > upcoming append is large in itself, the resizing is inevitable even > under the doubling-the-storage strategy; but if we only do a small > append, then we can be smarter. > > After trying a few options to fix this (see below), I have settled on > just adding a simple static "pad", to absorb the trivial appends after a > large append: > http://cr.openjdk.java.net/~shade/8076759/webrev.00/ > > The choice of "32" as magic number is deliberate: arraycopy likes large > power-of-two strides (and it does not like to make catch up loops for > small residuals). "16" is too small to fit the decimal representation of > Long.MIN_VALUE, therefore, we pick "32". > > There are other approaches, briefly mentioned here: > http://cr.openjdk.java.net/~shade/8076759/patches.txt > > There is a direct correlation between the allocation pressure, and test > performance: > http://cr.openjdk.java.net/~shade/8076759/data-perf.png > http://cr.openjdk.java.net/~shade/8076759/data-foot.png > > Naively, one could expect doubling the storage ("mult2") until we reach > $minimalCapacity solves the problem, but it wastes too much memory, and > only reaches the "plus32" on power-of-two sizes. That is also the > Achilles' Heel of the heuristics, because appending the > power-of-two-plus-one-sized string will set us up for the original > problem. This effect can be alleviated by doing the padding as well > ("mult2-plus32"). Exactly the same trouble manifests on smaller strings > that go through the usual double-the-storage route, and this is why a > proposed patch makes the pad on common path. > > I do believe the current heuristics is smart about large appends, and > mult2* strategies undo it. Therefore, I would think keeping the > minimumCapacity cap is a good thing, and just adding the pad is a good > solution. Thus, it is in the webrev. > > Thanks, > -Aleksey. > From Roger.Riggs at Oracle.com Fri May 1 14:20:02 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 01 May 2015 10:20:02 -0400 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <55434D4E.1080305@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> Message-ID: <55438B92.4080701@Oracle.com> Hi Chris, There is some duplication in the descriptions of the buffer contents; see below. On 5/1/2015 5:54 AM, Chris Hegarty wrote: > This latest version addresses all comments so far: > > /** > * Reads some bytes from the input stream into the given byte array. This > * method blocks until {@code len} bytes of input data have been read, > end > * of stream is detected, or an exception is thrown. The number of bytes > * actually read, possibly zero, is returned. This method does not close > * the input stream. > * > *

In the case where end of stream is reached before {@code len} > bytes > * have been read, then the actual number of bytes read will be returned. > * When this stream reaches end of stream, further invocations of this > * method will return zero. > * > *

If {@code len} is zero, then no bytes are read and {@code 0} is > * returned; otherwise, there is an attempt to read up to {@code len} > bytes. > * > *

The first byte read is stored into element {@code b[off]}, the > next > * one in to {@code b[off+1]}, and so on. The number of bytes read is, at > * most, equal to {@code len}. _Let k be the number of bytes > actually __ > __ * read; these bytes will be stored in elements {@code b[off]} > through __ > __ * {@code b[off+}k{@code -1]}, leaving elements {@code > b[off+}k __ > __ * {@code ]} through {@code b[off+len-1]} unaffected. _ This section duplicates the previous sentence and the following sentence. > * > *

In the case where {@code off > 0}, elements {@code b[0]} through > * {@code b[off-1]} are unaffected. In every case, elements > * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. > * > _ *

In every case, elements {@code b[0]} through {@code b[off-1]} > and __ > __ * elements {@code b[off+len]} through {@code b[b.length-1]} are > unaffected. _ Duplicates previous paragraph. Each section of the buffer should be described only once. Regards, Roger > * > *

The behavior for the case where the input stream is > asynchronously > * closed, or the thread interrupted during the read, is highly input > * stream specific, and therefore not specified. > * > *

If an I/O error occurs reading from the input stream, then it > may _occur _do > * so__after some, but not all, bytes of {@code b} have been updated with > * data from the input stream. Consequently the input stream and > {@code b} > * may be in an inconsistent state. It is strongly recommended that the > * stream be promptly closed if an I/O error occurs. > * > * @param b the buffer into which the data is read > * @param off the start offset in {@code b} at which the data is written > * @param len the maximum number of bytes to read > * @return the actual number of bytes read into the buffer > * @throws IOException if an I/O error occurs > * @throws NullPointerException if {@code b} is {@code null} > * @throws IndexOutOfBoundsException If {@code off} is negative, > {@code len} > * is negative, or {@code len} is greater than {@code b.length > - off} > * > * @since 1.9 > */ > public int readNBytes(byte[] b, int off, int len) throws IOException { > Objects.requireNonNull(b); > if (off < 0 || len < 0 || len > b.length - off) > throw new IndexOutOfBoundsException(); > int n = 0; > while (n < len) { > int count = read(b, off + n, len - n); > if (count < 0) > break; > n += count; > } > return n; > } > > -Chris. > > On 24/04/15 09:44, Chris Hegarty wrote: >> On 23 Apr 2015, at 22:24, Roger Riggs wrote: >> >>> Hi Pavel, >>> >>> On 4/23/2015 5:12 PM, Pavel Rappo wrote: >>>> Hey Roger, >>>> >>>> 1. Good catch! This thing also applies to >>>> java.io.InputStream.read(byte[], int, int): >> >> Yes, good catch indeed. >> >>>> *

In every case, elements b[0] through >>>> * b[off] and elements b[off+len] >>>> through >>>> * b[b.length-1] are unaffected. >>>> >>>> I suppose the javadoc for the method proposed by Chris has started >>>> its life as a >>>> copy of the javadoc read(byte[], int, int) which was assumed to be >>>> perfectly >>>> polished. Unfortunately it was a false assumption. >>> it happens... many many people have read those descriptions (or >>> didn't because >>> it was too obvious or thought to be redundant). >> >> I propose this small amendment. >> >> *

In the case where {@code off > 0}, elements {@code b[0]} through >> * {@code b[off-1]} are unaffected. In every case, elements >> * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. >> >>>> >>>> 2. About awkward sentences. This paragraph also has to be rephrased >>>> for the same reason: >>>> >>>> *

The first byte read is stored into element {@code >>>> b[off]}, the next >>>> * one in to {@code b[off+1]}, and so on. The number of bytes >>>> read is, at >>>> * most, equal to {@code len}. Let k be the number of >>>> bytes actually >>>> * read; these bytes will be stored in elements {@code b[off]} >>>> through >>>> * {@code b[off+}k{@code -1]}, leaving elements {@code >>>> b[off+}k >>>> * {@code ]} through {@code b[off+len-1]} unaffected. >>>> >>>> If k == 0 then spec claims to store values in b[off]... b[off - 1]. >> >> Reading the whole method description leads to be believe that 'k' >> cannot equal 0 at this point. The previous paragraph handles the case >> where len is 0. The previous paragraph to that handles the EOF case. >> This paragraph implicitly implies that k is greater than 0, ?The >> first byte read?, and ?the number of actual bytes read?, neither of >> which can be 0 at this point. >> >> I included below [*] the latest version of this method, including all >> comments so far. >> >>> If one concludes that's an empty interval then its ok; it just reads >>> oddly and can >>> make the reader think its wrong. >>> In some cases it is easier if the upper bound is defined to be >>> exclusive. >>> Then if lower == upper, its empty. >>> >>> If better language were constructed for the new method then perhaps >>> it could >>> be worked back into methods with similar behavior later. If the >>> wording changes >>> in any significant way, the conformance team will have to go back >>> and re-evaluate >>> it in detail to see if it really has changed. So I'd leave it alone. >>> >>> Roger >> >> -Chris. >> >> [*] >> >> /** >> * Reads some bytes from the input stream into the given byte array. >> This >> * method blocks until {@code len} bytes of input data have been >> read, end >> * of stream is detected, or an exception is thrown. The number of >> bytes >> * actually read, possibly zero, is returned. This method does not >> close >> * the input stream. >> * >> *

In the case where end of stream is reached before {@code len} >> bytes >> * have been read, then the actual number of bytes read will be >> returned. >> * When this stream reaches end of stream, further invocations of this >> * method will return zero. >> * >> *

If {@code len} is zero, then no bytes are read and {@code 0} is >> * returned; otherwise, there is an attempt to read up to {@code >> len} bytes. >> * >> *

The first byte read is stored into element {@code b[off]}, >> the next >> * one in to {@code b[off+1]}, and so on. The number of bytes read >> is, at >> * most, equal to {@code len}. Let k be the number of bytes >> actually >> * read; these bytes will be stored in elements {@code b[off]} through >> * {@code b[off+}k{@code -1]}, leaving elements {@code >> b[off+}k >> * {@code ]} through {@code b[off+len-1]} unaffected. >> * >> *

In the case where {@code off > 0}, elements {@code b[0]} through >> * {@code b[off-1]} are unaffected. In every case, elements >> * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. >> * >> *

In every case, elements {@code b[0]} through {@code b[off-1]} >> and >> * elements {@code b[off+len]} through {@code b[b.length-1]} are >> unaffected. >> * >> *

The behavior for the case where the input stream is >> asynchronously >> * closed, or the thread interrupted during the read, is highly >> input >> * stream specific, and therefore not specified. >> * >> *

If an I/O error occurs reading from the input stream, then it >> may do >> * so after some, but not all, bytes of {@code b} have been updated >> with >> * data from the input stream. Consequently the input stream and >> {@code b} >> * may be in an inconsistent state. It is strongly recommended that the >> * stream be promptly closed if an I/O error occurs. >> * >> * @param b the buffer into which the data is read >> * @param off the start offset in {@code b} at which the data is >> written >> * @param len the maximum number of bytes to read >> * @return the actual number of bytes read into the buffer >> * @throws IOException if an I/O error occurs >> * @throws NullPointerException if {@code b} is {@code null} >> * @throws IndexOutOfBoundsException If {@code off} is negative, >> {@code len} >> * is negative, or {@code len} is greater than {@code >> b.length - off} >> * >> * @since 1.9 >> */ >> public int readNBytes(byte[] b, int off, int len) throws IOException { >> Objects.requireNonNull(b); >> if (off < 0 || len < 0 || len > b.length - off) >> throw new IndexOutOfBoundsException(); >> int n = 0; >> while (n < len) { >> int count = read(b, off + n, len - n); >> if (count < 0) >> break; >> n += count; >> } >> return n; >> } >> From Ulf.Zibis at CoSoCo.de Fri May 1 14:29:12 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Fri, 01 May 2015 16:29:12 +0200 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <553A85EA.5090603@oracle.com> References: <553A85EA.5090603@oracle.com> Message-ID: <55438DB8.9080502@CoSoCo.de> Hi Aleksey, I like this approach and to me the webrev looks good. -Ulf Am 24.04.2015 um 20:05 schrieb Aleksey Shipilev: > Hi, > > This seems to be a simple one-liner fix, but the background is more > complicated. See the bug: > https://bugs.openjdk.java.net/browse/JDK-8076759 > > http://cr.openjdk.java.net/~shade/8076759/webrev.00/ > From anthony.vanelverdinghe at gmail.com Fri May 1 14:51:43 2015 From: anthony.vanelverdinghe at gmail.com (Anthony Vanelverdinghe) Date: Fri, 01 May 2015 16:51:43 +0200 Subject: Unicode command-line parameters on Windows Message-ID: <554392FF.1030402@gmail.com> Hi I would like to use a Java program for Windows file associations. However, this doesn't work when the file to be opened contains non-ASCII Unicode characters in its path. There are several related issues about Windows Unicode support (e.g. JDK-4488646, JDK-4519026, JDK-4900150, JDK-6475368, JDK-6937897, JDK-8029584), some of which are resolved with "Future Project" and the last one having Fix Version 10 [1]. A while ago there was also a draft JEP about this with ID 8047097 [2]. However, the JEP is no longer available & the associated JDK issue is private. In January a code submission was proposed by Microsoft developers [3], but it's unclear from the thread what happened with the submission. From these observations, I'd guess there will be a "Windows Unicode support" project targeted for Java SE 10? Who can shed some light on the current plans for this? Will there be improvements in this area in Java SE 9? Thanks in advance, Anthony [1] https://bugs.openjdk.java.net/browse/JDK-8029584 [2] http://openjdk.java.net/jeps/8047097 [3] http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-January/031068.html From Roger.Riggs at Oracle.com Fri May 1 17:19:11 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 01 May 2015 13:19:11 -0400 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <55438902.4000307@oracle.com> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> Message-ID: <5543B58F.6020105@Oracle.com> Hi Aleksey, Is there any additional benefit by rounding up the next multiple of 4 or 8. That would avoid a few wasted bytes at the end of the buffer modulo the allocation size. Otherwise, looks fine to me also. Roger On 5/1/2015 10:09 AM, Aleksey Shipilev wrote: > Anyone? > > -Aleksey > > On 04/24/2015 09:05 PM, Aleksey Shipilev wrote: >> Hi, >> >> This seems to be a simple one-liner fix, but the background is more >> complicated. See the bug: >> https://bugs.openjdk.java.net/browse/JDK-8076759 >> >> The bottom line is that our current resizing policy in ASB is hostile >> for long appends. There is a heuristics that extends the capacity to >> match the *exact* length of append if doubling the array would not help. >> >> This heuristics has a nasty corner case: if there is an upcoming append >> after a large one, then we are guaranteed to re-size again. If an >> upcoming append is large in itself, the resizing is inevitable even >> under the doubling-the-storage strategy; but if we only do a small >> append, then we can be smarter. >> >> After trying a few options to fix this (see below), I have settled on >> just adding a simple static "pad", to absorb the trivial appends after a >> large append: >> http://cr.openjdk.java.net/~shade/8076759/webrev.00/ >> >> The choice of "32" as magic number is deliberate: arraycopy likes large >> power-of-two strides (and it does not like to make catch up loops for >> small residuals). "16" is too small to fit the decimal representation of >> Long.MIN_VALUE, therefore, we pick "32". >> >> There are other approaches, briefly mentioned here: >> http://cr.openjdk.java.net/~shade/8076759/patches.txt >> >> There is a direct correlation between the allocation pressure, and test >> performance: >> http://cr.openjdk.java.net/~shade/8076759/data-perf.png >> http://cr.openjdk.java.net/~shade/8076759/data-foot.png >> >> Naively, one could expect doubling the storage ("mult2") until we reach >> $minimalCapacity solves the problem, but it wastes too much memory, and >> only reaches the "plus32" on power-of-two sizes. That is also the >> Achilles' Heel of the heuristics, because appending the >> power-of-two-plus-one-sized string will set us up for the original >> problem. This effect can be alleviated by doing the padding as well >> ("mult2-plus32"). Exactly the same trouble manifests on smaller strings >> that go through the usual double-the-storage route, and this is why a >> proposed patch makes the pad on common path. >> >> I do believe the current heuristics is smart about large appends, and >> mult2* strategies undo it. Therefore, I would think keeping the >> minimumCapacity cap is a good thing, and just adding the pad is a good >> solution. Thus, it is in the webrev. >> >> Thanks, >> -Aleksey. >> > From ecki at zusammenkunft.net Fri May 1 19:14:34 2015 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Fri, 1 May 2015 21:14:34 +0200 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <5543B58F.6020105@Oracle.com> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> <5543B58F.6020105@Oracle.com> Message-ID: <20150501211434.00006263.ecki@zusammenkunft.net> Hello, btw just a small - maybe unrelated - observation on stock Java8u40. When benchmarking String.valueOf/Integer.toString/""+n with JMH I noticed that the compiler aided concatenation is the fastest, but not for all integer values. I asume this is related with the initial size of the buffer? https://gist.github.com/ecki/399136f4fd59c1d110c1 Gruss Bernd Am Fri, 01 May 2015 13:19:11 -0400 schrieb Roger Riggs : > Hi Aleksey, > > Is there any additional benefit by rounding up the next multiple of 4 > or 8. That would avoid a few wasted bytes at the end of the buffer > modulo the allocation size. > > Otherwise, looks fine to me also. From chris.hegarty at oracle.com Sat May 2 08:27:04 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Sat, 2 May 2015 09:27:04 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <55438B92.4080701@Oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> Message-ID: <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> Thanks for looking at this Roger. On 1 May 2015, at 15:20, Roger Riggs wrote: > Hi Chris, > > There is some duplication in the descriptions of the buffer contents; see below. > > On 5/1/2015 5:54 AM, Chris Hegarty wrote: >> This latest version addresses all comments so far: >> >> /** >> * Reads some bytes from the input stream into the given byte array. This >> * method blocks until {@code len} bytes of input data have been read, end >> * of stream is detected, or an exception is thrown. The number of bytes >> * actually read, possibly zero, is returned. This method does not close >> * the input stream. >> * >> *

In the case where end of stream is reached before {@code len} bytes >> * have been read, then the actual number of bytes read will be returned. >> * When this stream reaches end of stream, further invocations of this >> * method will return zero. >> * >> *

If {@code len} is zero, then no bytes are read and {@code 0} is >> * returned; otherwise, there is an attempt to read up to {@code len} bytes. >> * >> *

The first byte read is stored into element {@code b[off]}, the next >> * one in to {@code b[off+1]}, and so on. The number of bytes read is, at >> * most, equal to {@code len}. Let k be the number of bytes actually >> * read; these bytes will be stored in elements {@code b[off]} through >> * {@code b[off+}k{@code -1]}, leaving elements {@code b[off+}k >> * {@code ]} through {@code b[off+len-1]} unaffected. > This section duplicates the previous sentence and the following sentence. I don?t see these as being duplicates. The above states the case where some bytes have been read, while the paragraph below is always the case, regardless of whether any bytes are read. I see it as being explicit. >> * >> *

In the case where {@code off > 0}, elements {@code b[0]} through >> * {@code b[off-1]} are unaffected. In every case, elements >> * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. >> * >> *

In every case, elements {@code b[0]} through {@code b[off-1]} and >> * elements {@code b[off+len]} through {@code b[b.length-1]} are unaffected. > Duplicates previous paragraph. Thanks, this was an editing issue. Removed. As Alan has commented, another readAllBytes() returning a byte[] maybe useful too ( but a different use case ). Let?s park this momentarily, while I sketch up the readAllBytes variant, so we can ensure that the typical use cases have been addressed. Doing so may feedback into the spec of this method. I?ll push this latest draft into the sandbox so it is not lost. -Chris. > Each section of the buffer should be described only once. > > Regards, Roger > >> * >> *

The behavior for the case where the input stream is asynchronously >> * closed, or the thread interrupted during the read, is highly input >> * stream specific, and therefore not specified. >> * >> *

If an I/O error occurs reading from the input stream, then it may occur do >> * so after some, but not all, bytes of {@code b} have been updated with >> * data from the input stream. Consequently the input stream and {@code b} >> * may be in an inconsistent state. It is strongly recommended that the >> * stream be promptly closed if an I/O error occurs. >> * >> * @param b the buffer into which the data is read >> * @param off the start offset in {@code b} at which the data is written >> * @param len the maximum number of bytes to read >> * @return the actual number of bytes read into the buffer >> * @throws IOException if an I/O error occurs >> * @throws NullPointerException if {@code b} is {@code null} >> * @throws IndexOutOfBoundsException If {@code off} is negative, {@code len} >> * is negative, or {@code len} is greater than {@code b.length - off} >> * >> * @since 1.9 >> */ >> public int readNBytes(byte[] b, int off, int len) throws IOException { >> Objects.requireNonNull(b); >> if (off < 0 || len < 0 || len > b.length - off) >> throw new IndexOutOfBoundsException(); >> int n = 0; >> while (n < len) { >> int count = read(b, off + n, len - n); >> if (count < 0) >> break; >> n += count; >> } >> return n; >> } >> >> -Chris. >> >> On 24/04/15 09:44, Chris Hegarty wrote: >>> On 23 Apr 2015, at 22:24, Roger Riggs wrote: >>> >>>> Hi Pavel, >>>> >>>> On 4/23/2015 5:12 PM, Pavel Rappo wrote: >>>>> Hey Roger, >>>>> >>>>> 1. Good catch! This thing also applies to java.io.InputStream.read(byte[], int, int): >>> >>> Yes, good catch indeed. >>> >>>>> *

In every case, elements b[0] through >>>>> * b[off] and elements b[off+len] through >>>>> * b[b.length-1] are unaffected. >>>>> >>>>> I suppose the javadoc for the method proposed by Chris has started its life as a >>>>> copy of the javadoc read(byte[], int, int) which was assumed to be perfectly >>>>> polished. Unfortunately it was a false assumption. >>>> it happens... many many people have read those descriptions (or didn't because >>>> it was too obvious or thought to be redundant). >>> >>> I propose this small amendment. >>> >>> *

In the case where {@code off > 0}, elements {@code b[0]} through >>> * {@code b[off-1]} are unaffected. In every case, elements >>> * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. >>> >>>>> >>>>> 2. About awkward sentences. This paragraph also has to be rephrased for the same reason: >>>>> >>>>> *

The first byte read is stored into element {@code b[off]}, the next >>>>> * one in to {@code b[off+1]}, and so on. The number of bytes read is, at >>>>> * most, equal to {@code len}. Let k be the number of bytes actually >>>>> * read; these bytes will be stored in elements {@code b[off]} through >>>>> * {@code b[off+}k{@code -1]}, leaving elements {@code b[off+}k >>>>> * {@code ]} through {@code b[off+len-1]} unaffected. >>>>> >>>>> If k == 0 then spec claims to store values in b[off]... b[off - 1]. >>> >>> Reading the whole method description leads to be believe that 'k' cannot equal 0 at this point. The previous paragraph handles the case where len is 0. The previous paragraph to that handles the EOF case. This paragraph implicitly implies that k is greater than 0, ?The first byte read?, and ?the number of actual bytes read?, neither of which can be 0 at this point. >>> >>> I included below [*] the latest version of this method, including all comments so far. >>> >>>> If one concludes that's an empty interval then its ok; it just reads oddly and can >>>> make the reader think its wrong. >>>> In some cases it is easier if the upper bound is defined to be exclusive. >>>> Then if lower == upper, its empty. >>>> >>>> If better language were constructed for the new method then perhaps it could >>>> be worked back into methods with similar behavior later. If the wording changes >>>> in any significant way, the conformance team will have to go back and re-evaluate >>>> it in detail to see if it really has changed. So I'd leave it alone. >>>> >>>> Roger >>> >>> -Chris. >>> >>> [*] >>> >>> /** >>> * Reads some bytes from the input stream into the given byte array. This >>> * method blocks until {@code len} bytes of input data have been read, end >>> * of stream is detected, or an exception is thrown. The number of bytes >>> * actually read, possibly zero, is returned. This method does not close >>> * the input stream. >>> * >>> *

In the case where end of stream is reached before {@code len} bytes >>> * have been read, then the actual number of bytes read will be returned. >>> * When this stream reaches end of stream, further invocations of this >>> * method will return zero. >>> * >>> *

If {@code len} is zero, then no bytes are read and {@code 0} is >>> * returned; otherwise, there is an attempt to read up to {@code len} bytes. >>> * >>> *

The first byte read is stored into element {@code b[off]}, the next >>> * one in to {@code b[off+1]}, and so on. The number of bytes read is, at >>> * most, equal to {@code len}. Let k be the number of bytes actually >>> * read; these bytes will be stored in elements {@code b[off]} through >>> * {@code b[off+}k{@code -1]}, leaving elements {@code b[off+}k >>> * {@code ]} through {@code b[off+len-1]} unaffected. >>> * >>> *

In the case where {@code off > 0}, elements {@code b[0]} through >>> * {@code b[off-1]} are unaffected. In every case, elements >>> * {@code b[off+len]} through {@code b[b.length-1]} are unaffected. >>> * >>> *

In every case, elements {@code b[0]} through {@code b[off-1]} and >>> * elements {@code b[off+len]} through {@code b[b.length-1]} are unaffected. >>> * >>> *

The behavior for the case where the input stream is asynchronously >>> * closed, or the thread interrupted during the read, is highly input >>> * stream specific, and therefore not specified. >>> * >>> *

If an I/O error occurs reading from the input stream, then it may do >>> * so after some, but not all, bytes of {@code b} have been updated with >>> * data from the input stream. Consequently the input stream and {@code b} >>> * may be in an inconsistent state. It is strongly recommended that the >>> * stream be promptly closed if an I/O error occurs. >>> * >>> * @param b the buffer into which the data is read >>> * @param off the start offset in {@code b} at which the data is written >>> * @param len the maximum number of bytes to read >>> * @return the actual number of bytes read into the buffer >>> * @throws IOException if an I/O error occurs >>> * @throws NullPointerException if {@code b} is {@code null} >>> * @throws IndexOutOfBoundsException If {@code off} is negative, {@code len} >>> * is negative, or {@code len} is greater than {@code b.length - off} >>> * >>> * @since 1.9 >>> */ >>> public int readNBytes(byte[] b, int off, int len) throws IOException { >>> Objects.requireNonNull(b); >>> if (off < 0 || len < 0 || len > b.length - off) >>> throw new IndexOutOfBoundsException(); >>> int n = 0; >>> while (n < len) { >>> int count = read(b, off + n, len - n); >>> if (count < 0) >>> break; >>> n += count; >>> } >>> return n; >>> } >>> > From forax at univ-mlv.fr Sat May 2 14:41:31 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 02 May 2015 16:41:31 +0200 Subject: Additional method on Stream In-Reply-To: <019DEEBC-592A-4571-9B1B-DC8278E21A19@oracle.com> References: <10F26F8C-3F79-45B9-9D06-C2F0CDCF59D7@oracle.com> <019DEEBC-592A-4571-9B1B-DC8278E21A19@oracle.com> Message-ID: <5544E21B.1080002@univ-mlv.fr> On 04/28/2015 03:05 PM, Paul Sandoz wrote: [...] > >> I do understand the desire to control methods, but API design isn't >> just about minimalism, it is also about meeting common use cases in a >> natural way. The parallel is of course a standard if (obj instanceof >> Foo) statement in Java, where developers often curse that they have to >> additionally cast obj after the check. > I believe Ceylon might also do contextual type narrowing. I dunno how easy it would to modify the Java language and javac to do similar things. A separate discussion to be had... I think this was discussed on the coin project mailing list when talking about the precise re-throw of exception. The main issue is that a more precise type will select another overload than the one that javac currently select: class A {} class B extends A {} class Bar { void foo(A a) { ... } void foo(B b) { ... } } Let suppose we have this code: A a = ... if (a instanceof B) { foo(a); } without narrowing, it will call foo(A), with narrowing, it will call foo(B). R?mi From forax at univ-mlv.fr Sat May 2 21:31:45 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 02 May 2015 23:31:45 +0200 Subject: Add Predicate.of(), Consumer.of(), etc. Message-ID: <55454241.8030409@univ-mlv.fr> Hi all, today, I stubble on a variant of JDK-8050818 [1], trying to call negate() on a lambda which is not yet a Predicate (due to target typing) which requires either to cast the lambda to a Predicate and everybody knows that cast are evil or to add a local variable. I think there is a way to fix that, it's not very orthodox so I let you judge. The idea is to introduce a static method 'of' on Predicate, class Predicate { ... public static Predicate of(Predicate predicate) { return predicate; } } so one can write: stream.filter(Predicate.of(String::isEmpty).negate()) compared to stream.filter(((Predicate)String::isEmpty).negate()) so the question is, does it it worth the cost to introduce a static method that basically do nothing on all functional interfaces of java.util.function. cheers, R?mi [1] https://bugs.openjdk.java.net/browse/JDK-8050818 From Sunny.Chan at gs.com Mon May 4 07:39:47 2015 From: Sunny.Chan at gs.com (Chan, Sunny) Date: Mon, 4 May 2015 15:39:47 +0800 Subject: Patch to improve primitives Array.sort() In-Reply-To: <553A0832.7070702@oracle.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> Message-ID: <1CF6FDFD0639DF478B44651D79ECE70401146C4C41@GSCMHKP12EX.firmwide.corp.gs.com> Hi Alan, Can you point us to the benchmarks that were created? I look back at the archive which mentions some benchmark but the sources doesn't look like they have been made available on OpenJDK - are they available somewhere else? (original discussion on DP quicksort implementation: http://permalink.gmane.org/gmane.comp.java.openjdk.core-libs.devel/2628) Sunny -----Original Message----- From: Alan Bateman [mailto:Alan.Bateman at oracle.com] Sent: 24 April 2015 17:09 To: Paul Sandoz; Chan, Sunny [Tech] Cc: 'core-libs-dev at openjdk.java.net'; O'Leary, Kristen [Tech] Subject: Re: Patch to improve primitives Array.sort() On 24/04/2015 09:57, Paul Sandoz wrote: > See here: > > http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev/ > > Some very quick comments as i have not yet had time to review more closely: > > - IANAL so i dunno about the GS copyright in the files. > > - The constant MAX_RUN_LENGTH is no longer used so could be removed. But i would like to understand why it's no longer required. > > - There is quite a bit of duplication in the tests. AFAICT data sources are all derived from ints that are then converted. The sources could be data providers, so only one test method per data type is required, each data can come with a descriptive string so it shows up in the test reports. The goal here being if another source of data is added (which is derivable) it could be added just once. > Also overall with the existing Sorting test should be examined as it tests a lot of cases with varying data sizes (and consequentially runs for a long time). We should also go back through the archives for all the other benchmarks that were created in the move to the dual pivot implementation. -Alan From peter.levart at gmail.com Mon May 4 08:16:42 2015 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 04 May 2015 10:16:42 +0200 Subject: RFR: JDK-8074003 java.time.zone.ZoneRules.getOffset(java.time.Instant) can be optimized In-Reply-To: <55422458.1040202@Oracle.com> References: <553E62D6.9030102@gmail.com> <5540A572.5@gmail.com> <5540DD22.1000503@Oracle.com> <5540F83C.2080100@gmail.com> <5540FA33.60009@Oracle.com> <554202D7.5030407@gmail.com> <55422458.1040202@Oracle.com> Message-ID: <55472AEA.7080607@gmail.com> Stephen, Roger, Thanks for reviews. This has been pushed to jdk9-dev. Regards, Peter On 04/30/2015 02:47 PM, Roger Riggs wrote: > Hi Peter, > > Yes, go ahead with the patch as is. > > Thanks, Roger > > > On 4/30/2015 6:24 AM, Peter Levart wrote: >> >> On 04/29/2015 05:35 PM, Roger Riggs wrote: >>> Hi Peter, >>> >>> There should be two changesets; so pretend the truncation has been >>> performed for this change. >>> It maybe useful to backport the performance improvement to jdk 8 but >>> the spec change >>> will have to be in 9 (or wait for a maintenance release). >>> >> >> Hi Roger, >> >> So perhaps it would be best to push what we have in webrev.03 now, so >> that it can be backported to 8u directly without modifications and >> simplify equals/compareTo/getInstant as part of the changeset for >> 8079063. I think this is more consistent. And I can prepare the >> change for 8079063 right away so the spec change process can be started. >> >> Do I have a go for webrev.03 for jdk9 ? >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneOffsetTransition.epochSecond/webrev.03/ >> >> >> Regards, Peter >> >>> The simplification of toInstant can happen with the changeset for >>> 8079063. >>> >>> Thanks, Roger >>> >>> >>> On 4/29/2015 11:26 AM, Peter Levart wrote: >>>> >>>> >>>> On 04/29/2015 03:31 PM, Roger Riggs wrote: >>>>> Hi Peter, >>>>> >>>>> Point taken about the constructor and that should have a spec >>>>> clarification to ignore the nanoseconds. >>>>> The issue is tracked with: >>>>> JDK-8079063 >>>>> ZoneOffsetTransition constructor should ignore nanoseconds >>>>> >>>>> With that, the compareTo method can be simpler. The rest looks fine. >>>>> >>>>> Roger >>>> >>>> Hi Roger, >>>> >>>> Should I prepare a patch for both issues in one changeset as the >>>> correct compareTo/equals depends on the truncation or should I just >>>> pretend that truncation has been performed and make this change >>>> accordingly or should I 1st do the JDK-8079063 and then this one on >>>> top? >>>> >>>> Also, getInstant() can be much simpler if the truncation is >>>> performed: return Instant.of(epochSecond); >>>> >>>> Regards, Peter >>>> >>>>> >>>>> >>>>> On 4/29/2015 5:33 AM, Peter Levart wrote: >>>>>> >>>>>> On 04/27/2015 06:51 PM, Stephen Colebourne wrote: >>>>>>> One additional change is needed. The compareTo() method can rely on >>>>>>> the new epochSecond field as well. >>>>>>> Otherwise good! >>>>>>> Stephen >>>>>> >>>>>> Hi Stephen, >>>>>> >>>>>> LocalDateTime (transition) has nanosecond precision. It may be >>>>>> that transitions loaded from file in ZoneRules only have second >>>>>> precisions, but ZoneOffsetTransition is a public class with >>>>>> public factory method that takes a LocalDateTime transition >>>>>> parameter, so I think compareTo() can't rely on epochSecond >>>>>> alone. But epochSecond can be used as optimization in compareTo() >>>>>> as well as equals(): >>>>>> >>>>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneOffsetTransition.epochSecond/webrev.03/ >>>>>> >>>>>> >>>>>> An alternative to keeping epochSecond field in >>>>>> ZoneOffsetTransition would be to keep a reference to Instant >>>>>> instead. Instant contains an epochSecond field (as well as nanos) >>>>>> and could be used for both toEpochSecond() and getInstant() methods. >>>>>> >>>>>> What do you think? >>>>>> >>>>>> It also occurred to me that serialization format of >>>>>> ZoneOffsetTransition is not adequate currently as it looses >>>>>> nanosecond precision. >>>>>> >>>>>> Regards, Peter >>>>>> >>>>>>> >>>>>>> On 27 April 2015 at 17:24, Peter Levart >>>>>>> wrote: >>>>>>>> Hi again, >>>>>>>> >>>>>>>> Here's another optimization to be reviewed that has been >>>>>>>> discussed a while >>>>>>>> ago (just rebased from webrev.01) and approved by Stephen: >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneOffsetTransition.epochSecond/webrev.02/ >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> The discussion about it is intermingled with the >>>>>>>> ZoneId.systemDefault() >>>>>>>> discussion and starts about here: >>>>>>>> >>>>>>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-February/031873.html >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> The rationale for the optimization is speeding-up the >>>>>>>> conversion from epoch >>>>>>>> time to LocalDateTime. This conversion uses >>>>>>>> ZoneRules.getOffset(Instant) >>>>>>>> where there is a loop over ZoneOffsetTransition[] array that >>>>>>>> searches for >>>>>>>> 1st transition that has its toEpochSecond value less than the >>>>>>>> Instant's >>>>>>>> epochSecond. This calls ZoneOffsetTransition.toEpochSecond >>>>>>>> repeatedly, >>>>>>>> converting ZoneOffsetTransition.transition which is a >>>>>>>> LocalDateTime to >>>>>>>> epochSecond. This repeated conversion is unnecessary, as >>>>>>>> ZoneOffsetTransition[] array is part of ZoneRules which is cached. >>>>>>>> Optimizing the ZoneOffsetTransition implementation (keeping both >>>>>>>> LocalDateTime variant and eposhSecond variant of transition >>>>>>>> time as the >>>>>>>> object's state) speeds up this conversion. >>>>>>>> >>>>>>>> >>>>>>>> Regards, Peter >>>>>>>> >>>>>> >>>>> >>>> >>> >> > From peter.levart at gmail.com Mon May 4 10:22:30 2015 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 04 May 2015 12:22:30 +0200 Subject: RFR: JDK-8079063 ZoneOffsetTransition constructor should ignore nanoseconds Message-ID: <55474866.3020506@gmail.com> Hi, Now that JDK-8074003 is in, I'd like to discuss how to tackle JDK-8079063. Package-private ZoneOffsetTransition constructor that takes LocalDateTime transition is invoked from the following 4 places: 1 - the public static factory method: /** * Obtains an instance defining a transition between two offsets. *

* Applications should normally obtain an instance from {@link ZoneRules}. * This factory is only intended for use when creating {@link ZoneRules}. * * @param transition the transition date-time at the transition, which never * actually occurs, expressed local to the before offset, not null * @param offsetBefore the offset before the transition, not null * @param offsetAfter the offset at and after the transition, not null * @return the transition, not null * @throws IllegalArgumentException if {@code offsetBefore} and {@code offsetAfter} * are equal, or {@code transition.getNano()} returns non-zero value */ public static ZoneOffsetTransition of(LocalDateTime transition, ZoneOffset offsetBefore, ZoneOffset offsetAfter) { ...this one already disallows transition parameters that have transition.getNano() != 0. 2 - Lines 498..500 of ZoneOffsetTransitionRule: LocalDateTime localDT = LocalDateTime.of(date, time); LocalDateTime transition = timeDefinition.createDateTime(localDT, standardOffset, offsetBefore); return new ZoneOffsetTransition(transition, offsetBefore, offsetAfter); ...where 'time' is an instance field of ZoneOffsetTransitionRule. The ZoneOffsetTransitionRule public static factory method has the following definition: /** * Obtains an instance defining the yearly rule to create transitions between two offsets. *

* Applications should normally obtain an instance from {@link ZoneRules}. * This factory is only intended for use when creating {@link ZoneRules}. * * @param month the month of the month-day of the first day of the cutover week, not null * @param dayOfMonthIndicator the day of the month-day of the cutover week, positive if the week is that * day or later, negative if the week is that day or earlier, counting from the last day of the month, * from -28 to 31 excluding 0 * @param dayOfWeek the required day-of-week, null if the month-day should not be changed * @param time the cutover time in the 'before' offset, not null * @param timeEndOfDay whether the time is midnight at the end of day * @param timeDefnition how to interpret the cutover * @param standardOffset the standard offset in force at the cutover, not null * @param offsetBefore the offset before the cutover, not null * @param offsetAfter the offset after the cutover, not null * @return the rule, not null * @throws IllegalArgumentException if the day of month indicator is invalid * @throws IllegalArgumentException if the end of day flag is true when the time is not midnight */ public static ZoneOffsetTransitionRule of( Month month, int dayOfMonthIndicator, DayOfWeek dayOfWeek, LocalTime time, boolean timeEndOfDay, TimeDefinition timeDefnition, ZoneOffset standardOffset, ZoneOffset offsetBefore, ZoneOffset offsetAfter) { Objects.requireNonNull(month, "month"); Objects.requireNonNull(time, "time"); Objects.requireNonNull(timeDefnition, "timeDefnition"); Objects.requireNonNull(standardOffset, "standardOffset"); Objects.requireNonNull(offsetBefore, "offsetBefore"); Objects.requireNonNull(offsetAfter, "offsetAfter"); if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || dayOfMonthIndicator == 0) { throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 inclusive excluding zero"); } if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == false) { throw new IllegalArgumentException("Time must be midnight when end of day flag is true"); } return new ZoneOffsetTransitionRule(month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay, timeDefnition, standardOffset, offsetBefore, offsetAfter); } ...which allows 'time' parameter (that becomes ZoneOffsetTransitionRule's 'time' field) with no restriction as to whether it can contain nanos != 0 or not. 3, 4 - Lines 668..678 of ZoneRules private getOffsetInfo method: LocalDateTime dtBefore = savingsLocalTransitions[index]; LocalDateTime dtAfter = savingsLocalTransitions[index + 1]; ZoneOffset offsetBefore = wallOffsets[index / 2]; ZoneOffset offsetAfter = wallOffsets[index / 2 + 1]; if (offsetAfter.getTotalSeconds() > offsetBefore.getTotalSeconds()) { // gap return new ZoneOffsetTransition(dtBefore, offsetBefore, offsetAfter); } else { // overlap return new ZoneOffsetTransition(dtAfter, offsetBefore, offsetAfter); } ...where dtBefore/dtAfter "transition" parameters are taken from savingsLocalTransitions[] array that is filled-in in ZoneRules constructors from passed-in ZoneOffsetTransition objects. So here no nanos != 0 can sneak in if ZoneOffsetTransition invariant holds. The only place where nanos can sneak-in therefore seems to be the public ZoneOffsetTransitionRule.of() factory method. The question is whether the spec. could be changed so that ZoneOffsetTransitionRule.of() factory method would add another @throws definition: * @throws IllegalArgumentException if {@code time.getNano()} returns non-zero value This, I think, would be consistent with ZoneOffsetTransition.of() factory method and I believe early enough in the live of the API so that no custom software would be affected: http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneOffsetTransitionRule.time/webrev.01/ What do you think? Regards, Peter From aleksey.shipilev at oracle.com Mon May 4 12:49:58 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 04 May 2015 15:49:58 +0300 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <20150501211434.00006263.ecki@zusammenkunft.net> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> <5543B58F.6020105@Oracle.com> <20150501211434.00006263.ecki@zusammenkunft.net> Message-ID: <55476AF6.9010202@oracle.com> On 05/01/2015 10:14 PM, Bernd Eckenfels wrote: > btw just a small - maybe unrelated - observation on stock Java8u40. When > benchmarking String.valueOf/Integer.toString/""+n with JMH I noticed > that the compiler aided concatenation is the fastest, String concat desugaring and optimizations is a separate topic, unrelated to the issue at hand. Let's not sidetrack. > but not for all integer values. You have to notice the errors are quite large, so you can't really tell if StringConcat is "slower" on 2147483647. > https://gist.github.com/ecki/399136f4fd59c1d110c1 Thanks, -Aleksey From peter.levart at gmail.com Mon May 4 13:26:02 2015 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 04 May 2015 15:26:02 +0200 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <5542C2ED.1090100@gmail.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> <5542C2ED.1090100@gmail.com> Message-ID: <5547736A.4060805@gmail.com> Hi Daniel, Mandy, What about the following: http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.03/ You see, no boolean flags needed. The globalHandlersState is always changed atomically within a locked region, so a graph of transitions can be drawn: http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/LogManager.globalHandlersState.png STATE_INITIALIZING and STATE_READING_CONFIG are intra-locked-region states used to prevent infinite recursion in initializeGlobalHandlers() and communicating state from within locked-region of readConfiguration() to nested reset(), respectively, but never from one locked region to another. Regards, Peter On 05/01/2015 02:03 AM, Peter Levart wrote: > > > On 04/30/2015 04:42 PM, Daniel Fuchs wrote: >> On 28/04/15 17:46, Peter Levart wrote: >>> >>> >>> On 04/28/2015 04:57 PM, Daniel Fuchs wrote: >>>>> Here's my attempt at simplifying this: >>>>> >>>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.01/ >>>>> >>>>> >>>> >>>> LogManager can be subclassed, and subclasses may override reset() for >>>> different purposes. >>>> So I'm afraid the Cleaner thread still needs to call te public >>>> reset() method. The same unfortunately applies to >>>> readConfiguration(). >>>> >>>> best regards, >>>> >>>> -- daniel >>> >>> Um, yes of course. This can be fixed: >>> >>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.02/ >>> >> >> Hi Peter, >> >> Sorry for the late reply. >> >> My gut feeling is that I dislike multi-state ints. >> But I guess that's a matter of taste - so I could probably >> overcome it ;-) > > Isn't that a simplification (of reasoning)? In particular if > individual boolean flags are read and/or written without holding any lock. > >> >> What makes me less happy is that I had managed to >> remove the explicit synchronized() { } block in the >> Cleaner thread - and I now see it's back. >> >> Could we maybe keep the imminentDeath boolean and remove >> the explicit locking in the Cleaner thread? >> >> I mean... imminentDeath should be checked from within >> the lock - before doing anything. But it does not need >> to be set from within a locked section. >> >> best regards, >> >> -- daniel >> > > > Hi Daniel, Mandy, > > Explicit locking in Cleaner is something that is performed in reset() > anyway, so getting rid of it is not actually getting rid of it, as > Cleaner is calling reset() anyway. The lock is reentrant. > > But If you want get rid of it so that reset() is not called under lock > held because reset() might be overridden, then imminentDeath must return. > > @Mandy: > > In webrev.01 we had a private reset(int newState), called from > reset(), Cleaner and readConfiguration(), but Daniel then spotted that > reset() is an overridable method, so it has to be called from Cleaner > and readConfiguration() too, unfortunately. > > The STATE_XXX names are best depicted if looking at code in > initializeGlobalHandlers() method. > > Let me prepare a changed webrew... > > Regards, Peter > From daniel.fuchs at oracle.com Mon May 4 13:46:32 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Mon, 04 May 2015 15:46:32 +0200 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <5547736A.4060805@gmail.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> <5542C2ED.1090100@gmail.com> <5547736A.4060805@gmail.com> Message-ID: <55477838.6020200@oracle.com> On 04/05/15 15:26, Peter Levart wrote: > Hi Daniel, Mandy, > > What about the following: > > http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.03/ > > You see, no boolean flags needed. The globalHandlersState is always > changed atomically within a locked region, so a graph of transitions can > be drawn: > > http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/LogManager.globalHandlersState.png > > STATE_INITIALIZING and STATE_READING_CONFIG are intra-locked-region > states used to prevent infinite recursion in initializeGlobalHandlers() > and communicating state from within locked-region of readConfiguration() > to nested reset(), respectively, but never from one locked region to > another. That looks better. I would consider removing these lines: 1333 if (globalHandlersState == STATE_SHUTDOWN) { 1334 // already in terminal state 1335 return; 1336 } in favor of: 1354 } else if (globalHandlersState != STATE_SHUTDOWN) { 1355 // ...user calling reset()... and let the reset reset twice if it's called from different contexts. There may be permissions that could prevent a user-called reset() to close all handlers, and we don't want that to prevent the Cleaner-called reset to come afterwards and perform its job. BTW - in the end - one of us will need to push this together with the new test :-) cheers, -- daniel > > Regards, Peter > > On 05/01/2015 02:03 AM, Peter Levart wrote: >> >> >> On 04/30/2015 04:42 PM, Daniel Fuchs wrote: >>> On 28/04/15 17:46, Peter Levart wrote: >>>> >>>> >>>> On 04/28/2015 04:57 PM, Daniel Fuchs wrote: >>>>>> Here's my attempt at simplifying this: >>>>>> >>>>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.01/ >>>>>> >>>>>> >>>>> >>>>> LogManager can be subclassed, and subclasses may override reset() for >>>>> different purposes. >>>>> So I'm afraid the Cleaner thread still needs to call te public >>>>> reset() method. The same unfortunately applies to >>>>> readConfiguration(). >>>>> >>>>> best regards, >>>>> >>>>> -- daniel >>>> >>>> Um, yes of course. This can be fixed: >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.02/ >>>> >>> >>> Hi Peter, >>> >>> Sorry for the late reply. >>> >>> My gut feeling is that I dislike multi-state ints. >>> But I guess that's a matter of taste - so I could probably >>> overcome it ;-) >> >> Isn't that a simplification (of reasoning)? In particular if >> individual boolean flags are read and/or written without holding any lock. >> >>> >>> What makes me less happy is that I had managed to >>> remove the explicit synchronized() { } block in the >>> Cleaner thread - and I now see it's back. >>> >>> Could we maybe keep the imminentDeath boolean and remove >>> the explicit locking in the Cleaner thread? >>> >>> I mean... imminentDeath should be checked from within >>> the lock - before doing anything. But it does not need >>> to be set from within a locked section. >>> >>> best regards, >>> >>> -- daniel >>> >> >> >> Hi Daniel, Mandy, >> >> Explicit locking in Cleaner is something that is performed in reset() >> anyway, so getting rid of it is not actually getting rid of it, as >> Cleaner is calling reset() anyway. The lock is reentrant. >> >> But If you want get rid of it so that reset() is not called under lock >> held because reset() might be overridden, then imminentDeath must return. >> >> @Mandy: >> >> In webrev.01 we had a private reset(int newState), called from >> reset(), Cleaner and readConfiguration(), but Daniel then spotted that >> reset() is an overridable method, so it has to be called from Cleaner >> and readConfiguration() too, unfortunately. >> >> The STATE_XXX names are best depicted if looking at code in >> initializeGlobalHandlers() method. >> >> Let me prepare a changed webrew... >> >> Regards, Peter >> > From peter.levart at gmail.com Mon May 4 14:09:25 2015 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 04 May 2015 16:09:25 +0200 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <55477838.6020200@oracle.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> <5542C2ED.1090100@gmail.com> <5547736A.4060805@gmail.com> <55477838.6020200@oracle.com> Message-ID: <55477D95.1010202@gmail.com> On 05/04/2015 03:46 PM, Daniel Fuchs wrote: > On 04/05/15 15:26, Peter Levart wrote: >> Hi Daniel, Mandy, >> >> What about the following: >> >> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.03/ >> >> >> You see, no boolean flags needed. The globalHandlersState is always >> changed atomically within a locked region, so a graph of transitions can >> be drawn: >> >> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/LogManager.globalHandlersState.png >> >> >> STATE_INITIALIZING and STATE_READING_CONFIG are intra-locked-region >> states used to prevent infinite recursion in initializeGlobalHandlers() >> and communicating state from within locked-region of readConfiguration() >> to nested reset(), respectively, but never from one locked region to >> another. > > That looks better. > > I would consider removing these lines: > > 1333 if (globalHandlersState == STATE_SHUTDOWN) { > 1334 // already in terminal state > 1335 return; > 1336 } > > in favor of: > > 1354 } else if (globalHandlersState != STATE_SHUTDOWN) { > 1355 // ...user calling reset()... > > and let the reset reset twice if it's called from different contexts. > There may be permissions that could prevent a user-called reset() to > close all handlers, and we don't want that to prevent the Cleaner-called > reset to come afterwards and perform its job. Then we don't need STATE_SHUTTING_DOWN. Cleaner.run() can change directly to STATE_SHUTDOWN and reset() would just leave it there, but perform the reset anyway. Will create another variant including your test too. Regards, Peter > > BTW - in the end - one of us will need to push this together with > the new test :-) > > cheers, > > -- daniel > > >> >> Regards, Peter >> >> On 05/01/2015 02:03 AM, Peter Levart wrote: >>> >>> >>> On 04/30/2015 04:42 PM, Daniel Fuchs wrote: >>>> On 28/04/15 17:46, Peter Levart wrote: >>>>> >>>>> >>>>> On 04/28/2015 04:57 PM, Daniel Fuchs wrote: >>>>>>> Here's my attempt at simplifying this: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.01/ >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> LogManager can be subclassed, and subclasses may override reset() >>>>>> for >>>>>> different purposes. >>>>>> So I'm afraid the Cleaner thread still needs to call te public >>>>>> reset() method. The same unfortunately applies to >>>>>> readConfiguration(). >>>>>> >>>>>> best regards, >>>>>> >>>>>> -- daniel >>>>> >>>>> Um, yes of course. This can be fixed: >>>>> >>>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.02/ >>>>> >>>>> >>>> >>>> Hi Peter, >>>> >>>> Sorry for the late reply. >>>> >>>> My gut feeling is that I dislike multi-state ints. >>>> But I guess that's a matter of taste - so I could probably >>>> overcome it ;-) >>> >>> Isn't that a simplification (of reasoning)? In particular if >>> individual boolean flags are read and/or written without holding any >>> lock. >>> >>>> >>>> What makes me less happy is that I had managed to >>>> remove the explicit synchronized() { } block in the >>>> Cleaner thread - and I now see it's back. >>>> >>>> Could we maybe keep the imminentDeath boolean and remove >>>> the explicit locking in the Cleaner thread? >>>> >>>> I mean... imminentDeath should be checked from within >>>> the lock - before doing anything. But it does not need >>>> to be set from within a locked section. >>>> >>>> best regards, >>>> >>>> -- daniel >>>> >>> >>> >>> Hi Daniel, Mandy, >>> >>> Explicit locking in Cleaner is something that is performed in reset() >>> anyway, so getting rid of it is not actually getting rid of it, as >>> Cleaner is calling reset() anyway. The lock is reentrant. >>> >>> But If you want get rid of it so that reset() is not called under lock >>> held because reset() might be overridden, then imminentDeath must >>> return. >>> >>> @Mandy: >>> >>> In webrev.01 we had a private reset(int newState), called from >>> reset(), Cleaner and readConfiguration(), but Daniel then spotted that >>> reset() is an overridable method, so it has to be called from Cleaner >>> and readConfiguration() too, unfortunately. >>> >>> The STATE_XXX names are best depicted if looking at code in >>> initializeGlobalHandlers() method. >>> >>> Let me prepare a changed webrew... >>> >>> Regards, Peter >>> >> > From peter.levart at gmail.com Mon May 4 14:46:48 2015 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 04 May 2015 16:46:48 +0200 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <55477D95.1010202@gmail.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> <5542C2ED.1090100@gmail.com> <5547736A.4060805@gmail.com> <55477838.6020200@oracle.com> <55477D95.1010202@gmail.com> Message-ID: <55478658.4090700@gmail.com> Hi Daniel, Here it is: http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.04/ All java/util/logging tests pass for me except java/util/logging/TestLoggerWeakRefLeak #section:build ----------messages:(2/93)---------- command: build jdk.testlibrary.* reason: User specified action: run build jdk.testlibrary.* result: Not run. Test running... test result: Error. Can't find source file: jdk/testlibrary/*.java in directory-list: /home/peter/work/hg/jdk9-dev/jdk/test/java/util/logging /home/peter/work/hg/jdk9-dev/jdk/test/lib/testlibrary Regards, Peter On 05/04/2015 04:09 PM, Peter Levart wrote: > > > On 05/04/2015 03:46 PM, Daniel Fuchs wrote: >> On 04/05/15 15:26, Peter Levart wrote: >>> Hi Daniel, Mandy, >>> >>> What about the following: >>> >>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.03/ >>> >>> >>> You see, no boolean flags needed. The globalHandlersState is always >>> changed atomically within a locked region, so a graph of transitions >>> can >>> be drawn: >>> >>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/LogManager.globalHandlersState.png >>> >>> >>> STATE_INITIALIZING and STATE_READING_CONFIG are intra-locked-region >>> states used to prevent infinite recursion in initializeGlobalHandlers() >>> and communicating state from within locked-region of >>> readConfiguration() >>> to nested reset(), respectively, but never from one locked region to >>> another. >> >> That looks better. >> >> I would consider removing these lines: >> >> 1333 if (globalHandlersState == STATE_SHUTDOWN) { >> 1334 // already in terminal state >> 1335 return; >> 1336 } >> >> in favor of: >> >> 1354 } else if (globalHandlersState != STATE_SHUTDOWN) { >> 1355 // ...user calling reset()... >> >> and let the reset reset twice if it's called from different contexts. >> There may be permissions that could prevent a user-called reset() to >> close all handlers, and we don't want that to prevent the Cleaner-called >> reset to come afterwards and perform its job. > > Then we don't need STATE_SHUTTING_DOWN. Cleaner.run() can change > directly to STATE_SHUTDOWN and reset() would just leave it there, but > perform the reset anyway. > > Will create another variant including your test too. > > Regards, Peter > >> >> BTW - in the end - one of us will need to push this together with >> the new test :-) >> >> cheers, >> >> -- daniel >> >> >>> >>> Regards, Peter >>> >>> On 05/01/2015 02:03 AM, Peter Levart wrote: >>>> >>>> >>>> On 04/30/2015 04:42 PM, Daniel Fuchs wrote: >>>>> On 28/04/15 17:46, Peter Levart wrote: >>>>>> >>>>>> >>>>>> On 04/28/2015 04:57 PM, Daniel Fuchs wrote: >>>>>>>> Here's my attempt at simplifying this: >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.01/ >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> LogManager can be subclassed, and subclasses may override >>>>>>> reset() for >>>>>>> different purposes. >>>>>>> So I'm afraid the Cleaner thread still needs to call te public >>>>>>> reset() method. The same unfortunately applies to >>>>>>> readConfiguration(). >>>>>>> >>>>>>> best regards, >>>>>>> >>>>>>> -- daniel >>>>>> >>>>>> Um, yes of course. This can be fixed: >>>>>> >>>>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.02/ >>>>>> >>>>>> >>>>> >>>>> Hi Peter, >>>>> >>>>> Sorry for the late reply. >>>>> >>>>> My gut feeling is that I dislike multi-state ints. >>>>> But I guess that's a matter of taste - so I could probably >>>>> overcome it ;-) >>>> >>>> Isn't that a simplification (of reasoning)? In particular if >>>> individual boolean flags are read and/or written without holding >>>> any lock. >>>> >>>>> >>>>> What makes me less happy is that I had managed to >>>>> remove the explicit synchronized() { } block in the >>>>> Cleaner thread - and I now see it's back. >>>>> >>>>> Could we maybe keep the imminentDeath boolean and remove >>>>> the explicit locking in the Cleaner thread? >>>>> >>>>> I mean... imminentDeath should be checked from within >>>>> the lock - before doing anything. But it does not need >>>>> to be set from within a locked section. >>>>> >>>>> best regards, >>>>> >>>>> -- daniel >>>>> >>>> >>>> >>>> Hi Daniel, Mandy, >>>> >>>> Explicit locking in Cleaner is something that is performed in reset() >>>> anyway, so getting rid of it is not actually getting rid of it, as >>>> Cleaner is calling reset() anyway. The lock is reentrant. >>>> >>>> But If you want get rid of it so that reset() is not called under lock >>>> held because reset() might be overridden, then imminentDeath must >>>> return. >>>> >>>> @Mandy: >>>> >>>> In webrev.01 we had a private reset(int newState), called from >>>> reset(), Cleaner and readConfiguration(), but Daniel then spotted that >>>> reset() is an overridable method, so it has to be called from Cleaner >>>> and readConfiguration() too, unfortunately. >>>> >>>> The STATE_XXX names are best depicted if looking at code in >>>> initializeGlobalHandlers() method. >>>> >>>> Let me prepare a changed webrew... >>>> >>>> Regards, Peter >>>> >>> >> > From paul.sandoz at oracle.com Mon May 4 15:59:27 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 4 May 2015 17:59:27 +0200 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false Message-ID: Hi Please review: http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8078645-ConcurrentMap-views-removeIf/webrev/ These updates are already in the 166 repo. The documentation update to the class of ConcurrentMap is going through CCC. I took the liberty of also cleaning up some smaller doc errors on ConcurrentMap as made in the 166 repo. Thanks, Paul. From brent.christian at oracle.com Mon May 4 16:11:59 2015 From: brent.christian at oracle.com (Brent Christian) Date: Mon, 04 May 2015 09:11:59 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java Message-ID: <55479A4F.4060806@oracle.com> Hi, Please review this fix, courtesy of Peter Levart (thanks!), that I would like to get in. https://bugs.openjdk.java.net/browse/JDK-8029891 http://cr.openjdk.java.net/~bchristi/8029891/webrev.0/ There is some discussion of it in the bug report, starting at 2014-12-31. The problem, as stated by Mandy: "System Properties is a hashtable that synchronizes on itself for any access. Currently System.getProperties returns the Properties instance accessed by the system in which any application code might synchronize on it (that's what the test is doing). The problem reported JDK-6977738 is about Properties.store method that was fixed not to synchronize on this instance. System property is a common way for changing the default setting and so it's impractical to expect the class loading code path not to call System.getProperty." This fix changes java.util.Properties to store its values in an internal ConcurrentHashMap, ignoring its Hashtable heritage. In this way, Properties can be "de-sychronized": all methods inherited from Hashtable are overridden, to remove synchronization, and delegate to the internal CHM. The serialized form is unchanged. An alternative approach considered would be for System.getProperties() to return a duplicate snapshot of the current Properties. This presents a compatibility risk to existing code that keeps a reference to the return value of System.getProperties() and expects to either read new properties added afterwards, or set properties on the cached copy. -Brent From martinrb at google.com Mon May 4 17:12:56 2015 From: martinrb at google.com (Martin Buchholz) Date: Mon, 4 May 2015 10:12:56 -0700 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: Message-ID: Thanks, Paul. Are there are too many cooks spoiling this broth? There are still a number of differences, mostly cosmetic, between your version of ConcurrentMap.java and jsr166 CVS (let's try hard to keep that the "master" copy). E.g. This code sample won't compile: * do { * K k = entry.getKey(); * V v = entry.getValue(); - * } while(!replace(k, v, function.apply(k, v))); I would take the opportunity to sync all the changes from jsr166 CVS. Or we could wait for the Great jsr166 CVS openjdk9 sync... On Mon, May 4, 2015 at 8:59 AM, Paul Sandoz wrote: > Hi > > Please review: > > > http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8078645-ConcurrentMap-views-removeIf/webrev/ > > These updates are already in the 166 repo. > > The documentation update to the class of ConcurrentMap is going through > CCC. I took the liberty of also cleaning up some smaller doc errors on > ConcurrentMap as made in the 166 repo. > > Thanks, > Paul. > From paul.sandoz at oracle.com Mon May 4 17:29:16 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 4 May 2015 19:29:16 +0200 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: Message-ID: On May 4, 2015, at 7:12 PM, Martin Buchholz wrote: > Thanks, Paul. > > Are there are too many cooks spoiling this broth? Probably :-) > There are still a number of differences, mostly cosmetic, between your version of ConcurrentMap.java and jsr166 CVS (let's try hard to keep that the "master" copy). Yeah, there are a bunch of cosmetic differences, i just tried to fix some of the JavaDoc-like errors and may have slipped in some other cosmetic things. Let me fully sync up ConcurrentMap from 166. > E.g. This code sample won't compile: > > * do { > * K k = entry.getKey(); > * V v = entry.getValue(); > - * } while(!replace(k, v, function.apply(k, v))); > I thought I fixed that in the patch. > I would take the opportunity to sync all the changes from jsr166 CVS. At some point, yes. Would prefer to do that a littler later. Paul. > Or we could wait for the Great jsr166 CVS openjdk9 sync... > From peter.levart at gmail.com Mon May 4 18:32:26 2015 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 04 May 2015 20:32:26 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55479A4F.4060806@oracle.com> References: <55479A4F.4060806@oracle.com> Message-ID: <5547BB3A.8000109@gmail.com> On 05/04/2015 06:11 PM, Brent Christian wrote: > Hi, > > Please review this fix, courtesy of Peter Levart (thanks!), that I > would like to get in. > > https://bugs.openjdk.java.net/browse/JDK-8029891 > http://cr.openjdk.java.net/~bchristi/8029891/webrev.0/ > > There is some discussion of it in the bug report, starting at 2014-12-31. > > The problem, as stated by Mandy: > > "System Properties is a hashtable that synchronizes on itself for any > access. Currently System.getProperties returns the Properties instance > accessed by the system in which any application code might synchronize > on it (that's what the test is doing). The problem reported > JDK-6977738 is about Properties.store method that was fixed not to > synchronize on this instance. System property is a common way for > changing the default setting and so it's impractical to expect the > class loading code path not to call System.getProperty." > > This fix changes java.util.Properties to store its values in an > internal ConcurrentHashMap, ignoring its Hashtable heritage. In this > way, Properties can be "de-sychronized": all methods inherited from > Hashtable are overridden, to remove synchronization, and delegate to > the internal CHM. > > The serialized form is unchanged. > > > An alternative approach considered would be for System.getProperties() > to return a duplicate snapshot of the current Properties. This > presents a compatibility risk to existing code that keeps a reference > to the return value of System.getProperties() and expects to either > read new properties added afterwards, or set properties on the cached > copy. > > -Brent > Hi Brent, The test looks mostly good, but I would refrain from matching the exception types as part of method signature. Why? - javac already performs all the necessary checks about declared exceptions if some method overrides another method - overriding method can declare a subset and/or subtypes of checked exceptions of those than overridden method declares and this is OK. - overriding/overridden methods can declare arbitrary unrelated sets of unchecked exceptions and this is OK. Another question is whether return type should be considered part of the method signature. For JVM it is, but Java, the language, just matches the method's name and parameter types and javac makes sure that overriding method declarest the same return type or a subtype of overridden method's return type. Well, javac generates two methods in the later case - the one declared in the source code with covariant return type and a synthetic bridge method with overridden method's return type that just calls the declared method. Class.getDeclaredMethods() returns both methods in that case. So either "key" shape would work (one that takes returnType as part of key and one that doesn't). I don't think you need or even want to check that Properties declares all the methods with signatures from all interfaces. Just checking superclass(es) would do, as Properties is not abstract and in order to compile it must implement all abstract methods (either by inheriting from superclass(es) or implementing them itself). Specifically, you would not want to enforce interface default methods to be overridden by Properties if they are not overridden by superclass(es) (as the interface default method can only call other methods in the interface or Object methods and you need not override such method in Properties for Properties to be OK). Regards, Peter From daniel.fuchs at oracle.com Mon May 4 18:52:48 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Mon, 04 May 2015 20:52:48 +0200 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <55478658.4090700@gmail.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> <5542C2ED.1090100@gmail.com> <5547736A.4060805@gmail.com> <55477838.6020200@oracle.com> <55477D95.1010202@gmail.com> <55478658.4090700@gmail.com> Message-ID: <5547C000.9040005@oracle.com> On 04/05/15 16:46, Peter Levart wrote: > Hi Daniel, > > Here it is: > > http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.04/ Looks good for me Peter :-) Hopefully Mandy will like it too! > All java/util/logging tests pass for me except > java/util/logging/TestLoggerWeakRefLeak > > #section:build > ----------messages:(2/93)---------- > command: build jdk.testlibrary.* > reason: User specified action: run build jdk.testlibrary.* > result: Not run. Test running... > > > test result: Error. Can't find source file: jdk/testlibrary/*.java in > directory-list: /home/peter/work/hg/jdk9-dev/jdk/test/java/util/logging > /home/peter/work/hg/jdk9-dev/jdk/test/lib/testlibrary I assume you may have a somewhat older version of jtreg that doesn't support the .* pattern in @library / @build I have imported your patch and tested locally - on my machine all the logging tests have passed. I have also run a test campaign against it and things looked good there as well. best regards, -- daniel > > > Regards, Peter > > > On 05/04/2015 04:09 PM, Peter Levart wrote: >> >> >> On 05/04/2015 03:46 PM, Daniel Fuchs wrote: >>> On 04/05/15 15:26, Peter Levart wrote: >>>> Hi Daniel, Mandy, >>>> >>>> What about the following: >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.03/ >>>> >>>> >>>> You see, no boolean flags needed. The globalHandlersState is always >>>> changed atomically within a locked region, so a graph of transitions >>>> can >>>> be drawn: >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/LogManager.globalHandlersState.png >>>> >>>> >>>> STATE_INITIALIZING and STATE_READING_CONFIG are intra-locked-region >>>> states used to prevent infinite recursion in initializeGlobalHandlers() >>>> and communicating state from within locked-region of >>>> readConfiguration() >>>> to nested reset(), respectively, but never from one locked region to >>>> another. >>> >>> That looks better. >>> >>> I would consider removing these lines: >>> >>> 1333 if (globalHandlersState == STATE_SHUTDOWN) { >>> 1334 // already in terminal state >>> 1335 return; >>> 1336 } >>> >>> in favor of: >>> >>> 1354 } else if (globalHandlersState != STATE_SHUTDOWN) { >>> 1355 // ...user calling reset()... >>> >>> and let the reset reset twice if it's called from different contexts. >>> There may be permissions that could prevent a user-called reset() to >>> close all handlers, and we don't want that to prevent the Cleaner-called >>> reset to come afterwards and perform its job. >> >> Then we don't need STATE_SHUTTING_DOWN. Cleaner.run() can change >> directly to STATE_SHUTDOWN and reset() would just leave it there, but >> perform the reset anyway. >> >> Will create another variant including your test too. >> >> Regards, Peter >> >>> >>> BTW - in the end - one of us will need to push this together with >>> the new test :-) >>> >>> cheers, >>> >>> -- daniel >>> >>> >>>> >>>> Regards, Peter >>>> >>>> On 05/01/2015 02:03 AM, Peter Levart wrote: >>>>> >>>>> >>>>> On 04/30/2015 04:42 PM, Daniel Fuchs wrote: >>>>>> On 28/04/15 17:46, Peter Levart wrote: >>>>>>> >>>>>>> >>>>>>> On 04/28/2015 04:57 PM, Daniel Fuchs wrote: >>>>>>>>> Here's my attempt at simplifying this: >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.01/ >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> LogManager can be subclassed, and subclasses may override >>>>>>>> reset() for >>>>>>>> different purposes. >>>>>>>> So I'm afraid the Cleaner thread still needs to call te public >>>>>>>> reset() method. The same unfortunately applies to >>>>>>>> readConfiguration(). >>>>>>>> >>>>>>>> best regards, >>>>>>>> >>>>>>>> -- daniel >>>>>>> >>>>>>> Um, yes of course. This can be fixed: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.02/ >>>>>>> >>>>>>> >>>>>> >>>>>> Hi Peter, >>>>>> >>>>>> Sorry for the late reply. >>>>>> >>>>>> My gut feeling is that I dislike multi-state ints. >>>>>> But I guess that's a matter of taste - so I could probably >>>>>> overcome it ;-) >>>>> >>>>> Isn't that a simplification (of reasoning)? In particular if >>>>> individual boolean flags are read and/or written without holding >>>>> any lock. >>>>> >>>>>> >>>>>> What makes me less happy is that I had managed to >>>>>> remove the explicit synchronized() { } block in the >>>>>> Cleaner thread - and I now see it's back. >>>>>> >>>>>> Could we maybe keep the imminentDeath boolean and remove >>>>>> the explicit locking in the Cleaner thread? >>>>>> >>>>>> I mean... imminentDeath should be checked from within >>>>>> the lock - before doing anything. But it does not need >>>>>> to be set from within a locked section. >>>>>> >>>>>> best regards, >>>>>> >>>>>> -- daniel >>>>>> >>>>> >>>>> >>>>> Hi Daniel, Mandy, >>>>> >>>>> Explicit locking in Cleaner is something that is performed in reset() >>>>> anyway, so getting rid of it is not actually getting rid of it, as >>>>> Cleaner is calling reset() anyway. The lock is reentrant. >>>>> >>>>> But If you want get rid of it so that reset() is not called under lock >>>>> held because reset() might be overridden, then imminentDeath must >>>>> return. >>>>> >>>>> @Mandy: >>>>> >>>>> In webrev.01 we had a private reset(int newState), called from >>>>> reset(), Cleaner and readConfiguration(), but Daniel then spotted that >>>>> reset() is an overridable method, so it has to be called from Cleaner >>>>> and readConfiguration() too, unfortunately. >>>>> >>>>> The STATE_XXX names are best depicted if looking at code in >>>>> initializeGlobalHandlers() method. >>>>> >>>>> Let me prepare a changed webrew... >>>>> >>>>> Regards, Peter >>>>> >>>> >>> >> > From peter.levart at gmail.com Mon May 4 19:33:52 2015 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 04 May 2015 21:33:52 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <5547BB3A.8000109@gmail.com> References: <55479A4F.4060806@oracle.com> <5547BB3A.8000109@gmail.com> Message-ID: <5547C9A0.50902@gmail.com> Hi Brent, I think all you need for test is this: import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; public class CheckOverrides { public static void main(String[] args) { Set pMethodSignatures = Stream.of(Properties.class.getDeclaredMethods()) .filter(CheckOverrides::isMethodOfInterest) .map(MethodSignature::new) .collect(Collectors.toSet()); Map unoverriddenMethods = new HashMap<>(); for (Class superclass = Properties.class.getSuperclass(); superclass != Object.class; superclass = superclass.getSuperclass()) { Stream.of(superclass.getDeclaredMethods()) .filter(CheckOverrides::isMethodOfInterest) .forEach(m -> unoverriddenMethods.putIfAbsent(new MethodSignature(m), m)); } unoverriddenMethods.keySet().removeAll(pMethodSignatures); if (!unoverriddenMethods.isEmpty()) { throw new RuntimeException( "The following methods should be overridden by Properties class:\n" + unoverriddenMethods.values().stream() .map(Method::toString) .collect(Collectors.joining("\n ", " ", "\n")) ); } } static boolean isMethodOfInterest(Method method) { int mods = method.getModifiers(); return !Modifier.isStatic(mods) && (Modifier.isPublic(mods) || Modifier.isProtected(mods)); } static class MethodSignature { final Class returnType; final String name; final Class[] parameterTypes; MethodSignature(Method method) { this(method.getReturnType(), method.getName(), method.getParameterTypes()); } private MethodSignature(Class returnType, String name, Class[] parameterTypes) { this.returnType = returnType; this.name = name; this.parameterTypes = parameterTypes; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MethodSignature that = (MethodSignature) o; if (!returnType.equals(that.returnType)) return false; if (!name.equals(that.name)) return false; return Arrays.equals(parameterTypes, that.parameterTypes); } @Override public int hashCode() { int result = returnType.hashCode(); result = 31 * result + name.hashCode(); result = 31 * result + Arrays.hashCode(parameterTypes); return result; } } } Regards, Peter On 05/04/2015 08:32 PM, Peter Levart wrote: > > > On 05/04/2015 06:11 PM, Brent Christian wrote: >> Hi, >> >> Please review this fix, courtesy of Peter Levart (thanks!), that I >> would like to get in. >> >> https://bugs.openjdk.java.net/browse/JDK-8029891 >> http://cr.openjdk.java.net/~bchristi/8029891/webrev.0/ >> >> There is some discussion of it in the bug report, starting at >> 2014-12-31. >> >> The problem, as stated by Mandy: >> >> "System Properties is a hashtable that synchronizes on itself for any >> access. Currently System.getProperties returns the Properties >> instance accessed by the system in which any application code might >> synchronize on it (that's what the test is doing). The problem >> reported JDK-6977738 is about Properties.store method that was fixed >> not to synchronize on this instance. System property is a common way >> for changing the default setting and so it's impractical to expect >> the class loading code path not to call System.getProperty." >> >> This fix changes java.util.Properties to store its values in an >> internal ConcurrentHashMap, ignoring its Hashtable heritage. In this >> way, Properties can be "de-sychronized": all methods inherited from >> Hashtable are overridden, to remove synchronization, and delegate to >> the internal CHM. >> >> The serialized form is unchanged. >> >> >> An alternative approach considered would be for >> System.getProperties() to return a duplicate snapshot of the current >> Properties. This presents a compatibility risk to existing code that >> keeps a reference to the return value of System.getProperties() and >> expects to either read new properties added afterwards, or set >> properties on the cached copy. >> >> -Brent >> > > Hi Brent, > > The test looks mostly good, but I would refrain from matching the > exception types as part of method signature. Why? > > - javac already performs all the necessary checks about declared > exceptions if some method overrides another method > - overriding method can declare a subset and/or subtypes of checked > exceptions of those than overridden method declares and this is OK. > - overriding/overridden methods can declare arbitrary unrelated sets > of unchecked exceptions and this is OK. > > Another question is whether return type should be considered part of > the method signature. For JVM it is, but Java, the language, just > matches the method's name and parameter types and javac makes sure > that overriding method declarest the same return type or a subtype of > overridden method's return type. Well, javac generates two methods in > the later case - the one declared in the source code with covariant > return type and a synthetic bridge method with overridden method's > return type that just calls the declared method. > Class.getDeclaredMethods() returns both methods in that case. So > either "key" shape would work (one that takes returnType as part of > key and one that doesn't). > > I don't think you need or even want to check that Properties declares > all the methods with signatures from all interfaces. Just checking > superclass(es) would do, as Properties is not abstract and in order to > compile it must implement all abstract methods (either by inheriting > from superclass(es) or implementing them itself). Specifically, you > would not want to enforce interface default methods to be overridden > by Properties if they are not overridden by superclass(es) (as the > interface default method can only call other methods in the interface > or Object methods and you need not override such method in Properties > for Properties to be OK). > > Regards, Peter > From paul.sandoz at oracle.com Mon May 4 20:39:20 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 4 May 2015 22:39:20 +0200 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: Message-ID: On May 4, 2015, at 7:29 PM, Paul Sandoz wrote: >> There are still a number of differences, mostly cosmetic, between your version of ConcurrentMap.java and jsr166 CVS (let's try hard to keep that the "master" copy). > > Yeah, there are a bunch of cosmetic differences, i just tried to fix some of the JavaDoc-like errors and may have slipped in some other cosmetic things. Let me fully sync up ConcurrentMap from 166. > Done, webrev updated in place. http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8078645-ConcurrentMap-views-removeIf/webrev/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java.sdiff.html Paul. From martinrb at google.com Mon May 4 21:11:15 2015 From: martinrb at google.com (Martin Buchholz) Date: Mon, 4 May 2015 14:11:15 -0700 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: Message-ID: Paul, thanks. Looks good. Test uses some impressive machinery, but I like what we did in jsr166 tck tests for similar sorts of tests: - rename latch to "done" - rename barrier to "threadsStarted" - rename "map" to "entry" or "e" - if a worker thread throws, make sure the test fails, e.g. by defining a "CheckedRunnable" or using a real ThreadPool that returns Futures that can be checked in the main thread. - do you really want to swallow the exception from barrier.await? But it's unfair to ask you to create a new jdk jtreg concurrency testlibrary when jsr166 maintainers failed to do so! On Mon, May 4, 2015 at 1:39 PM, Paul Sandoz wrote: > On May 4, 2015, at 7:29 PM, Paul Sandoz wrote: > >> There are still a number of differences, mostly cosmetic, between your > version of ConcurrentMap.java and jsr166 CVS (let's try hard to keep that > the "master" copy). > > > > Yeah, there are a bunch of cosmetic differences, i just tried to fix > some of the JavaDoc-like errors and may have slipped in some other cosmetic > things. Let me fully sync up ConcurrentMap from 166. > > > > Done, webrev updated in place. > > > http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8078645-ConcurrentMap-views-removeIf/webrev/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java.sdiff.html > > Paul. > From david.holmes at oracle.com Tue May 5 01:25:47 2015 From: david.holmes at oracle.com (David Holmes) Date: Tue, 05 May 2015 11:25:47 +1000 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55479A4F.4060806@oracle.com> References: <55479A4F.4060806@oracle.com> Message-ID: <55481C1B.5030309@oracle.com> Hi Brent, On 5/05/2015 2:11 AM, Brent Christian wrote: > Hi, > > Please review this fix, courtesy of Peter Levart (thanks!), that I would > like to get in. > > https://bugs.openjdk.java.net/browse/JDK-8029891 > http://cr.openjdk.java.net/~bchristi/8029891/webrev.0/ > > There is some discussion of it in the bug report, starting at 2014-12-31. > > The problem, as stated by Mandy: > > "System Properties is a hashtable that synchronizes on itself for any > access. Currently System.getProperties returns the Properties instance > accessed by the system in which any application code might synchronize > on it (that's what the test is doing). The problem reported JDK-6977738 > is about Properties.store method that was fixed not to synchronize on > this instance. System property is a common way for changing the default > setting and so it's impractical to expect the class loading code path > not to call System.getProperty." > > This fix changes java.util.Properties to store its values in an internal > ConcurrentHashMap, ignoring its Hashtable heritage. In this way, > Properties can be "de-sychronized": all methods inherited from Hashtable > are overridden, to remove synchronization, and delegate to the internal > CHM. I don't think you want to de-synchronize the load* methods - you don't want two threads calling load concurrently. But that then raises the problem of concurrent modification while a load is in progress. Synchronization ensures serialization and by removing it you have done more than just avoid deadlocks. I think this needs a more careful examination of the expected/desired concurrent interactions between different methods. It may be that simply not utilizing the synchronized Hashtable methods is sufficient to resolve the deadlock, while still providing reasonable serialization via the existing synchronized Properties methods - or it may not. But allowing concurrent modifications will change behaviour in an unexpected, and incompatible way, in my opinion. David ----- > The serialized form is unchanged. > > > An alternative approach considered would be for System.getProperties() > to return a duplicate snapshot of the current Properties. This presents > a compatibility risk to existing code that keeps a reference to the > return value of System.getProperties() and expects to either read new > properties added afterwards, or set properties on the cached copy. > > -Brent > From david.holmes at oracle.com Tue May 5 01:40:53 2015 From: david.holmes at oracle.com (David Holmes) Date: Tue, 05 May 2015 11:40:53 +1000 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: Message-ID: <55481FA5.1060407@oracle.com> Hi Paul, On 5/05/2015 1:59 AM, Paul Sandoz wrote: > Hi > > Please review: > > http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8078645-ConcurrentMap-views-removeIf/webrev/ > > These updates are already in the 166 repo. > > The documentation update to the class of ConcurrentMap is going through CCC. I took the liberty of also cleaning up some smaller doc errors on ConcurrentMap as made in the 166 repo. Functional changes look okay - I'll not comment on test. One query in ConcurrentSkipListMap, we have: 2500 // else use iterator 2501 @SuppressWarnings("unchecked") Iterator> it = 2502 ((SubMap)m).entryIterator(); and then 2578 // else use iterator 2579 Iterator> it = ((SubMap)m).entryIterator(); why does only the former require the "unchecked" warning suppression? Thanks, David > Thanks, > Paul. > From martinrb at google.com Tue May 5 05:54:49 2015 From: martinrb at google.com (Martin Buchholz) Date: Mon, 4 May 2015 22:54:49 -0700 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: <55481FA5.1060407@oracle.com> References: <55481FA5.1060407@oracle.com> Message-ID: > > > One query in ConcurrentSkipListMap, we have: > > 2500 // else use iterator > 2501 @SuppressWarnings("unchecked") > Iterator> it = > 2502 ((SubMap)m).entryIterator(); > > and then > > 2578 // else use iterator > 2579 Iterator> it = > ((SubMap)m).entryIterator(); > > why does only the former require the "unchecked" warning suppression? > Good question. I think it's a small but clear improvement to consistently use K,V on view subclasses, allowing a few @SuppressWarnings to be removed: Index: src/main/java/util/concurrent/ConcurrentSkipListMap.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java,v retrieving revision 1.146 diff -u -r1.146 ConcurrentSkipListMap.java --- src/main/java/util/concurrent/ConcurrentSkipListMap.java 3 May 2015 12:09:30 -0000 1.146 +++ src/main/java/util/concurrent/ConcurrentSkipListMap.java 5 May 2015 05:52:59 -0000 @@ -346,11 +346,11 @@ final Comparator comparator; /** Lazily initialized key set */ - private transient KeySet keySet; + private transient KeySet keySet; /** Lazily initialized entry set */ private transient EntrySet entrySet; /** Lazily initialized values collection */ - private transient Values values; + private transient Values values; /** Lazily initialized descending key set */ private transient ConcurrentNavigableMap descendingMap; @@ -1798,13 +1798,13 @@ * @return a navigable set view of the keys in this map */ public NavigableSet keySet() { - KeySet ks = keySet; - return (ks != null) ? ks : (keySet = new KeySet(this)); + KeySet ks = keySet; + return (ks != null) ? ks : (keySet = new KeySet<>(this)); } public NavigableSet navigableKeySet() { - KeySet ks = keySet; - return (ks != null) ? ks : (keySet = new KeySet(this)); + KeySet ks = keySet; + return (ks != null) ? ks : (keySet = new KeySet<>(this)); } /** @@ -1827,8 +1827,8 @@ * weakly consistent. */ public Collection values() { - Values vs = values; - return (vs != null) ? vs : (values = new Values(this)); + Values vs = values; + return (vs != null) ? vs : (values = new Values<>(this)); } /** @@ -2341,36 +2341,35 @@ return list; } - static final class KeySet - extends AbstractSet implements NavigableSet { - final ConcurrentNavigableMap m; - KeySet(ConcurrentNavigableMap map) { m = map; } + static final class KeySet + extends AbstractSet implements NavigableSet { + final ConcurrentNavigableMap m; + KeySet(ConcurrentNavigableMap map) { m = map; } public int size() { return m.size(); } public boolean isEmpty() { return m.isEmpty(); } public boolean contains(Object o) { return m.containsKey(o); } public boolean remove(Object o) { return m.remove(o) != null; } public void clear() { m.clear(); } - public E lower(E e) { return m.lowerKey(e); } - public E floor(E e) { return m.floorKey(e); } - public E ceiling(E e) { return m.ceilingKey(e); } - public E higher(E e) { return m.higherKey(e); } - public Comparator comparator() { return m.comparator(); } - public E first() { return m.firstKey(); } - public E last() { return m.lastKey(); } - public E pollFirst() { - Map.Entry e = m.pollFirstEntry(); + public K lower(K e) { return m.lowerKey(e); } + public K floor(K e) { return m.floorKey(e); } + public K ceiling(K e) { return m.ceilingKey(e); } + public K higher(K e) { return m.higherKey(e); } + public Comparator comparator() { return m.comparator(); } + public K first() { return m.firstKey(); } + public K last() { return m.lastKey(); } + public K pollFirst() { + Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } - public E pollLast() { - Map.Entry e = m.pollLastEntry(); + public K pollLast() { + Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } - @SuppressWarnings("unchecked") - public Iterator iterator() { + public Iterator iterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).keyIterator(); + return ((ConcurrentSkipListMap)m).keyIterator(); else - return ((ConcurrentSkipListMap.SubMap)m).keyIterator(); + return ((ConcurrentSkipListMap.SubMap)m).keyIterator(); } public boolean equals(Object o) { if (o == this) @@ -2388,54 +2387,53 @@ } public Object[] toArray() { return toList(this).toArray(); } public T[] toArray(T[] a) { return toList(this).toArray(a); } - public Iterator descendingIterator() { + public Iterator descendingIterator() { return descendingSet().iterator(); } - public NavigableSet subSet(E fromElement, + public NavigableSet subSet(K fromElement, boolean fromInclusive, - E toElement, + K toElement, boolean toInclusive) { - return new KeySet(m.subMap(fromElement, fromInclusive, - toElement, toInclusive)); + return new KeySet<>(m.subMap(fromElement, fromInclusive, + toElement, toInclusive)); } - public NavigableSet headSet(E toElement, boolean inclusive) { - return new KeySet(m.headMap(toElement, inclusive)); + public NavigableSet headSet(K toElement, boolean inclusive) { + return new KeySet<>(m.headMap(toElement, inclusive)); } - public NavigableSet tailSet(E fromElement, boolean inclusive) { - return new KeySet(m.tailMap(fromElement, inclusive)); + public NavigableSet tailSet(K fromElement, boolean inclusive) { + return new KeySet<>(m.tailMap(fromElement, inclusive)); } - public NavigableSet subSet(E fromElement, E toElement) { + public NavigableSet subSet(K fromElement, K toElement) { return subSet(fromElement, true, toElement, false); } - public NavigableSet headSet(E toElement) { + public NavigableSet headSet(K toElement) { return headSet(toElement, false); } - public NavigableSet tailSet(E fromElement) { + public NavigableSet tailSet(K fromElement) { return tailSet(fromElement, true); } - public NavigableSet descendingSet() { - return new KeySet(m.descendingMap()); + public NavigableSet descendingSet() { + return new KeySet<>(m.descendingMap()); } @SuppressWarnings("unchecked") - public Spliterator spliterator() { + public Spliterator spliterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).keySpliterator(); + return ((ConcurrentSkipListMap)m).keySpliterator(); else - return (Spliterator)((SubMap)m).keyIterator(); + return (Spliterator)((SubMap)m).keyIterator(); } } - static final class Values extends AbstractCollection { - final ConcurrentNavigableMap m; - Values(ConcurrentNavigableMap map) { + static final class Values extends AbstractCollection { + final ConcurrentNavigableMap m; + Values(ConcurrentNavigableMap map) { m = map; } - @SuppressWarnings("unchecked") - public Iterator iterator() { + public Iterator iterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).valueIterator(); + return ((ConcurrentSkipListMap)m).valueIterator(); else - return ((SubMap)m).valueIterator(); + return ((SubMap)m).valueIterator(); } public boolean isEmpty() { return m.isEmpty(); @@ -2452,24 +2450,23 @@ public Object[] toArray() { return toList(this).toArray(); } public T[] toArray(T[] a) { return toList(this).toArray(a); } @SuppressWarnings("unchecked") - public Spliterator spliterator() { + public Spliterator spliterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).valueSpliterator(); + return ((ConcurrentSkipListMap)m).valueSpliterator(); else - return (Spliterator)((SubMap)m).valueIterator(); + return (Spliterator)((SubMap)m).valueIterator(); } - public boolean removeIf(Predicate filter) { + public boolean removeIf(Predicate filter) { if (filter == null) throw new NullPointerException(); if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).removeValueIf(filter); + return ((ConcurrentSkipListMap)m).removeValueIf(filter); // else use iterator - @SuppressWarnings("unchecked") Iterator> it = - ((SubMap)m).entryIterator(); + Iterator> it = ((SubMap)m).entryIterator(); boolean removed = false; while (it.hasNext()) { - Map.Entry e = it.next(); - E v = e.getValue(); + Map.Entry e = it.next(); + V v = e.getValue(); if (filter.test(v) && m.remove(e.getKey(), v)) removed = true; } @@ -2477,24 +2474,23 @@ } } - static final class EntrySet extends AbstractSet> { - final ConcurrentNavigableMap m; - EntrySet(ConcurrentNavigableMap map) { + static final class EntrySet extends AbstractSet> { + final ConcurrentNavigableMap m; + EntrySet(ConcurrentNavigableMap map) { m = map; } - @SuppressWarnings("unchecked") - public Iterator> iterator() { + public Iterator> iterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).entryIterator(); + return ((ConcurrentSkipListMap)m).entryIterator(); else - return ((SubMap)m).entryIterator(); + return ((SubMap)m).entryIterator(); } public boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e = (Map.Entry)o; - V1 v = m.get(e.getKey()); + V v = m.get(e.getKey()); return v != null && v.equals(e.getValue()); } public boolean remove(Object o) { @@ -2530,22 +2526,22 @@ public Object[] toArray() { return toList(this).toArray(); } public T[] toArray(T[] a) { return toList(this).toArray(a); } @SuppressWarnings("unchecked") - public Spliterator> spliterator() { + public Spliterator> spliterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).entrySpliterator(); + return ((ConcurrentSkipListMap)m).entrySpliterator(); else - return (Spliterator>) - ((SubMap)m).entryIterator(); + return (Spliterator>) + ((SubMap)m).entryIterator(); } - public boolean removeIf(Predicate> filter) { + public boolean removeIf(Predicate> filter) { if (filter == null) throw new NullPointerException(); if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).removeEntryIf(filter); + return ((ConcurrentSkipListMap)m).removeEntryIf(filter); // else use iterator - Iterator> it = ((SubMap)m).entryIterator(); + Iterator> it = ((SubMap)m).entryIterator(); boolean removed = false; while (it.hasNext()) { - Map.Entry e = it.next(); + Map.Entry e = it.next(); if (filter.test(e) && m.remove(e.getKey(), e.getValue())) removed = true; } @@ -2583,7 +2579,7 @@ private final boolean isDescending; // Lazily initialized view holders - private transient KeySet keySetView; + private transient KeySet keySetView; private transient Set> entrySetView; private transient Collection valuesView; @@ -3051,18 +3047,18 @@ /* ---------------- Submap Views -------------- */ public NavigableSet keySet() { - KeySet ks = keySetView; - return (ks != null) ? ks : (keySetView = new KeySet(this)); + KeySet ks = keySetView; + return (ks != null) ? ks : (keySetView = new KeySet<>(this)); } public NavigableSet navigableKeySet() { - KeySet ks = keySetView; - return (ks != null) ? ks : (keySetView = new KeySet(this)); + KeySet ks = keySetView; + return (ks != null) ? ks : (keySetView = new KeySet<>(this)); } public Collection values() { Collection vs = valuesView; - return (vs != null) ? vs : (valuesView = new Values(this)); + return (vs != null) ? vs : (valuesView = new Values<>(this)); } public Set> entrySet() { From mandy.chung at oracle.com Tue May 5 06:19:31 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 04 May 2015 23:19:31 -0700 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <5547C000.9040005@oracle.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> <5542C2ED.1090100@gmail.com> <5547736A.4060805@gmail.com> <55477838.6020200@oracle.com> <55477D95.1010202@gmail.com> <55478658.4090700@gmail.com> <5547C000.9040005@oracle.com> Message-ID: <554860F3.6030909@oracle.com> On 5/4/2015 11:52 AM, Daniel Fuchs wrote: > On 04/05/15 16:46, Peter Levart wrote: >> Hi Daniel, >> >> Here it is: >> >> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.04/ >> > > Looks good for me Peter :-) > Hopefully Mandy will like it too! > Yes it looks good to me. Thanks to both of you for imprpving the synchronization. This is the comment on the test I sent last round: TestConfigurationLock.java Copyright year should be 2015 TestConfigurationLock.properties It would be good to delete all commented lines except the lines relevant to the setting to make it obvious what the configuration is. Mandy From ivan.gerasimov at oracle.com Tue May 5 07:17:57 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 05 May 2015 10:17:57 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError Message-ID: <55486EA5.8000009@oracle.com> Hello! When creating a sublist with List.subList(), it keeps a reference to its parent. Then, when accessing (get(), set(), add(), remove(), etc.) the sublist, it recursively calls the corresponding methods of its parent. This recursion, when deep enough, can cause StackOverflowError. The only reason to do things recursively here, is the need to update modCount and size of all the parents. So, the proposal is to update these fields in a loop. A few cleanups were done along the way. Would you please help review the fix? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/0/webrev/ Sincerely yours, Ivan From paul.sandoz at oracle.com Tue May 5 07:56:39 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 5 May 2015 09:56:39 +0200 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: Message-ID: On May 4, 2015, at 11:11 PM, Martin Buchholz wrote: > Paul, thanks. > > Looks good. > > Test uses some impressive machinery, but I like what we did in jsr166 tck tests for similar sorts of tests: > - rename latch to "done" > - rename barrier to "threadsStarted" > - rename "map" to "entry" or "e" That name was meant to correspond to the kind of entry, i changed it to mapSupplier. > - if a worker thread throws, make sure the test fails, e.g. by defining a "CheckedRunnable" or using a real ThreadPool that returns Futures that can be checked in the main thread. > - do you really want to swallow the exception from barrier.await? > > But it's unfair to ask you to create a new jdk jtreg concurrency testlibrary when jsr166 maintainers failed to do so! > Here's an update using CompletableFuture: http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8078645-ConcurrentMap-views-removeIf/webrev/test/java/util/concurrent/ConcurrentMap/ConcurrentRemoveIf.java.html Paul. From daniel.fuchs at oracle.com Tue May 5 08:14:50 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 05 May 2015 10:14:50 +0200 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <55486EA5.8000009@oracle.com> References: <55486EA5.8000009@oracle.com> Message-ID: <55487BFA.4040409@oracle.com> Hi Ivan, Have you considered to simply override/change subList(int fromIndex, int toIndex) in SubList and RandomAccessSubList - so that 'l'/'parent' points always to the original root list (instead of being a sublist of sublist of sublist)? It seems to me that overriding sublist to create a sublist based on 'l'/'parent' instead of basing it on 'this' would solve the same problem with much less modifications... Or am I maybe missing something? best regards, -- daniel On 5/5/15 9:17 AM, Ivan Gerasimov wrote: > Hello! > > When creating a sublist with List.subList(), it keeps a reference to > its parent. > Then, when accessing (get(), set(), add(), remove(), etc.) the > sublist, it recursively calls the corresponding methods of its parent. > This recursion, when deep enough, can cause StackOverflowError. > > The only reason to do things recursively here, is the need to update > modCount and size of all the parents. > So, the proposal is to update these fields in a loop. > > A few cleanups were done along the way. > > Would you please help review the fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 > WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/0/webrev/ > > Sincerely yours, > Ivan From aleksey.shipilev at oracle.com Tue May 5 08:31:37 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 05 May 2015 11:31:37 +0300 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <5543B58F.6020105@Oracle.com> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> <5543B58F.6020105@Oracle.com> Message-ID: <55487FE9.5010606@oracle.com> Hi Roger, On 05/01/2015 08:19 PM, Roger Riggs wrote: > Is there any additional benefit by rounding up the next multiple of 4 or 8. > That would avoid a few wasted bytes at the end of the buffer modulo the > allocation size. It does not seem to help any further. Tried "plus32-round8", as in: http://cr.openjdk.java.net/~shade/8076759/patches.txt ...and it performs similar to "plus32": http://cr.openjdk.java.net/~shade/8076759/data-foot.png http://cr.openjdk.java.net/~shade/8076759/data-perf.png > Otherwise, looks fine to me also. I actually wonder if my change in ensureCapacity Javadoc requires a CCC? On that topic, I also tempted to remove the implementation details from the Javadoc there, since it does not play well with "describe what you will do, not how would you do it". Thanks, -Aleksey. From aleksey.shipilev at oracle.com Tue May 5 08:31:51 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 05 May 2015 11:31:51 +0300 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <55438DB8.9080502@CoSoCo.de> References: <553A85EA.5090603@oracle.com> <55438DB8.9080502@CoSoCo.de> Message-ID: <55487FF7.80205@oracle.com> Thanks for review, Ulf! -Aleksey. On 05/01/2015 05:29 PM, Ulf Zibis wrote: > Hi Aleksey, > > I like this approach and to me the webrev looks good. > > -Ulf > > > Am 24.04.2015 um 20:05 schrieb Aleksey Shipilev: >> Hi, >> >> This seems to be a simple one-liner fix, but the background is more >> complicated. See the bug: >> https://bugs.openjdk.java.net/browse/JDK-8076759 >> >> http://cr.openjdk.java.net/~shade/8076759/webrev.00/ >> > From ivan.gerasimov at oracle.com Tue May 5 08:58:07 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 05 May 2015 11:58:07 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <55487BFA.4040409@oracle.com> References: <55486EA5.8000009@oracle.com> <55487BFA.4040409@oracle.com> Message-ID: <5548861F.30007@oracle.com> Thank you Daniel for taking look at it! On 05.05.2015 11:14, Daniel Fuchs wrote: > Hi Ivan, > > Have you considered to simply override/change subList(int fromIndex, > int toIndex) > in SubList and RandomAccessSubList - so that 'l'/'parent' points > always to the original > root list (instead of being a sublist of sublist of sublist)? > With this fix, both SubList and RandomAccessSubList are made private inner classes of AbstractList. So now we have a pointer to the original root list, which is AbstractList.this in addition to the parent field. All the access methods are implemented to call the corresponding methods of this root list. However, we still need to keep a reference to the immediate parent (which might also be a sublist). When the leaf sublist is modified, its modCount and size fields are adjusted. The same adjustment has to be done to all the members of the sublist chain. > It seems to me that overriding sublist to create a sublist based on > 'l'/'parent' instead of basing it on 'this' would solve the same problem > with much less modifications... Or am I maybe missing something? > We have to keep both references: one to the root list, and the other to the immediate parent list. The first reference is used to pass the access requests. The second is used to maintain modCount and size fields of all the sublists in the chain. Sincerely yours, Ivan > best regards, > > -- daniel > > On 5/5/15 9:17 AM, Ivan Gerasimov wrote: >> Hello! >> >> When creating a sublist with List.subList(), it keeps a reference to >> its parent. >> Then, when accessing (get(), set(), add(), remove(), etc.) the >> sublist, it recursively calls the corresponding methods of its parent. >> This recursion, when deep enough, can cause StackOverflowError. >> >> The only reason to do things recursively here, is the need to update >> modCount and size of all the parents. >> So, the proposal is to update these fields in a loop. >> >> A few cleanups were done along the way. >> >> Would you please help review the fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/0/webrev/ >> >> Sincerely yours, >> Ivan > > > From yekaterina.kantserova at oracle.com Tue May 5 09:04:20 2015 From: yekaterina.kantserova at oracle.com (Yekaterina Kantserova) Date: Tue, 05 May 2015 11:04:20 +0200 Subject: RFR(M): 8078896: Add @modules as needed to the jdk_svc tests Message-ID: <55488794.3060008@oracle.com> Hi, Could I please have a review of this fix. bug: https://bugs.openjdk.java.net/browse/JDK-8078896 webrev: http://cr.openjdk.java.net/~ykantser/8078896 The push will be pushed to jdk9/dev. Thanks, Katja Alan's clarification from same change in hotspot (RFR: JDK-8075586: add @modules as needed to the open hotspot tests) ========== Just to put more context on this patch and similar patches that will be proposed for tests in other repos. The new @modules tag can be used for test selection (e.g. no point running a test that make use of types in module java.management if the runtime under test does not have the management module), and additionally to declare a dependency on JDK-internal APIs. If my test uses sun.misc.Unsafe for example then the runtime under test needs to export that API for the test to compile and run. Clearly the latter requires the module system in JDK 9 so consider this part as just preparing the tests for when that day comes. One other thing to say to say is that Alex has tooling to examine the test tree and create or change the @modules tag as needed. The intention is that this should run periodically to refresh the @modules tags. In this period before the module system then we can't expect everyone that is adding or changing tests to have internalized the module graph [1] and furthermore know which APIs are exported or not. In other words, the intention is not to needlessly burden anyone that adds or changes tests. Clearly making use of a new jtreg tag means everyone with a local copy of jtreg should grab a recent build. Finally, I hope in time that the TEST.groups files can be cleaned up to remove the needs_* groups, this is important for the group definitions in the jdk repo mostly (but there are some in the hotspot TEST.groups too). -Alan From paul.sandoz at oracle.com Tue May 5 09:12:33 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 5 May 2015 11:12:33 +0200 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: <55481FA5.1060407@oracle.com> Message-ID: On May 5, 2015, at 7:54 AM, Martin Buchholz wrote: > > One query in ConcurrentSkipListMap, we have: > > 2500 // else use iterator > 2501 @SuppressWarnings("unchecked") Iterator> it = > 2502 ((SubMap)m).entryIterator(); > > and then > > 2578 // else use iterator > 2579 Iterator> it = ((SubMap)m).entryIterator(); > > why does only the former require the "unchecked" warning suppression? > > Good question. Yes, for values the key type parameter is "thrown" away and reconstituting as Object is not type safe. > I think it's a small but clear improvement to consistently use K,V on view subclasses, allowing a few @SuppressWarnings to be removed: > AFAICT all but the above related suppress warning annotations could be removed if spliterator returning methods were on SubMap, rather than casting the result of the iterator based methods (see end of email for patch). I dunno if the 9 compiler got smarter or code was updated and the annotation was not removed. Your patch (plus addition of SubMap spliterator returning methods) seems like a good change to bring in bulk-wise, or otherwise earlier on if fixing another bug. Paul. diff -r b029e73f9cbb src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Tue May 05 09:43:27 2015 +0200 +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Tue May 05 11:10:41 2015 +0200 @@ -2400,12 +2400,12 @@ Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } - @SuppressWarnings("unchecked") +// @SuppressWarnings("unchecked") public Iterator iterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).keyIterator(); + return ((ConcurrentSkipListMap)m).keyIterator(); else - return ((ConcurrentSkipListMap.SubMap)m).keyIterator(); + return ((ConcurrentSkipListMap.SubMap)m).keyIterator(); } public boolean equals(Object o) { if (o == this) @@ -2451,12 +2451,12 @@ public NavigableSet descendingSet() { return new KeySet(m.descendingMap()); } - @SuppressWarnings("unchecked") +// @SuppressWarnings("unchecked") public Spliterator spliterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).keySpliterator(); else - return (Spliterator)((SubMap)m).keyIterator(); + return ((SubMap)m).keySpliterator(); } } @@ -2465,7 +2465,7 @@ Values(ConcurrentNavigableMap map) { m = map; } - @SuppressWarnings("unchecked") +// @SuppressWarnings("unchecked") public Iterator iterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).valueIterator(); @@ -2486,12 +2486,12 @@ } public Object[] toArray() { return toList(this).toArray(); } public T[] toArray(T[] a) { return toList(this).toArray(a); } - @SuppressWarnings("unchecked") +// @SuppressWarnings("unchecked") public Spliterator spliterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).valueSpliterator(); else - return (Spliterator)((SubMap)m).valueIterator(); + return ((SubMap)m).valueSpliterator(); } public boolean removeIf(Predicate filter) { if (filter == null) throw new NullPointerException(); @@ -2516,7 +2516,7 @@ EntrySet(ConcurrentNavigableMap map) { m = map; } - @SuppressWarnings("unchecked") +// @SuppressWarnings("unchecked") public Iterator> iterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).entryIterator(); @@ -2563,13 +2563,12 @@ } public Object[] toArray() { return toList(this).toArray(); } public T[] toArray(T[] a) { return toList(this).toArray(a); } - @SuppressWarnings("unchecked") +// @SuppressWarnings("unchecked") public Spliterator> spliterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).entrySpliterator(); else - return (Spliterator>) - ((SubMap)m).entryIterator(); + return ((SubMap)m).entrySpliterator(); } public boolean removeIf(Predicate> filter) { if (filter == null) throw new NullPointerException(); @@ -3112,14 +3111,26 @@ return new SubMapKeyIterator(); } + Spliterator keySpliterator() { + return new SubMapKeyIterator(); + } + Iterator valueIterator() { return new SubMapValueIterator(); } + Spliterator valueSpliterator() { + return new SubMapValueIterator(); + } + Iterator> entryIterator() { return new SubMapEntryIterator(); } + Spliterator> entrySpliterator() { + return new SubMapEntryIterator(); + } + /** * Variant of main Iter class to traverse through submaps. * Also serves as back-up Spliterator for views From Alan.Bateman at oracle.com Tue May 5 09:54:29 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 05 May 2015 10:54:29 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> Message-ID: <55489355.9010601@oracle.com> On 02/05/2015 09:27, Chris Hegarty wrote: > : > Thanks, this was an editing issue. Removed. I think the javadoc looks quite good now, except may be the first statement "Reads some bytes ...". It might be clearer to start with "Reads a given number of bytes ...". The subsequent text makes the short read case and the return value clear. > > As Alan has commented, another readAllBytes() returning a byte[] maybe useful too ( but a different use case ). Let?s park this momentarily, while I sketch up the readAllBytes variant, so we can ensure that the typical use cases have been addressed. Doing so may feedback into the spec of this method. I?ll push this latest draft into the sandbox so it is not lost. Yes, a separate use-case but once that I would expect to be common. -Alan. From daniel.fuchs at oracle.com Tue May 5 10:23:01 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 05 May 2015 12:23:01 +0200 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <5548861F.30007@oracle.com> References: <55486EA5.8000009@oracle.com> <55487BFA.4040409@oracle.com> <5548861F.30007@oracle.com> Message-ID: <55489A05.80009@oracle.com> On 05/05/15 10:58, Ivan Gerasimov wrote: > Thank you Daniel for taking look at it! > > On 05.05.2015 11:14, Daniel Fuchs wrote: >> Hi Ivan, >> >> Have you considered to simply override/change subList(int fromIndex, >> int toIndex) >> in SubList and RandomAccessSubList - so that 'l'/'parent' points >> always to the original >> root list (instead of being a sublist of sublist of sublist)? >> > With this fix, both SubList and RandomAccessSubList are made private > inner classes of AbstractList. > So now we have a pointer to the original root list, which is > AbstractList.this in addition to the parent field. > All the access methods are implemented to call the corresponding methods > of this root list. > > However, we still need to keep a reference to the immediate parent > (which might also be a sublist). > When the leaf sublist is modified, its modCount and size fields are > adjusted. > The same adjustment has to be done to all the members of the sublist chain. Ah, I see. That's what I missed. Thanks for the explanation! It's fortunate that sublists are not Serializable. Keeping the implementation package (not inner), renaming 'l' to parent, and adding a 'root' parameter could however make the changes less obscure. Given that SubList is itself an AbstractList, then syntaxes like AbstractList.this.new SubList(this, ...); can become a bit intricate - since SubList inherit the ability of having an inner SubList of its own. What new SubList(root, this, ...); does might thus be more obvious. (+ it would be easier to review as it wouldn't cause code reorganization:-) ) Note: I'm not an expert of collections, so you might want to wait for further feedback from the experts of the field. best regards, -- daniel >> It seems to me that overriding sublist to create a sublist based on >> 'l'/'parent' instead of basing it on 'this' would solve the same problem >> with much less modifications... Or am I maybe missing something? >> > We have to keep both references: one to the root list, and the other to > the immediate parent list. > The first reference is used to pass the access requests. > The second is used to maintain modCount and size fields of all the > sublists in the chain. > > Sincerely yours, > Ivan > >> best regards, >> >> -- daniel >> >> On 5/5/15 9:17 AM, Ivan Gerasimov wrote: >>> Hello! >>> >>> When creating a sublist with List.subList(), it keeps a reference to >>> its parent. >>> Then, when accessing (get(), set(), add(), remove(), etc.) the >>> sublist, it recursively calls the corresponding methods of its parent. >>> This recursion, when deep enough, can cause StackOverflowError. >>> >>> The only reason to do things recursively here, is the need to update >>> modCount and size of all the parents. >>> So, the proposal is to update these fields in a loop. >>> >>> A few cleanups were done along the way. >>> >>> Would you please help review the fix? >>> >>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/0/webrev/ >>> >>> Sincerely yours, >>> Ivan >> >> >> > From staffan.larsen at oracle.com Tue May 5 10:38:37 2015 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Tue, 5 May 2015 12:38:37 +0200 Subject: RFR(M): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <554894E9.8020908@oracle.com> References: <554894E9.8020908@oracle.com> Message-ID: <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> Dmitry, I think this should be reviewed on hotspot-gc and core-libs-dev as well considering the changes to Finalizer. I?m a little worried about the potentially very large String that is returned from printFinalizationQueue(). A possible different approach would be to write printFinalizationQueue() in C++ inside Hotspot. That would allow for outputting one line at a time. The output would still be saved in memory (since the stream is buffered), but at least the data is only saved once in memory, then. It would make the code a bit harder to write, so its a question of how scared we are of running out of memory. I see you are traversing the ?unfinalized? list in Finalizer, whereas the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am not sure of the difference, perhaps someone from the GC team can help out? For the output, it would be a nice touch to sort it on the number of references for each type. Perhaps outputting it more like a table (see the old code again) would also make it easier to digest. In diagnosticCommand.hpp, the new commands should override permission() and limit access: static const JavaPermission permission() { JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", NULL}; return p; } The two tests don?t validate the output in any way. Would it be possible to add validation? Perhaps hard to make sure an object is on the finalizer queue? Hmm. Thanks, /Staffan > On 5 maj 2015, at 12:01, Dmitry Samersoff wrote: > > Everyone, > > Please review the fix: > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ > > heap dcmd outputs the same information as SIGBREAK > > finalizerinfo dcmd outputs a list of all classes in finalization queue > with count > > -Dmitry > > -- > Dmitry Samersoff > Oracle Java development team, Saint Petersburg, Russia > * I would love to change the world, but they won't give me the sources. From dl at cs.oswego.edu Tue May 5 10:42:11 2015 From: dl at cs.oswego.edu (Doug Lea) Date: Tue, 05 May 2015 06:42:11 -0400 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: <55481FA5.1060407@oracle.com> Message-ID: <55489E83.8000204@cs.oswego.edu> On 05/05/2015 05:12 AM, Paul Sandoz wrote: > On May 5, 2015, at 7:54 AM, Martin Buchholz wrote: >> >> One query in ConcurrentSkipListMap, we have: >> >> 2500 // else use iterator >> 2501 @SuppressWarnings("unchecked") Iterator> it = >> 2502 ((SubMap)m).entryIterator(); >> >> and then >> >> 2578 // else use iterator >> 2579 Iterator> it = ((SubMap)m).entryIterator(); >> >> why does only the former require the "unchecked" warning suppression? >> >> Good question. > > Yes, for values the key type parameter is "thrown" away and reconstituting as Object is not type safe. > It was originally done this way because keeping the "K" parameter hit a generics type parameter inference limitation. Similarly for some constructions in TreeMap. But I think jdk8 (not just 9) allow this to be done with explicit type parameters, so now is as good a time to update this as any, combining both Martin's and Paul's changes. Someone might also want to look at TreeMap. -Doug From ivan.gerasimov at oracle.com Tue May 5 12:55:48 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 05 May 2015 15:55:48 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <55489A05.80009@oracle.com> References: <55486EA5.8000009@oracle.com> <55487BFA.4040409@oracle.com> <5548861F.30007@oracle.com> <55489A05.80009@oracle.com> Message-ID: <5548BDD4.4060604@oracle.com> On 05.05.2015 13:23, Daniel Fuchs wrote: > On 05/05/15 10:58, Ivan Gerasimov wrote: >> Thank you Daniel for taking look at it! >> >> On 05.05.2015 11:14, Daniel Fuchs wrote: >>> Hi Ivan, >>> >>> Have you considered to simply override/change subList(int fromIndex, >>> int toIndex) >>> in SubList and RandomAccessSubList - so that 'l'/'parent' points >>> always to the original >>> root list (instead of being a sublist of sublist of sublist)? >>> >> With this fix, both SubList and RandomAccessSubList are made private >> inner classes of AbstractList. >> So now we have a pointer to the original root list, which is >> AbstractList.this in addition to the parent field. >> All the access methods are implemented to call the corresponding methods >> of this root list. >> >> However, we still need to keep a reference to the immediate parent >> (which might also be a sublist). >> When the leaf sublist is modified, its modCount and size fields are >> adjusted. >> The same adjustment has to be done to all the members of the sublist >> chain. > > Ah, I see. That's what I missed. Thanks for the explanation! > It's fortunate that sublists are not Serializable. > > Keeping the implementation package (not inner), renaming 'l' to parent, > and adding a 'root' parameter could however make the changes less > obscure. > I converted the SubList into an inner class to make the implementations for AbstractList.SubList and ArrayList.SubList similar. It might be not worth doing so, but I thought it would be easier to maintain those classes, if they have similar structure. > Given that SubList is itself an AbstractList, then syntaxes like > AbstractList.this.new SubList(this, ...); > can become a bit intricate - since SubList inherit the ability > of having an inner SubList of its own. AbstractList.this.new SubList() was used just for that -- to avoid SubList become an inner class of itself. I learned it hard way that 'new SubList()' could not be used used here :) > What > new SubList(root, this, ...); > does might thus be more obvious. > (+ it would be easier to review as it wouldn't cause code > reorganization:-) ) > If ArrayList.SubList and AbstractList.SubList are unified, the code reorganization would be made somewhere anyway :) > Note: I'm not an expert of collections, so you might want to wait for > further feedback from the experts of the field. > Thank you anyway! Sincerely yours, Ivan > best regards, > > -- daniel > > >>> It seems to me that overriding sublist to create a sublist based on >>> 'l'/'parent' instead of basing it on 'this' would solve the same >>> problem >>> with much less modifications... Or am I maybe missing something? >>> >> We have to keep both references: one to the root list, and the other to >> the immediate parent list. >> The first reference is used to pass the access requests. >> The second is used to maintain modCount and size fields of all the >> sublists in the chain. >> >> Sincerely yours, >> Ivan >> >>> best regards, >>> >>> -- daniel >>> >>> On 5/5/15 9:17 AM, Ivan Gerasimov wrote: >>>> Hello! >>>> >>>> When creating a sublist with List.subList(), it keeps a reference to >>>> its parent. >>>> Then, when accessing (get(), set(), add(), remove(), etc.) the >>>> sublist, it recursively calls the corresponding methods of its parent. >>>> This recursion, when deep enough, can cause StackOverflowError. >>>> >>>> The only reason to do things recursively here, is the need to update >>>> modCount and size of all the parents. >>>> So, the proposal is to update these fields in a loop. >>>> >>>> A few cleanups were done along the way. >>>> >>>> Would you please help review the fix? >>>> >>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/0/webrev/ >>>> >>>> Sincerely yours, >>>> Ivan >>> >>> >>> >> > > > From daniel.fuchs at oracle.com Tue May 5 13:29:50 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 05 May 2015 15:29:50 +0200 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <5548BDD4.4060604@oracle.com> References: <55486EA5.8000009@oracle.com> <55487BFA.4040409@oracle.com> <5548861F.30007@oracle.com> <55489A05.80009@oracle.com> <5548BDD4.4060604@oracle.com> Message-ID: <5548C5CE.7040702@oracle.com> Hi Ivan, On 05/05/15 14:55, Ivan Gerasimov wrote: > I converted the SubList into an inner class to make the implementations > for AbstractList.SubList and ArrayList.SubList similar. > It might be not worth doing so, but I thought it would be easier to > maintain those classes, if they have similar structure. There's a subtle difference here - because SubList in ArrayList is not an ArrayList - so I find it less confusing: that SubList can't have inner SubList instances :-) Whereas SubList in AbstractList is itslef an AbstractList, and therefore if SubList is an AbstractList it can have inner SubList instances too - which is precisely what you don't want to happen. You might want to wait and see where other reviewer's preferences lean to... best regards, -- daniel From Alan.Bateman at oracle.com Tue May 5 13:30:30 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 05 May 2015 14:30:30 +0100 Subject: RFR(M): 8078896: Add @modules as needed to the jdk_svc tests In-Reply-To: <55488794.3060008@oracle.com> References: <55488794.3060008@oracle.com> Message-ID: <5548C5F6.50102@oracle.com> On 05/05/2015 10:04, Yekaterina Kantserova wrote: > Hi, > > Could I please have a review of this fix. > > bug: https://bugs.openjdk.java.net/browse/JDK-8078896 > webrev: http://cr.openjdk.java.net/~ykantser/8078896 > > The push will be pushed to jdk9/dev. > Thanks Katja, this looks good. One thing that we should as part of this is rev the requiredVersion in jdk/test/TEST.ROOT in case people are using older versions of jtreg. I think you did that as part of the patch for the hotspot repo. -Alan. From Roger.Riggs at Oracle.com Tue May 5 13:33:59 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 05 May 2015 09:33:59 -0400 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <55487FE9.5010606@oracle.com> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> <5543B58F.6020105@Oracle.com> <55487FE9.5010606@oracle.com> Message-ID: <5548C6C7.9000308@Oracle.com> Hi Aleksey, Thanks for checking the rounding alternative. As for the CCC, since the implementation details are in the javadoc then it will be needed either to remove the details or to update them. I'd be inclined to try to remove them since they are there primarily for performance. Thanks, Roger On 5/5/2015 4:31 AM, Aleksey Shipilev wrote: > Hi Roger, > > On 05/01/2015 08:19 PM, Roger Riggs wrote: >> Is there any additional benefit by rounding up the next multiple of 4 or 8. >> That would avoid a few wasted bytes at the end of the buffer modulo the >> allocation size. > It does not seem to help any further. Tried "plus32-round8", as in: > http://cr.openjdk.java.net/~shade/8076759/patches.txt > > ...and it performs similar to "plus32": > http://cr.openjdk.java.net/~shade/8076759/data-foot.png > http://cr.openjdk.java.net/~shade/8076759/data-perf.png > >> Otherwise, looks fine to me also. > I actually wonder if my change in ensureCapacity Javadoc requires a CCC? > On that topic, I also tempted to remove the implementation details from > the Javadoc there, since it does not play well with "describe what you > will do, not how would you do it". > > Thanks, > -Aleksey. > From yekaterina.kantserova at oracle.com Tue May 5 13:36:18 2015 From: yekaterina.kantserova at oracle.com (Yekaterina Kantserova) Date: Tue, 05 May 2015 15:36:18 +0200 Subject: RFR(M): 8078896: Add @modules as needed to the jdk_svc tests In-Reply-To: <5548C5F6.50102@oracle.com> References: <55488794.3060008@oracle.com> <5548C5F6.50102@oracle.com> Message-ID: <5548C752.5030308@oracle.com> Alan, Thanks for the review! And for the catch - I'll fix it. // Katja On 05/05/2015 03:30 PM, Alan Bateman wrote: > Thanks Katja, this looks good. One thing that we should as part of > this is rev the requiredVersion in jdk/test/TEST.ROOT in case people > are using older versions of jtreg. I think you did that as part of the > patch for the hotspot repo. > > -Alan. From peter.levart at gmail.com Tue May 5 14:40:28 2015 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 05 May 2015 16:40:28 +0200 Subject: RFR(M): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> Message-ID: <5548D65C.8040304@gmail.com> Hi Dmitry, Staffan, On 05/05/2015 12:38 PM, Staffan Larsen wrote: > Dmitry, > > I think this should be reviewed on hotspot-gc and core-libs-dev as well considering the changes to Finalizer. > > I?m a little worried about the potentially very large String that is returned from printFinalizationQueue(). A possible different approach would be to write printFinalizationQueue() in C++ inside Hotspot. That would allow for outputting one line at a time. The output would still be saved in memory (since the stream is buffered), but at least the data is only saved once in memory, then. It would make the code a bit harder to write, so its a question of how scared we are of running out of memory. If the output is just a histogram of # of instances per class name, then it should not be too large, as there are not many different classes overriding finalize() method (I counted 72 overriddings of finalize() method in the whole jdk/src tree). I'm more concerned about the fact that while traversing the list, a lock is held, which might impact prompt finalization(). Is it acceptable for diagnostic output to impact performance and/or interfere with synchronization? It might be possible to scan the list without holding a lock for diagnostic purposes if Finalizer.remove() didn't set the removed Finalizer.next pointer to point back to itself: private void remove() { synchronized (lock) { if (unfinalized == this) { if (this.next != null) { unfinalized = this.next; } else { unfinalized = this.prev; } } if (this.next != null) { this.next.prev = this.prev; } if (this.prev != null) { this.prev.next = this.next; } // this.next = this; must not be set so that we can traverse the list unsynchronized this.prev = this; /* Indicates that this has been finalized */ } } For detecting whether a Finalizer is already processed, the 'prev' pointer could be used instead: private boolean hasBeenFinalized() { return (prev == this); } Also, to make sure a data race dereferencing 'unfinalized' in unsynchronized printFinalizationQueue() would get you a fully initialized Finalizer instance (in particular the next pointer), you would have to make the 'unfinalized' field volatile or insert an Unsafe.storeFence() before assigning to 'unfinalized': private void add() { synchronized (lock) { if (unfinalized != null) { this.next = unfinalized; unfinalized.prev = this; } // make sure a data race dereferencing 'unfinalized' // in printFinalizationQueue() does see the Finalizer // instance fully initialized // (in particular the 'next' pointer) U.storeFence(); unfinalized = this; } } By doing these modifications, I think you can remove synchronized(lock) {} from printFinalizationQueue(). > > I see you are traversing the ?unfinalized? list in Finalizer, whereas the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am not sure of the difference, perhaps someone from the GC team can help out? The 'queue' is a ReferenceQueue of Finalizer (FinalReference) instances pending processing by finalizer thread because their referents are eligible for finalization (they are not reachable any more). The 'unfinalized' is a doubly-linked list of all Finalizer instances for which their referents have not been finalized yet (including those that are still reachable and alive). The later serves two purposes: - it keeps Finalizer instances reachable until they are processed - it is a source of unfinalized instances for running-finalizers-on-exit if requested by System.runFinalizersOnExit(true); So it really depends on what one would like to see. Showing the queue may be interesting if one wants to see how the finalizer thread is coping with processing the finalize() invocations. Showing unfinalized list may be interesting if one wants to know how many live + finalization pending instances are there on the heap that override finalize() method. Regards, Peter > > For the output, it would be a nice touch to sort it on the number of references for each type. Perhaps outputting it more like a table (see the old code again) would also make it easier to digest. > > In diagnosticCommand.hpp, the new commands should override permission() and limit access: > > static const JavaPermission permission() { > JavaPermission p = {"java.lang.management.ManagementPermission", > "monitor", NULL}; > return p; > } > > The two tests don?t validate the output in any way. Would it be possible to add validation? Perhaps hard to make sure an object is on the finalizer queue? Hmm. > > Thanks, > /Staffan > > >> On 5 maj 2015, at 12:01, Dmitry Samersoff wrote: >> >> Everyone, >> >> Please review the fix: >> >> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >> >> heap dcmd outputs the same information as SIGBREAK >> >> finalizerinfo dcmd outputs a list of all classes in finalization queue >> with count >> >> -Dmitry >> >> -- >> Dmitry Samersoff >> Oracle Java development team, Saint Petersburg, Russia >> * I would love to change the world, but they won't give me the sources. From alexander.v.stepanov at oracle.com Tue May 5 15:21:18 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Tue, 05 May 2015 18:21:18 +0300 Subject: RFR [9] 8079342: some docs cleanup for CORBA - part 2 Message-ID: <5548DFEE.2030504@oracle.com> Hello, Could you please review the following fix http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8079342 Just some HTML markup fix for CORBA. Thanks, Alexander From lance.andersen at oracle.com Tue May 5 15:25:52 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 5 May 2015 11:25:52 -0400 Subject: RFR [9] 8079342: some docs cleanup for CORBA - part 2 In-Reply-To: <5548DFEE.2030504@oracle.com> References: <5548DFEE.2030504@oracle.com> Message-ID: <8727E323-15ED-47DF-91A1-07C1C765203D@oracle.com> Hi Alexander, I just started to look at this and have a question: /** * Writes the value to the stream using java semantics. - * @param out The stream to write the value to + * @param _out The stream to write the value to * @param value The value to be written to the stream **/ public void writeValue(org.omg.CORBA.portable.OutputStream _out, Is there a reason that you did not change the parameter name to "out" vs changing the @param tag to "_out" ? Best, lance On May 5, 2015, at 11:21 AM, alexander stepanov wrote: > Hello, > > Could you please review the following fix > http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/ > for > https://bugs.openjdk.java.net/browse/JDK-8079342 > > Just some HTML markup fix for CORBA. > > Thanks, > Alexander 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 alexander.v.stepanov at oracle.com Tue May 5 15:41:47 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Tue, 05 May 2015 18:41:47 +0300 Subject: RFR [9] 8079342: some docs cleanup for CORBA - part 2 In-Reply-To: <8727E323-15ED-47DF-91A1-07C1C765203D@oracle.com> References: <5548DFEE.2030504@oracle.com> <8727E323-15ED-47DF-91A1-07C1C765203D@oracle.com> Message-ID: <5548E4BB.6030002@oracle.com> Hello Lance, It just seemed to be less hazardous. E.g., method 'readValue' (in ValueHandlerImpl) contains inner variable 'in' and parameter '_in' being documented (also, '_sender' - 'sender'). But of course the names could be swapped, if desired. I lazily preferred not to touch the code (just in case...). Regards, Alexander On 05.05.2015 18:25, Lance Andersen wrote: > Hi Alexander, > > I just started to look at this and have a question: > > > /** > * Writes the value to the stream using java semantics. > - * @param out The stream to write the value to > + * @param _out The stream to write the value to > * @param value The value to be written to the stream > **/ > public void writeValue(org.omg.CORBA.portable.OutputStream _out, > > > Is there a reason that you did not change the parameter name to "out" > vs changing the @param tag to "_out" ? > > Best, > lance > > > On May 5, 2015, at 11:21 AM, alexander stepanov > > wrote: > >> Hello, >> >> Could you please review the following fix >> http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/ >> >> for >> https://bugs.openjdk.java.net/browse/JDK-8079342 >> >> Just some HTML markup fix for CORBA. >> >> Thanks, >> Alexander > > > > 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 alexander.v.stepanov at oracle.com Tue May 5 15:45:16 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Tue, 05 May 2015 18:45:16 +0300 Subject: RFR [9] 8079342: some docs cleanup for CORBA - part 2 In-Reply-To: <5548E4BB.6030002@oracle.com> References: <5548DFEE.2030504@oracle.com> <8727E323-15ED-47DF-91A1-07C1C765203D@oracle.com> <5548E4BB.6030002@oracle.com> Message-ID: <5548E58C.6020206@oracle.com> But yes, for 'writeValue' it could be renamed without any thoughts, thanks... On 05.05.2015 18:41, alexander stepanov wrote: > Hello Lance, > > It just seemed to be less hazardous. E.g., method 'readValue' (in > ValueHandlerImpl) contains inner variable 'in' and parameter '_in' > being documented (also, '_sender' - 'sender'). > > But of course the names could be swapped, if desired. I lazily > preferred not to touch the code (just in case...). > > Regards, > Alexander > > > On 05.05.2015 18:25, Lance Andersen wrote: >> Hi Alexander, >> >> I just started to look at this and have a question: >> >> >> /** >> * Writes the value to the stream using java semantics. >> - * @param out The stream to write the value to >> + * @param _out The stream to write the value to >> * @param value The value to be written to the stream >> **/ >> public void writeValue(org.omg.CORBA.portable.OutputStream _out, >> >> >> Is there a reason that you did not change the parameter name to "out" >> vs changing the @param tag to "_out" ? >> >> Best, >> lance >> >> >> On May 5, 2015, at 11:21 AM, alexander stepanov >> > > wrote: >> >>> Hello, >>> >>> Could you please review the following fix >>> http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/ >>> >>> for >>> https://bugs.openjdk.java.net/browse/JDK-8079342 >>> >>> Just some HTML markup fix for CORBA. >>> >>> Thanks, >>> Alexander >> >> >> >> >> Lance >> Andersen| Principal Member of Technical Staff | +1.781.442.2037 >> Oracle Java Engineering >> 1 Network Drive >> Burlington, MA 01803 >> Lance.Andersen at oracle.com >> >> >> > From lance.andersen at oracle.com Tue May 5 15:46:41 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 5 May 2015 11:46:41 -0400 Subject: RFR [9] 8079342: some docs cleanup for CORBA - part 2 In-Reply-To: <5548E4BB.6030002@oracle.com> References: <5548DFEE.2030504@oracle.com> <8727E323-15ED-47DF-91A1-07C1C765203D@oracle.com> <5548E4BB.6030002@oracle.com> Message-ID: <891F11C6-E91C-4646-ACD7-AADE2B2AC770@oracle.com> Hi Alexander, Thank you, I guess I am not a fan of _variableName in the public javadocs as it is not something we normally see. Understand less is more, especially with CORBA. On May 5, 2015, at 11:41 AM, alexander stepanov wrote: > Hello Lance, > > It just seemed to be less hazardous. E.g., method 'readValue' (in ValueHandlerImpl) contains inner variable 'in' and parameter '_in' being documented (also, '_sender' - 'sender'). > > But of course the names could be swapped, if desired. I lazily preferred not to touch the code (just in case...). > > Regards, > Alexander > > > On 05.05.2015 18:25, Lance Andersen wrote: >> Hi Alexander, >> >> I just started to look at this and have a question: >> >> >> /** >> * Writes the value to the stream using java semantics. >> - * @param out The stream to write the value to >> + * @param _out The stream to write the value to >> * @param value The value to be written to the stream >> **/ >> public void writeValue(org.omg.CORBA.portable.OutputStream _out, >> >> >> Is there a reason that you did not change the parameter name to "out" vs changing the @param tag to "_out" ? >> >> Best, >> lance >> >> >> On May 5, 2015, at 11:21 AM, alexander stepanov > wrote: >> >>> Hello, >>> >>> Could you please review the following fix >>> http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/ >>> for >>> https://bugs.openjdk.java.net/browse/JDK-8079342 >>> >>> Just some HTML markup fix for CORBA. >>> >>> Thanks, >>> Alexander >> >> >> >> 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 alexander.v.stepanov at oracle.com Tue May 5 16:30:13 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Tue, 05 May 2015 19:30:13 +0300 Subject: RFR [9] 8079342: some docs cleanup for CORBA - part 2 In-Reply-To: <891F11C6-E91C-4646-ACD7-AADE2B2AC770@oracle.com> References: <5548DFEE.2030504@oracle.com> <8727E323-15ED-47DF-91A1-07C1C765203D@oracle.com> <5548E4BB.6030002@oracle.com> <891F11C6-E91C-4646-ACD7-AADE2B2AC770@oracle.com> Message-ID: <5548F015.7080304@oracle.com> > _variableName in the public javadocs Please see http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/src/java.corba/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java.udiff.html (please update the page as I didn't prepare a new webrev). Hopefully that do not harm the code... Thanks, Alexander On 05.05.2015 18:46, Lance Andersen wrote: > Hi Alexander, > > Thank you, I guess I am not a fan of _variableName in the public > javadocs as it is not something we normally see. > > Understand less is more, especially with CORBA. > > On May 5, 2015, at 11:41 AM, alexander stepanov > > wrote: > >> Hello Lance, >> >> It just seemed to be less hazardous. E.g., method 'readValue' (in >> ValueHandlerImpl) contains inner variable 'in' and parameter '_in' >> being documented (also, '_sender' - 'sender'). >> >> But of course the names could be swapped, if desired. I lazily >> preferred not to touch the code (just in case...). >> >> Regards, >> Alexander >> >> >> On 05.05.2015 18:25, Lance Andersen wrote: >>> Hi Alexander, >>> >>> I just started to look at this and have a question: >>> >>> >>> /** >>> * Writes the value to the stream using java semantics. >>> - * @param out The stream to write the value to >>> + * @param _out The stream to write the value to >>> * @param value The value to be written to the stream >>> **/ >>> public void writeValue(org.omg.CORBA.portable.OutputStream _out, >>> >>> >>> Is there a reason that you did not change the parameter name to >>> "out" vs changing the @param tag to "_out" ? >>> >>> Best, >>> lance >>> >>> >>> On May 5, 2015, at 11:21 AM, alexander stepanov >>> >> >>> > wrote: >>> >>>> Hello, >>>> >>>> Could you please review the following fix >>>> http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/ >>>> >>>> >>>> for >>>> https://bugs.openjdk.java.net/browse/JDK-8079342 >>>> >>>> Just some HTML markup fix for CORBA. >>>> >>>> Thanks, >>>> Alexander >>> >>> >>> >>> 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 paul.sandoz at oracle.com Tue May 5 16:56:35 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 5 May 2015 18:56:35 +0200 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <55486EA5.8000009@oracle.com> References: <55486EA5.8000009@oracle.com> Message-ID: <8CE7C8C6-B31F-4BEB-AD2B-4E0C62FF39A9@oracle.com> Hi Ivan, ArrayList -- You can simplify SubList with: private final class SubList extends AbstractList implements RandomAccess { private final SubList parent; private final int offset; int size; // Top level sub-list SubList(int offset, int fromIndex, int toIndex) { this.parent = null; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; } // Sub sub-lst SubList(SubList parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; } ArrayList.subList becomes: public List subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(0, fromIndex, toIndex); } And SubList.subList: public List subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, offset, fromIndex, toIndex); } And SubList. updateSizeAndModCount: private void updateSizeAndModCount(int sizeChange) { int modCount = ArrayList.this.modCount; for (SubList slist = this; slist != null; slist = slist.parent) { slist.size += sizeChange; slist.modCount = modCount; } } AbstractList -- Similar changes can be made as above to ArrayList.SubList etc. The construction of sub-lists does indeed require a second take. A comment is worthwhile. IMO such scoping is not necessary for ArrayList, i have actually found it rare to require such scoping so using it when not necessary is rather jarring. NestedSubList -- My preference is you use a testng data provider so you don't have to roll your own failure checking and reporting. Are there any other tests for testing the integrity of sublists? Paul. On May 5, 2015, at 9:17 AM, Ivan Gerasimov wrote: > Hello! > > When creating a sublist with List.subList(), it keeps a reference to its parent. > Then, when accessing (get(), set(), add(), remove(), etc.) the sublist, it recursively calls the corresponding methods of its parent. > This recursion, when deep enough, can cause StackOverflowError. > > The only reason to do things recursively here, is the need to update modCount and size of all the parents. > So, the proposal is to update these fields in a loop. > > A few cleanups were done along the way. > > Would you please help review the fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 > WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/0/webrev/ > > Sincerely yours, > Ivan From martinrb at google.com Tue May 5 17:39:22 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 5 May 2015 10:39:22 -0700 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: <55481FA5.1060407@oracle.com> Message-ID: I'd prefer to go the other way, deleting those trivial methods entirely, utilizing the rarely used .new syntax. Index: ConcurrentSkipListMap.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListMap.java,v retrieving revision 1.147 diff -u -r1.147 ConcurrentSkipListMap.java --- ConcurrentSkipListMap.java 5 May 2015 16:36:32 -0000 1.147 +++ ConcurrentSkipListMap.java 5 May 2015 17:34:53 -0000 @@ -2311,20 +2311,6 @@ } } - // Factory methods for iterators needed by ConcurrentSkipListSet etc - - Iterator keyIterator() { - return new KeyIterator(); - } - - Iterator valueIterator() { - return new ValueIterator(); - } - - Iterator> entryIterator() { - return new EntryIterator(); - } - /* ---------------- View Classes -------------- */ /* @@ -2367,9 +2353,9 @@ } public Iterator iterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).keyIterator(); + return ((ConcurrentSkipListMap)m).new KeyIterator(); else - return ((ConcurrentSkipListMap.SubMap)m).keyIterator(); + return ((SubMap)m).new SubMapKeyIterator(); } public boolean equals(Object o) { if (o == this) @@ -2415,12 +2401,12 @@ public NavigableSet descendingSet() { return new KeySet<>(m.descendingMap()); } - @SuppressWarnings("unchecked") + public Spliterator spliterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).keySpliterator(); else - return (Spliterator)((SubMap)m).keyIterator(); + return ((SubMap)m).new SubMapKeyIterator(); } } @@ -2431,9 +2417,9 @@ } public Iterator iterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).valueIterator(); + return ((ConcurrentSkipListMap)m).new ValueIterator(); else - return ((SubMap)m).valueIterator(); + return ((SubMap)m).new SubMapValueIterator(); } public int size() { return m.size(); } public boolean isEmpty() { return m.isEmpty(); } @@ -2441,12 +2427,12 @@ public void clear() { m.clear(); } public Object[] toArray() { return toList(this).toArray(); } public T[] toArray(T[] a) { return toList(this).toArray(a); } - @SuppressWarnings("unchecked") + public Spliterator spliterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).valueSpliterator(); else - return (Spliterator)((SubMap)m).valueIterator(); + return ((SubMap)m).new SubMapValueIterator(); } public boolean removeIf(Predicate filter) { @@ -2454,7 +2440,8 @@ if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).removeValueIf(filter); // else use iterator - Iterator> it = ((SubMap)m).entryIterator(); + Iterator> it = + ((SubMap)m).new SubMapEntryIterator(); boolean removed = false; while (it.hasNext()) { Map.Entry e = it.next(); @@ -2473,9 +2460,9 @@ } public Iterator> iterator() { if (m instanceof ConcurrentSkipListMap) - return ((ConcurrentSkipListMap)m).entryIterator(); + return ((ConcurrentSkipListMap)m).new EntryIterator(); else - return ((SubMap)m).entryIterator(); + return ((SubMap)m).new SubMapEntryIterator(); } public boolean contains(Object o) { @@ -2517,20 +2504,20 @@ } public Object[] toArray() { return toList(this).toArray(); } public T[] toArray(T[] a) { return toList(this).toArray(a); } - @SuppressWarnings("unchecked") + public Spliterator> spliterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).entrySpliterator(); else - return (Spliterator>) - ((SubMap)m).entryIterator(); + return ((SubMap)m).new SubMapEntryIterator(); } public boolean removeIf(Predicate> filter) { if (filter == null) throw new NullPointerException(); if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).removeEntryIf(filter); // else use iterator - Iterator> it = ((SubMap)m).entryIterator(); + Iterator> it = + ((SubMap)m).new SubMapEntryIterator(); boolean removed = false; while (it.hasNext()) { Map.Entry e = it.next(); @@ -3062,18 +3049,6 @@ return descendingMap().navigableKeySet(); } - Iterator keyIterator() { - return new SubMapKeyIterator(); - } - - Iterator valueIterator() { - return new SubMapValueIterator(); - } - - Iterator> entryIterator() { - return new SubMapEntryIterator(); - } - /** * Variant of main Iter class to traverse through submaps. * Also serves as back-up Spliterator for views Index: ConcurrentSkipListSet.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentSkipListSet.java,v retrieving revision 1.47 diff -u -r1.47 ConcurrentSkipListSet.java --- ConcurrentSkipListSet.java 15 Jan 2015 18:34:18 -0000 1.47 +++ ConcurrentSkipListSet.java 5 May 2015 17:34:53 -0000 @@ -474,7 +474,7 @@ if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap)m).keySpliterator(); else - return (Spliterator)((ConcurrentSkipListMap.SubMap)m).keyIterator(); + return ((ConcurrentSkipListMap.SubMap)m).new SubMapKeyIterator(); } // Support for resetting map in clone On Tue, May 5, 2015 at 2:12 AM, Paul Sandoz wrote: > On May 5, 2015, at 7:54 AM, Martin Buchholz wrote: > > > > One query in ConcurrentSkipListMap, we have: > > > > 2500 // else use iterator > > 2501 @SuppressWarnings("unchecked") > Iterator> it = > > 2502 ((SubMap)m).entryIterator(); > > > > and then > > > > 2578 // else use iterator > > 2579 Iterator> it = > ((SubMap)m).entryIterator(); > > > > why does only the former require the "unchecked" warning suppression? > > > > Good question. > > Yes, for values the key type parameter is "thrown" away and reconstituting > as Object is not type safe. > > > > I think it's a small but clear improvement to consistently use K,V on > view subclasses, allowing a few @SuppressWarnings to be removed: > > > > AFAICT all but the above related suppress warning annotations could be > removed if spliterator returning methods were on SubMap, rather than > casting the result of the iterator based methods (see end of email for > patch). I dunno if the 9 compiler got smarter or code was updated and the > annotation was not removed. > > Your patch (plus addition of SubMap spliterator returning methods) seems > like a good change to bring in bulk-wise, or otherwise earlier on if fixing > another bug. > > Paul. > > diff -r b029e73f9cbb > src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java > --- > a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java > Tue May 05 09:43:27 2015 +0200 > +++ > b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java > Tue May 05 11:10:41 2015 +0200 > @@ -2400,12 +2400,12 @@ > Map.Entry e = m.pollLastEntry(); > return (e == null) ? null : e.getKey(); > } > - @SuppressWarnings("unchecked") > +// @SuppressWarnings("unchecked") > public Iterator iterator() { > if (m instanceof ConcurrentSkipListMap) > - return ((ConcurrentSkipListMap)m).keyIterator(); > + return ((ConcurrentSkipListMap)m).keyIterator(); > else > - return > ((ConcurrentSkipListMap.SubMap)m).keyIterator(); > + return > ((ConcurrentSkipListMap.SubMap)m).keyIterator(); > } > public boolean equals(Object o) { > if (o == this) > @@ -2451,12 +2451,12 @@ > public NavigableSet descendingSet() { > return new KeySet(m.descendingMap()); > } > - @SuppressWarnings("unchecked") > +// @SuppressWarnings("unchecked") > public Spliterator spliterator() { > if (m instanceof ConcurrentSkipListMap) > return ((ConcurrentSkipListMap)m).keySpliterator(); > else > - return (Spliterator)((SubMap)m).keyIterator(); > + return ((SubMap)m).keySpliterator(); > } > } > > @@ -2465,7 +2465,7 @@ > Values(ConcurrentNavigableMap map) { > m = map; > } > - @SuppressWarnings("unchecked") > +// @SuppressWarnings("unchecked") > public Iterator iterator() { > if (m instanceof ConcurrentSkipListMap) > return ((ConcurrentSkipListMap)m).valueIterator(); > @@ -2486,12 +2486,12 @@ > } > public Object[] toArray() { return toList(this).toArray(); } > public T[] toArray(T[] a) { return toList(this).toArray(a); } > - @SuppressWarnings("unchecked") > +// @SuppressWarnings("unchecked") > public Spliterator spliterator() { > if (m instanceof ConcurrentSkipListMap) > return ((ConcurrentSkipListMap)m).valueSpliterator(); > else > - return (Spliterator)((SubMap)m).valueIterator(); > + return ((SubMap)m).valueSpliterator(); > } > public boolean removeIf(Predicate filter) { > if (filter == null) throw new NullPointerException(); > @@ -2516,7 +2516,7 @@ > EntrySet(ConcurrentNavigableMap map) { > m = map; > } > - @SuppressWarnings("unchecked") > +// @SuppressWarnings("unchecked") > public Iterator> iterator() { > if (m instanceof ConcurrentSkipListMap) > return ((ConcurrentSkipListMap)m).entryIterator(); > @@ -2563,13 +2563,12 @@ > } > public Object[] toArray() { return toList(this).toArray(); } > public T[] toArray(T[] a) { return toList(this).toArray(a); } > - @SuppressWarnings("unchecked") > +// @SuppressWarnings("unchecked") > public Spliterator> spliterator() { > if (m instanceof ConcurrentSkipListMap) > return > ((ConcurrentSkipListMap)m).entrySpliterator(); > else > - return (Spliterator>) > - ((SubMap)m).entryIterator(); > + return ((SubMap)m).entrySpliterator(); > } > public boolean removeIf(Predicate> filter) { > if (filter == null) throw new NullPointerException(); > @@ -3112,14 +3111,26 @@ > return new SubMapKeyIterator(); > } > > + Spliterator keySpliterator() { > + return new SubMapKeyIterator(); > + } > + > Iterator valueIterator() { > return new SubMapValueIterator(); > } > > + Spliterator valueSpliterator() { > + return new SubMapValueIterator(); > + } > + > Iterator> entryIterator() { > return new SubMapEntryIterator(); > } > > + Spliterator> entrySpliterator() { > + return new SubMapEntryIterator(); > + } > + > /** > * Variant of main Iter class to traverse through submaps. > * Also serves as back-up Spliterator for views > > From aleksey.shipilev at oracle.com Tue May 5 17:47:44 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 05 May 2015 20:47:44 +0300 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <5548C6C7.9000308@Oracle.com> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> <5543B58F.6020105@Oracle.com> <55487FE9.5010606@oracle.com> <5548C6C7.9000308@Oracle.com> Message-ID: <55490240.1080206@oracle.com> Hi again, Here is a new webrev: http://cr.openjdk.java.net/~shade/8076759/webrev.01/ Pruned the implementation details from expandCapacity Javadoc, and about to submit a CCC for it. Thanks, -Aleksey. On 05.05.2015 16:33, Roger Riggs wrote: > Hi Aleksey, > > Thanks for checking the rounding alternative. > > As for the CCC, since the implementation details are in the javadoc > then it will be needed either to remove the details or to update them. > I'd be inclined to try to remove them since they are there primarily for > performance. > > Thanks, Roger > > > > On 5/5/2015 4:31 AM, Aleksey Shipilev wrote: >> Hi Roger, >> >> On 05/01/2015 08:19 PM, Roger Riggs wrote: >>> Is there any additional benefit by rounding up the next multiple of 4 >>> or 8. >>> That would avoid a few wasted bytes at the end of the buffer modulo the >>> allocation size. >> It does not seem to help any further. Tried "plus32-round8", as in: >> http://cr.openjdk.java.net/~shade/8076759/patches.txt >> >> ...and it performs similar to "plus32": >> http://cr.openjdk.java.net/~shade/8076759/data-foot.png >> http://cr.openjdk.java.net/~shade/8076759/data-perf.png >> >>> Otherwise, looks fine to me also. >> I actually wonder if my change in ensureCapacity Javadoc requires a CCC? >> On that topic, I also tempted to remove the implementation details from >> the Javadoc there, since it does not play well with "describe what you >> will do, not how would you do it". >> >> Thanks, >> -Aleksey. >> > From ivan.gerasimov at oracle.com Tue May 5 18:02:31 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 05 May 2015 21:02:31 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <8CE7C8C6-B31F-4BEB-AD2B-4E0C62FF39A9@oracle.com> References: <55486EA5.8000009@oracle.com> <8CE7C8C6-B31F-4BEB-AD2B-4E0C62FF39A9@oracle.com> Message-ID: <554905B7.6040605@oracle.com> Hi Paul On 05.05.2015 19:56, Paul Sandoz wrote: > Hi Ivan, > > ArrayList > -- > > You can simplify SubList with: > > private final class SubList extends AbstractList implements RandomAccess { > private final SubList parent; > private final int offset; > int size; > > // Top level sub-list > SubList(int offset, int fromIndex, int toIndex) { > this.parent = null; > this.offset = offset + fromIndex; > this.size = toIndex - fromIndex; > this.modCount = ArrayList.this.modCount; > } > > // Sub sub-lst > SubList(SubList parent, > int offset, int fromIndex, int toIndex) { > this.parent = parent; > this.offset = offset + fromIndex; > this.size = toIndex - fromIndex; > this.modCount = ArrayList.this.modCount; > } > > ArrayList.subList becomes: > > public List subList(int fromIndex, int toIndex) { > subListRangeCheck(fromIndex, toIndex, size); > return new SubList(0, fromIndex, toIndex); > } > > And SubList.subList: > > public List subList(int fromIndex, int toIndex) { > subListRangeCheck(fromIndex, toIndex, size); > return new SubList(this, offset, fromIndex, toIndex); > } > > And SubList. updateSizeAndModCount: > > private void updateSizeAndModCount(int sizeChange) { > int modCount = ArrayList.this.modCount; > for (SubList slist = this; slist != null; slist = slist.parent) { > slist.size += sizeChange; > slist.modCount = modCount; > } > } > Thanks for suggestion! I should have realized this myself, that there's no need to set parent to ArrayList.this. It was a left-over from the previous design, when parent was used in different ways. > AbstractList > -- > > Similar changes can be made as above to ArrayList.SubList etc. > > The construction of sub-lists does indeed require a second take. A comment is worthwhile. IMO such scoping is not necessary for ArrayList, i have actually found it rare to require such scoping so using it when not necessary is rather jarring. > Okay, I'll reorganize it to make SubList classes stand-alone, not inner classes. Let's see, if it makes the things nicer. > NestedSubList > -- > > My preference is you use a testng data provider so you don't have to roll your own failure checking and reporting. > Are there any other tests for testing the integrity of sublists? I found only a few tests that test some parts of the functionality: test/java/util/List/LockStep.java test/java/util/Collection/MOAT.java I'll post an update on the code and test soon. Sincerely yours, Ivan From lance.andersen at oracle.com Tue May 5 18:25:25 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 5 May 2015 14:25:25 -0400 Subject: RFR [9] 8079342: some docs cleanup for CORBA - part 2 In-Reply-To: <5548F015.7080304@oracle.com> References: <5548DFEE.2030504@oracle.com> <8727E323-15ED-47DF-91A1-07C1C765203D@oracle.com> <5548E4BB.6030002@oracle.com> <891F11C6-E91C-4646-ACD7-AADE2B2AC770@oracle.com> <5548F015.7080304@oracle.com> Message-ID: <03B9EB84-7639-4A5E-A77C-D3D1526AEE5F@oracle.com> The changes seem reasonable those the comments in ValueBoxGen24 are somewhat cryptic to me at least :-) On May 5, 2015, at 12:30 PM, alexander stepanov wrote: > > _variableName in the public javadocs > > Please see > http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/src/java.corba/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java.udiff.html > (please update the page as I didn't prepare a new webrev). Hopefully that do not harm the code... > > Thanks, > Alexander > > On 05.05.2015 18:46, Lance Andersen wrote: >> Hi Alexander, >> >> Thank you, I guess I am not a fan of _variableName in the public javadocs as it is not something we normally see. >> >> Understand less is more, especially with CORBA. >> >> On May 5, 2015, at 11:41 AM, alexander stepanov > wrote: >> >>> Hello Lance, >>> >>> It just seemed to be less hazardous. E.g., method 'readValue' (in ValueHandlerImpl) contains inner variable 'in' and parameter '_in' being documented (also, '_sender' - 'sender'). >>> >>> But of course the names could be swapped, if desired. I lazily preferred not to touch the code (just in case...). >>> >>> Regards, >>> Alexander >>> >>> >>> On 05.05.2015 18:25, Lance Andersen wrote: >>>> Hi Alexander, >>>> >>>> I just started to look at this and have a question: >>>> >>>> >>>> /** >>>> * Writes the value to the stream using java semantics. >>>> - * @param out The stream to write the value to >>>> + * @param _out The stream to write the value to >>>> * @param value The value to be written to the stream >>>> **/ >>>> public void writeValue(org.omg.CORBA.portable.OutputStream _out, >>>> >>>> >>>> Is there a reason that you did not change the parameter name to "out" vs changing the @param tag to "_out" ? >>>> >>>> Best, >>>> lance >>>> >>>> >>>> On May 5, 2015, at 11:21 AM, alexander stepanov > wrote: >>>> >>>>> Hello, >>>>> >>>>> Could you please review the following fix >>>>> http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/ >>>>> for >>>>> https://bugs.openjdk.java.net/browse/JDK-8079342 >>>>> >>>>> Just some HTML markup fix for CORBA. >>>>> >>>>> Thanks, >>>>> Alexander >>>> >>>> >>>> >>>> Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 >>>> Oracle Java Engineering >>>> 1 Network Drive >>>> Burlington, MA 01803 >>>> Lance.Andersen at oracle.com >>>> >>>> >>>> >>> >> >> >> >> Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 >> Oracle Java Engineering >> 1 Network Drive >> Burlington, MA 01803 >> Lance.Andersen at oracle.com >> >> >> > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From mandy.chung at oracle.com Tue May 5 20:33:27 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 05 May 2015 13:33:27 -0700 Subject: RFR(M): 8078896: Add @modules as needed to the jdk_svc tests In-Reply-To: <55488794.3060008@oracle.com> References: <55488794.3060008@oracle.com> Message-ID: <55492917.6010200@oracle.com> On 05/05/2015 02:04 AM, Yekaterina Kantserova wrote: > Hi, > > Could I please have a review of this fix. > > bug: https://bugs.openjdk.java.net/browse/JDK-8078896 > webrev: http://cr.openjdk.java.net/~ykantser/8078896 > com.sun.management has been moved to jdk.management module. The patch for JDK-8042901 is just integrated in jdk9/dev today. Most, if not all, test/com/sun/management tests need updates to require @modules jdk.management. There are several test/java/lang/management tests dependng on both java.lang.management and com.sun.management. For tests only using java.lang.management API, @modules java.management is adequate. test/com/sun/jdi/InterfaceMethodsTest.java test/com/sun/jdi/InterruptHangTest.java Since you have updated the end year of the copyright header in most tests, I spot a couple and so mention it to you. Otherwise looks good. Thanks for doing this. Mandy From kumar.x.srinivasan at oracle.com Tue May 5 20:37:39 2015 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Tue, 05 May 2015 13:37:39 -0700 Subject: RFR (XS): 8078225: tools/launcher/FXLauncherTest.java fails intermittently (win) Message-ID: <55492A13.9010404@oracle.com> Hello, Please review the simple fix which allows the test to be run in its own vm, there seems to be some issue with the harness running in a concurrent mode specifically on Windows. Thanks Kumar diff --git a/test/tools/launcher/FXLauncherTest.java b/test/tools/launcher/FXLauncherTest.java --- a/test/tools/launcher/FXLauncherTest.java +++ b/test/tools/launcher/FXLauncherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * Test uses main method and blank main method, a jfx app class and an incorrest * jfx app class, a main-class for the manifest, a bogus one and none. * All should execute except the incorrect fx app class entries. - * @run main FXLauncherTest + * @run main/othervm FXLauncherTest */ import java.io.File; import java.io.IOException; From mandy.chung at oracle.com Tue May 5 21:00:35 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 05 May 2015 14:00:35 -0700 Subject: RFR(M): 8078896: Add @modules as needed to the jdk_svc tests In-Reply-To: <55492917.6010200@oracle.com> References: <55488794.3060008@oracle.com> <55492917.6010200@oracle.com> Message-ID: <55492F73.2020806@oracle.com> On 05/05/2015 01:33 PM, Mandy Chung wrote: > > > On 05/05/2015 02:04 AM, Yekaterina Kantserova wrote: >> Hi, >> >> Could I please have a review of this fix. >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8078896 >> webrev: http://cr.openjdk.java.net/~ykantser/8078896 >> > > com.sun.management has been moved to jdk.management module. The patch > for JDK-8042901 is just integrated in jdk9/dev today. Most, if not > all, test/com/sun/management tests need updates to require @modules > jdk.management. > > There are several test/java/lang/management tests dependng on both > java.lang.management and com.sun.management. For tests only using > java.lang.management API, @modules java.management is adequate. > > test/com/sun/jdi/InterfaceMethodsTest.java > test/com/sun/jdi/InterruptHangTest.java > Since you have updated the end year of the copyright header in most > tests, I spot a couple and so mention it to you. > > Otherwise looks good. Thanks for doing this. About the test selection, one typical aspect of svc tests is to run a j* tool in a child process (e.g. jinfo, jstack, jstat, jstatd,jcmd, jps etc that are in jdk.jcmd module). I would expect all test/sun/tools/jcmd tests should have @modules jdk.jcmd and similiar for other sun/tools/j* tests. Are you thinking to come back in the next round of test selection update? Mandy From joe.darcy at oracle.com Tue May 5 21:02:36 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Tue, 05 May 2015 14:02:36 -0700 Subject: RFR (XS): 8078225: tools/launcher/FXLauncherTest.java fails intermittently (win) In-Reply-To: <55492A13.9010404@oracle.com> References: <55492A13.9010404@oracle.com> Message-ID: <55492FEC.9030804@oracle.com> Looks fine Kumar; thanks, -Joe On 5/5/2015 1:37 PM, Kumar Srinivasan wrote: > Hello, > > Please review the simple fix which allows the test to be run in its > own vm, > there seems to be some issue with the harness running in a concurrent > mode > specifically on Windows. > > Thanks > Kumar > > diff --git a/test/tools/launcher/FXLauncherTest.java > b/test/tools/launcher/FXLauncherTest.java > --- a/test/tools/launcher/FXLauncherTest.java > +++ b/test/tools/launcher/FXLauncherTest.java > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights > reserved. > + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights > reserved. > * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > * > * This code is free software; you can redistribute it and/or modify it > @@ -28,7 +28,7 @@ > * Test uses main method and blank main method, a jfx app class and > an incorrest > * jfx app class, a main-class for the manifest, a bogus one and none. > * All should execute except the incorrect fx app class entries. > - * @run main FXLauncherTest > + * @run main/othervm FXLauncherTest > */ > import java.io.File; > import java.io.IOException; > > From joe.darcy at oracle.com Tue May 5 21:53:31 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Tue, 05 May 2015 14:53:31 -0700 Subject: JDK 9 RFR of Update to RegEx test to use random number library Message-ID: <55493BDB.9090102@oracle.com> Hello, The regression test test/java/util/regex/RegExTest.java has been observed to intermittently fail. As the test uses randomness, I'd like to update to the test to use the random number testing library to better identify the cause of any future failures. Please review the patch below: diff -r 207c1b0356ea test/java/util/regex/RegExTest.java --- a/test/java/util/regex/RegExTest.java Tue May 05 17:55:16 2015 +0100 +++ b/test/java/util/regex/RegExTest.java Tue May 05 14:50:10 2015 -0700 @@ -23,7 +23,7 @@ /** * @test - * @summary tests RegExp framework + * @summary tests RegExp framework (use -Dseed=X to set PRNG seed) * @author Mike McCloskey * @bug 4481568 4482696 4495089 4504687 4527731 4599621 4631553 4619345 * 4630911 4672616 4711773 4727935 4750573 4792284 4803197 4757029 4808962 @@ -33,6 +33,9 @@ * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066 * 7067045 7014640 7189363 8007395 8013252 8013254 8012646 8023647 6559590 * 8027645 8035076 8039124 8035975 8074678 + * @library /lib/testlibrary + * @build jdk.testlibrary.* + * @run main RegExTest * @key randomness */ @@ -50,7 +53,7 @@ */ public class RegExTest { - private static Random generator = new Random(); + private static Random generator = RandomFactory.getRandom(); private static boolean failure = false; private static int failCount = 0; private static String firstFailure = null; Thanks, -Joe From wasserman.louis at gmail.com Tue May 5 22:02:04 2015 From: wasserman.louis at gmail.com (Louis Wasserman) Date: Tue, 05 May 2015 22:02:04 +0000 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554905B7.6040605@oracle.com> References: <55486EA5.8000009@oracle.com> <8CE7C8C6-B31F-4BEB-AD2B-4E0C62FF39A9@oracle.com> <554905B7.6040605@oracle.com> Message-ID: Just checking -- IIRC, this will change the semantics of how structural modifications to a subList of a subList will affect the first subList. For example, I believe in the past, removing an element from a subList of a subList would decrease the size of the first subList by 1, but now the first subList will represent the same range of indices, and another element will be moved into that subList. Is that an accurate representation of current behavior? Is changing that behavior acceptable in this context? On Tue, May 5, 2015 at 11:02 AM Ivan Gerasimov wrote: > Hi Paul > > On 05.05.2015 19:56, Paul Sandoz wrote: > > Hi Ivan, > > > > ArrayList > > -- > > > > You can simplify SubList with: > > > > private final class SubList extends AbstractList implements > RandomAccess { > > private final SubList parent; > > private final int offset; > > int size; > > > > // Top level sub-list > > SubList(int offset, int fromIndex, int toIndex) { > > this.parent = null; > > this.offset = offset + fromIndex; > > this.size = toIndex - fromIndex; > > this.modCount = ArrayList.this.modCount; > > } > > > > // Sub sub-lst > > SubList(SubList parent, > > int offset, int fromIndex, int toIndex) { > > this.parent = parent; > > this.offset = offset + fromIndex; > > this.size = toIndex - fromIndex; > > this.modCount = ArrayList.this.modCount; > > } > > > > ArrayList.subList becomes: > > > > public List subList(int fromIndex, int toIndex) { > > subListRangeCheck(fromIndex, toIndex, size); > > return new SubList(0, fromIndex, toIndex); > > } > > > > And SubList.subList: > > > > public List subList(int fromIndex, int toIndex) { > > subListRangeCheck(fromIndex, toIndex, size); > > return new SubList(this, offset, fromIndex, toIndex); > > } > > > > And SubList. updateSizeAndModCount: > > > > private void updateSizeAndModCount(int sizeChange) { > > int modCount = ArrayList.this.modCount; > > for (SubList slist = this; slist != null; slist = slist.parent) { > > slist.size += sizeChange; > > slist.modCount = modCount; > > } > > } > > > Thanks for suggestion! > I should have realized this myself, that there's no need to set parent > to ArrayList.this. > It was a left-over from the previous design, when parent was used in > different ways. > > > AbstractList > > -- > > > > Similar changes can be made as above to ArrayList.SubList etc. > > > > The construction of sub-lists does indeed require a second take. A > comment is worthwhile. IMO such scoping is not necessary for ArrayList, i > have actually found it rare to require such scoping so using it when not > necessary is rather jarring. > > > Okay, I'll reorganize it to make SubList classes stand-alone, not inner > classes. > Let's see, if it makes the things nicer. > > > NestedSubList > > -- > > > > My preference is you use a testng data provider so you don't have to > roll your own failure checking and reporting. > > Are there any other tests for testing the integrity of sublists? > > I found only a few tests that test some parts of the functionality: > test/java/util/List/LockStep.java > test/java/util/Collection/MOAT.java > > > I'll post an update on the code and test soon. > > Sincerely yours, > Ivan > > From xueming.shen at oracle.com Tue May 5 22:25:15 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 05 May 2015 15:25:15 -0700 Subject: JDK 9 RFR of Update to RegEx test to use random number library In-Reply-To: <55493BDB.9090102@oracle.com> References: <55493BDB.9090102@oracle.com> Message-ID: <5549434B.1090003@oracle.com> looks fine. On 5/5/15 2:53 PM, Joseph D. Darcy wrote: > Hello, > > The regression test > > test/java/util/regex/RegExTest.java > > has been observed to intermittently fail. As the test uses randomness, > I'd like to update to the test to use the random number testing > library to better identify the cause of any future failures. > > Please review the patch below: > > diff -r 207c1b0356ea test/java/util/regex/RegExTest.java > --- a/test/java/util/regex/RegExTest.java Tue May 05 17:55:16 2015 > +0100 > +++ b/test/java/util/regex/RegExTest.java Tue May 05 14:50:10 2015 > -0700 > @@ -23,7 +23,7 @@ > > /** > * @test > - * @summary tests RegExp framework > + * @summary tests RegExp framework (use -Dseed=X to set PRNG seed) > * @author Mike McCloskey > * @bug 4481568 4482696 4495089 4504687 4527731 4599621 4631553 4619345 > * 4630911 4672616 4711773 4727935 4750573 4792284 4803197 4757029 > 4808962 > @@ -33,6 +33,9 @@ > * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 > 7039066 > * 7067045 7014640 7189363 8007395 8013252 8013254 8012646 8023647 > 6559590 > * 8027645 8035076 8039124 8035975 8074678 > + * @library /lib/testlibrary > + * @build jdk.testlibrary.* > + * @run main RegExTest > * @key randomness > */ > > @@ -50,7 +53,7 @@ > */ > public class RegExTest { > > - private static Random generator = new Random(); > + private static Random generator = RandomFactory.getRandom(); > private static boolean failure = false; > private static int failCount = 0; > private static String firstFailure = null; > > Thanks, > > -Joe From ivan.gerasimov at oracle.com Wed May 6 03:51:51 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 06 May 2015 06:51:51 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: References: <55486EA5.8000009@oracle.com> <8CE7C8C6-B31F-4BEB-AD2B-4E0C62FF39A9@oracle.com> <554905B7.6040605@oracle.com> Message-ID: <55498FD7.7030205@oracle.com> Thanks Louis for looking at this! Removing an element from a sub-sublist is done as: 549 public E remove(int index) { 550 rangeCheck(index); 551 checkForComodification(); 552 E result = AbstractList.this.remove(index + offset); 553 updateSizeAndModCount(-1, AbstractList.this.modCount); 554 return result; 555 } It first removes the element from the root list at the line 552. Then, it updates sizes of all sublist in the chain at 553, so that sizes of sublist and sub-sublist are decreased by one. Sincerely yours, Ivan On 06.05.2015 1:02, Louis Wasserman wrote: > Just checking -- IIRC, this will change the semantics of how > structural modifications to a subList of a subList will affect the > first subList. For example, I believe in the past, removing an > element from a subList of a subList would decrease the size of the > first subList by 1, but now the first subList will represent the same > range of indices, and another element will be moved into that subList. > > Is that an accurate representation of current behavior? Is changing > that behavior acceptable in this context? > > On Tue, May 5, 2015 at 11:02 AM Ivan Gerasimov > > wrote: > > Hi Paul > > On 05.05.2015 19:56, Paul Sandoz wrote: > > Hi Ivan, > > > > ArrayList > > -- > > > > You can simplify SubList with: > > > > private final class SubList extends AbstractList implements > RandomAccess { > > private final SubList parent; > > private final int offset; > > int size; > > > > // Top level sub-list > > SubList(int offset, int fromIndex, int toIndex) { > > this.parent = null; > > this.offset = offset + fromIndex; > > this.size = toIndex - fromIndex; > > this.modCount = ArrayList.this.modCount; > > } > > > > // Sub sub-lst > > SubList(SubList parent, > > int offset, int fromIndex, int toIndex) { > > this.parent = parent; > > this.offset = offset + fromIndex; > > this.size = toIndex - fromIndex; > > this.modCount = ArrayList.this.modCount; > > } > > > > ArrayList.subList becomes: > > > > public List subList(int fromIndex, int toIndex) { > > subListRangeCheck(fromIndex, toIndex, size); > > return new SubList(0, fromIndex, toIndex); > > } > > > > And SubList.subList: > > > > public List subList(int fromIndex, int toIndex) { > > subListRangeCheck(fromIndex, toIndex, size); > > return new SubList(this, offset, fromIndex, toIndex); > > } > > > > And SubList. updateSizeAndModCount: > > > > private void updateSizeAndModCount(int sizeChange) { > > int modCount = ArrayList.this.modCount; > > for (SubList slist = this; slist != null; slist = > slist.parent) { > > slist.size += sizeChange; > > slist.modCount = modCount; > > } > > } > > > Thanks for suggestion! > I should have realized this myself, that there's no need to set parent > to ArrayList.this. > It was a left-over from the previous design, when parent was used in > different ways. > > > AbstractList > > -- > > > > Similar changes can be made as above to ArrayList.SubList etc. > > > > The construction of sub-lists does indeed require a second take. > A comment is worthwhile. IMO such scoping is not necessary for > ArrayList, i have actually found it rare to require such scoping > so using it when not necessary is rather jarring. > > > Okay, I'll reorganize it to make SubList classes stand-alone, not > inner > classes. > Let's see, if it makes the things nicer. > > > NestedSubList > > -- > > > > My preference is you use a testng data provider so you don't > have to roll your own failure checking and reporting. > > Are there any other tests for testing the integrity of sublists? > > I found only a few tests that test some parts of the functionality: > test/java/util/List/LockStep.java > test/java/util/Collection/MOAT.java > > > I'll post an update on the code and test soon. > > Sincerely yours, > Ivan > From martinrb at google.com Wed May 6 04:18:25 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 5 May 2015 21:18:25 -0700 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <55498FD7.7030205@oracle.com> References: <55486EA5.8000009@oracle.com> <8CE7C8C6-B31F-4BEB-AD2B-4E0C62FF39A9@oracle.com> <554905B7.6040605@oracle.com> <55498FD7.7030205@oracle.com> Message-ID: The problem of deep nesting of sublists was known to previous generations of ArrayList maintainers. We got discouraged because there is no known way to make operations that are O(1) on the full list also O(1) on subsub...sublists. It's especially a performance problem when you use ArrayLists with a divide-and-conquer algorithm like fork/join (hint - use arrays instead) But if you can keep space consumption (if not CPU consumption) O(1) while preserving other behavior, that might be progress. From Alan.Bateman at oracle.com Wed May 6 07:17:42 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 06 May 2015 08:17:42 +0100 Subject: RFR(M): 8078896: Add @modules as needed to the jdk_svc tests In-Reply-To: <55492F73.2020806@oracle.com> References: <55488794.3060008@oracle.com> <55492917.6010200@oracle.com> <55492F73.2020806@oracle.com> Message-ID: <5549C016.20002@oracle.com> On 05/05/2015 22:00, Mandy Chung wrote: > : > > > About the test selection, one typical aspect of svc tests is to run a > j* tool in a child process (e.g. jinfo, jstack, jstat, jstatd,jcmd, > jps etc that are in jdk.jcmd module). I would expect all > test/sun/tools/jcmd tests should have @modules jdk.jcmd and similiar > for other sun/tools/j* tests. Are you thinking to come back in the > next round of test selection update? Alexander Kulyakhtin's tool hasn't been pushed to jdk9/dev yet but I expect it will be run regularly to keep the tests updated. For modules then we're mostly interested in the tests that make use of JDK-internal APIs of course, the test selection aspect is for later when jtreg has support for this. -Alan From peter.levart at gmail.com Wed May 6 07:57:43 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 06 May 2015 09:57:43 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55481C1B.5030309@oracle.com> References: <55479A4F.4060806@oracle.com> <55481C1B.5030309@oracle.com> Message-ID: <5549C977.8030100@gmail.com> On 05/05/2015 03:25 AM, David Holmes wrote: > Hi Brent, > > On 5/05/2015 2:11 AM, Brent Christian wrote: >> Hi, >> >> Please review this fix, courtesy of Peter Levart (thanks!), that I would >> like to get in. >> >> https://bugs.openjdk.java.net/browse/JDK-8029891 >> http://cr.openjdk.java.net/~bchristi/8029891/webrev.0/ >> >> There is some discussion of it in the bug report, starting at >> 2014-12-31. >> >> The problem, as stated by Mandy: >> >> "System Properties is a hashtable that synchronizes on itself for any >> access. Currently System.getProperties returns the Properties instance >> accessed by the system in which any application code might synchronize >> on it (that's what the test is doing). The problem reported JDK-6977738 >> is about Properties.store method that was fixed not to synchronize on >> this instance. System property is a common way for changing the default >> setting and so it's impractical to expect the class loading code path >> not to call System.getProperty." >> >> This fix changes java.util.Properties to store its values in an internal >> ConcurrentHashMap, ignoring its Hashtable heritage. In this way, >> Properties can be "de-sychronized": all methods inherited from Hashtable >> are overridden, to remove synchronization, and delegate to the internal >> CHM. > > I don't think you want to de-synchronize the load* methods - you don't > want two threads calling load concurrently. But that then raises the > problem of concurrent modification while a load is in progress. > Synchronization ensures serialization and by removing it you have done > more than just avoid deadlocks. > > I think this needs a more careful examination of the expected/desired > concurrent interactions between different methods. It may be that > simply not utilizing the synchronized Hashtable methods is sufficient > to resolve the deadlock, while still providing reasonable > serialization via the existing synchronized Properties methods - or it > may not. But allowing concurrent modifications will change behaviour > in an unexpected, and incompatible way, in my opinion. > > David > ----- Hi David, You say: "It may be that simply not utilizing the synchronized Hashtable methods is sufficient to resolve the deadlock, while still providing reasonable serialization via the existing synchronized Properties methods - or it may not". How do you propose to not utilize synchronized Hashtable methods? By not utilizing Properties at all? This may be difficult to achieve as most system configuration is specified as system Properties. So what about taking a more conservative approach by making all "modification" and "bulk" methods synchronized and exposing just single-entry "read-only" methods as not synchronized (mainly Hashatable.get())? Regards, Peter > >> The serialized form is unchanged. >> >> >> An alternative approach considered would be for System.getProperties() >> to return a duplicate snapshot of the current Properties. This presents >> a compatibility risk to existing code that keeps a reference to the >> return value of System.getProperties() and expects to either read new >> properties added afterwards, or set properties on the cached copy. >> >> -Brent >> From paul.sandoz at oracle.com Wed May 6 08:14:47 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 6 May 2015 10:14:47 +0200 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: <55481FA5.1060407@oracle.com> Message-ID: On May 5, 2015, at 7:39 PM, Martin Buchholz wrote: > I'd prefer to go the other way, deleting those trivial methods entirely, utilizing the rarely used .new syntax. > Very good, even better! Paul. From peter.levart at gmail.com Wed May 6 08:27:53 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 06 May 2015 10:27:53 +0200 Subject: JEP 132: More-prompt finalization Message-ID: <5549D089.5090606@gmail.com> Hi, Is there any interest to propose JEP 132 for JDK9 ? I have some ideas how to achieve it's goals. Regards, Peter From pavel.rappo at oracle.com Wed May 6 09:12:33 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 6 May 2015 10:12:33 +0100 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: References: <55486EA5.8000009@oracle.com> <8CE7C8C6-B31F-4BEB-AD2B-4E0C62FF39A9@oracle.com> <554905B7.6040605@oracle.com> <55498FD7.7030205@oracle.com> Message-ID: <1176D029-3948-4091-B7C4-0557FF74AD32@oracle.com> Ivan, It looks like your change (I don't know whether it was intentional or not) brings some more "fail-fast"-ness which is good! For instance, before the change, this snippet: List integers = new LinkedList<>(); integers.addAll(Arrays.asList(0, 1)); List sublist = integers.subList(0, 2).subList(0, 2); System.out.print(sublist.size()); integers.clear(); System.out.print(" " + sublist.size()); would shamelessly produce: 2 2. But now it throws CME. Which is more expected I believe. The reason is that now `checkForComodification` consults topmost list rather than an immediate parent. Well to AbstractList's credit it's not a bug as it falls into the category described in javadoc of java.util.List.subList: * The semantics of the list returned by this method become undefined if * the backing list (i.e., this list) is structurally modified in * any way other than via the returned list. (Structural modifications are * those that change the size of this list, or otherwise perturb it in such * a fashion that iterations in progress may yield incorrect results.) But still, it's a nice bonus for safety. -Pavel From david.holmes at oracle.com Wed May 6 09:41:40 2015 From: david.holmes at oracle.com (David Holmes) Date: Wed, 06 May 2015 19:41:40 +1000 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <5549C977.8030100@gmail.com> References: <55479A4F.4060806@oracle.com> <55481C1B.5030309@oracle.com> <5549C977.8030100@gmail.com> Message-ID: <5549E1D4.4030607@oracle.com> On 6/05/2015 5:57 PM, Peter Levart wrote: > > > On 05/05/2015 03:25 AM, David Holmes wrote: >> Hi Brent, >> >> On 5/05/2015 2:11 AM, Brent Christian wrote: >>> Hi, >>> >>> Please review this fix, courtesy of Peter Levart (thanks!), that I would >>> like to get in. >>> >>> https://bugs.openjdk.java.net/browse/JDK-8029891 >>> http://cr.openjdk.java.net/~bchristi/8029891/webrev.0/ >>> >>> There is some discussion of it in the bug report, starting at >>> 2014-12-31. >>> >>> The problem, as stated by Mandy: >>> >>> "System Properties is a hashtable that synchronizes on itself for any >>> access. Currently System.getProperties returns the Properties instance >>> accessed by the system in which any application code might synchronize >>> on it (that's what the test is doing). The problem reported JDK-6977738 >>> is about Properties.store method that was fixed not to synchronize on >>> this instance. System property is a common way for changing the default >>> setting and so it's impractical to expect the class loading code path >>> not to call System.getProperty." >>> >>> This fix changes java.util.Properties to store its values in an internal >>> ConcurrentHashMap, ignoring its Hashtable heritage. In this way, >>> Properties can be "de-sychronized": all methods inherited from Hashtable >>> are overridden, to remove synchronization, and delegate to the internal >>> CHM. >> >> I don't think you want to de-synchronize the load* methods - you don't >> want two threads calling load concurrently. But that then raises the >> problem of concurrent modification while a load is in progress. >> Synchronization ensures serialization and by removing it you have done >> more than just avoid deadlocks. >> >> I think this needs a more careful examination of the expected/desired >> concurrent interactions between different methods. It may be that >> simply not utilizing the synchronized Hashtable methods is sufficient >> to resolve the deadlock, while still providing reasonable >> serialization via the existing synchronized Properties methods - or it >> may not. But allowing concurrent modifications will change behaviour >> in an unexpected, and incompatible way, in my opinion. >> >> David >> ----- > > Hi David, > > You say: "It may be that simply not utilizing the synchronized Hashtable > methods is sufficient to resolve the deadlock, while still providing > reasonable serialization via the existing synchronized Properties > methods - or it may not". > > How do you propose to not utilize synchronized Hashtable methods? By not > utilizing Properties at all? This may be difficult to achieve as most > system configuration is specified as system Properties. What I meant was to continue to delegate to the CHM to replace the inherited Hashtable methods, but to keep the synchronized on the Properties specific methods. Cheers, David ----- > So what about taking a more conservative approach by making all > "modification" and "bulk" methods synchronized and exposing just > single-entry "read-only" methods as not synchronized (mainly > Hashatable.get())? > > Regards, Peter > >> >>> The serialized form is unchanged. >>> >>> >>> An alternative approach considered would be for System.getProperties() >>> to return a duplicate snapshot of the current Properties. This presents >>> a compatibility risk to existing code that keeps a reference to the >>> return value of System.getProperties() and expects to either read new >>> properties added afterwards, or set properties on the cached copy. >>> >>> -Brent >>> > From daniel.fuchs at oracle.com Wed May 6 10:06:17 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 06 May 2015 12:06:17 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <5549E1D4.4030607@oracle.com> References: <55479A4F.4060806@oracle.com> <55481C1B.5030309@oracle.com> <5549C977.8030100@gmail.com> <5549E1D4.4030607@oracle.com> Message-ID: <5549E799.4010902@oracle.com> On 06/05/15 11:41, David Holmes wrote: >>> I don't think you want to de-synchronize the load* methods - you don't >>> want two threads calling load concurrently. But that then raises the >>> problem of concurrent modification while a load is in progress. >>> Synchronization ensures serialization and by removing it you have done >>> more than just avoid deadlocks. >>> >>> I think this needs a more careful examination of the expected/desired >>> concurrent interactions between different methods. It may be that >>> simply not utilizing the synchronized Hashtable methods is sufficient >>> to resolve the deadlock, while still providing reasonable >>> serialization via the existing synchronized Properties methods - or it >>> may not. But allowing concurrent modifications will change behaviour >>> in an unexpected, and incompatible way, in my opinion. >>> >>> David >>> ----- >> >> Hi David, >> >> You say: "It may be that simply not utilizing the synchronized Hashtable >> methods is sufficient to resolve the deadlock, while still providing >> reasonable serialization via the existing synchronized Properties >> methods - or it may not". >> >> How do you propose to not utilize synchronized Hashtable methods? By not >> utilizing Properties at all? This may be difficult to achieve as most >> system configuration is specified as system Properties. > > What I meant was to continue to delegate to the CHM to replace the > inherited Hashtable methods, but to keep the synchronized on the > Properties specific methods. What about changing load0 to return a plain HashMap? Then you could transfer the HashMap content into the CHM in one go - that's the only part that really needs to be protected against concurrent modification, isn't it? The PropertiesDefaultHandler could also be changed to use an intermediate HashMap object as well. There would be a small compatibility issue however if some subclass of Properties has some special logic for the case where a property is declared twice (for instance, if it overrides put() to merge values)... best regards, -- daniel From alexander.v.stepanov at oracle.com Wed May 6 10:15:32 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Wed, 06 May 2015 13:15:32 +0300 Subject: RFR [9] 8079342: some docs cleanup for CORBA - part 2 In-Reply-To: <03B9EB84-7639-4A5E-A77C-D3D1526AEE5F@oracle.com> References: <5548DFEE.2030504@oracle.com> <8727E323-15ED-47DF-91A1-07C1C765203D@oracle.com> <5548E4BB.6030002@oracle.com> <891F11C6-E91C-4646-ACD7-AADE2B2AC770@oracle.com> <5548F015.7080304@oracle.com> <03B9EB84-7639-4A5E-A77C-D3D1526AEE5F@oracle.com> Message-ID: <5549E9C4.3030101@oracle.com> Thanks! > the comments in ValueBoxGen24 are somewhat cryptic to me at least Yes, indeed... Roger mentioned that these may be some (outdated?) bug tracker references, so I prefer not to touch them; just remove the angle brackets to avoid warnings. Regards, Alexander On 05.05.2015 21:25, Lance Andersen wrote: > The changes seem reasonable those the comments in ValueBoxGen24 are > somewhat cryptic to me at least :-) > > On May 5, 2015, at 12:30 PM, alexander stepanov > > wrote: > >> > _variableName in the public javadocs >> >> Please see >> http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/src/java.corba/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java.udiff.html >> >> (please update the page as I didn't prepare a new webrev). Hopefully >> that do not harm the code... >> >> Thanks, >> Alexander >> >> On 05.05.2015 18:46, Lance Andersen wrote: >>> Hi Alexander, >>> >>> Thank you, I guess I am not a fan of _variableName in the public >>> javadocs as it is not something we normally see. >>> >>> Understand less is more, especially with CORBA. >>> >>> On May 5, 2015, at 11:41 AM, alexander stepanov >>> >> > wrote: >>> >>>> Hello Lance, >>>> >>>> It just seemed to be less hazardous. E.g., method 'readValue' (in >>>> ValueHandlerImpl) contains inner variable 'in' and parameter '_in' >>>> being documented (also, '_sender' - 'sender'). >>>> >>>> But of course the names could be swapped, if desired. I lazily >>>> preferred not to touch the code (just in case...). >>>> >>>> Regards, >>>> Alexander >>>> >>>> >>>> On 05.05.2015 18:25, Lance Andersen wrote: >>>>> Hi Alexander, >>>>> >>>>> I just started to look at this and have a question: >>>>> >>>>> >>>>> /** >>>>> * Writes the value to the stream using java semantics. >>>>> - * @param out The stream to write the value to >>>>> + * @param _out The stream to write the value to >>>>> * @param value The value to be written to the stream >>>>> **/ >>>>> public void writeValue(org.omg.CORBA.portable.OutputStream _out, >>>>> >>>>> >>>>> Is there a reason that you did not change the parameter name to >>>>> "out" vs changing the @param tag to "_out" ? >>>>> >>>>> Best, >>>>> lance >>>>> >>>>> >>>>> On May 5, 2015, at 11:21 AM, alexander stepanov >>>>> >>>> >>>>> > wrote: >>>>> >>>>>> Hello, >>>>>> >>>>>> Could you please review the following fix >>>>>> http://cr.openjdk.java.net/~avstepan/8079342/webrev.00/ >>>>>> >>>>>> >>>>>> for >>>>>> https://bugs.openjdk.java.net/browse/JDK-8079342 >>>>>> >>>>>> Just some HTML markup fix for CORBA. >>>>>> >>>>>> Thanks, >>>>>> Alexander >>>>> >>>>> >>>>> >>>>> Lance >>>>> Andersen| Principal Member of Technical Staff | +1.781.442.2037 >>>>> Oracle Java Engineering >>>>> 1 Network Drive >>>>> Burlington, MA 01803 >>>>> Lance.Andersen at oracle.com >>>>> >>>>> >>>>> >>>>> >>>> >>> >>> >>> >>> Lance >>> Andersen| Principal Member of Technical Staff | +1.781.442.2037 >>> Oracle Java Engineering >>> 1 Network Drive >>> Burlington, MA 01803 >>> Lance.Andersen at oracle.com >>> >>> >>> >> > > > > Lance > Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From paul.sandoz at oracle.com Wed May 6 10:37:34 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 6 May 2015 12:37:34 +0200 Subject: Add Predicate.of(), Consumer.of(), etc. In-Reply-To: <55454241.8030409@univ-mlv.fr> References: <55454241.8030409@univ-mlv.fr> Message-ID: <035D1CE5-592A-4834-AC2E-9FBE0911F122@oracle.com> On May 2, 2015, at 11:31 PM, Remi Forax wrote: > Hi all, > today, I stubble on a variant of JDK-8050818 [1], > trying to call negate() on a lambda which is not yet a Predicate (due to target typing) which requires either to cast the lambda to a Predicate and everybody knows that cast are evil or to add a local variable. > > I think there is a way to fix that, it's not very orthodox so I let you judge. > The idea is to introduce a static method 'of' on Predicate, > class Predicate { > ... > public static Predicate of(Predicate predicate) { > return predicate; > } > } > > so one can write: > stream.filter(Predicate.of(String::isEmpty).negate()) > compared to > stream.filter(((Predicate)String::isEmpty).negate()) > > so the question is, does it it worth the cost to introduce a static method that basically do nothing on all functional interfaces of java.util.function. > That does have the virtue of not adding a static method per operation but i still cannot bring myself to add such methods as a work around for seems like a compiler inference problem (albeit one in which might be very tricky or not possible to solve). In some respects i wonder if the default methods on the functional interfaces are an attractive nuisance. Paul. From yekaterina.kantserova at oracle.com Wed May 6 11:21:45 2015 From: yekaterina.kantserova at oracle.com (Yekaterina Kantserova) Date: Wed, 06 May 2015 13:21:45 +0200 Subject: RFR(M): 8078896: Add @modules as needed to the jdk_svc tests In-Reply-To: <55492F73.2020806@oracle.com> References: <55488794.3060008@oracle.com> <55492917.6010200@oracle.com> <55492F73.2020806@oracle.com> Message-ID: <5549F949.4010300@oracle.com> Mandy, Thanks fro your review! Please see my comment inlined. On 05/05/2015 11:00 PM, Mandy Chung wrote: >> com.sun.management has been moved to jdk.management module. The >> patch for JDK-8042901 is just integrated in jdk9/dev today. Most, if >> not all, test/com/sun/management tests need updates to require >> @modules jdk.management. >> >> There are several test/java/lang/management tests dependng on both >> java.lang.management and com.sun.management. For tests only using >> java.lang.management API, @modules java.management is adequate. >> >> test/com/sun/jdi/InterfaceMethodsTest.java The copyright header contains already 2015. >> test/com/sun/jdi/InterruptHangTest.java The test has been missing copyrights, I've updated it with the copyright header. >> Since you have updated the end year of the copyright header in >> most tests, I spot a couple and so mention it to you. >> >> Otherwise looks good. Thanks for doing this. The new webrev can be found here: http://cr.openjdk.java.net/~ykantser/8078896/webrev.02/ > > About the test selection, one typical aspect of svc tests is to run a > j* tool in a child process (e.g. jinfo, jstack, jstat, jstatd,jcmd, > jps etc that are in jdk.jcmd module). I would expect all > test/sun/tools/jcmd tests should have @modules jdk.jcmd and similiar > for other sun/tools/j* tests. Are you thinking to come back in the > next round of test selection update? As Alan pointed in his answer to this mail JTreg is not ready yet. I prefer to do it when it will be possible to test this change. Best regards, Katja > > Mandy From attila.szegedi at oracle.com Wed May 6 11:58:58 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Wed, 6 May 2015 13:58:58 +0200 Subject: Add Predicate.of(), Consumer.of(), etc. In-Reply-To: <035D1CE5-592A-4834-AC2E-9FBE0911F122@oracle.com> References: <55454241.8030409@univ-mlv.fr> <035D1CE5-592A-4834-AC2E-9FBE0911F122@oracle.com> Message-ID: <2D2F2B20-0FC7-430F-9C4B-696CCE775B29@oracle.com> On May 6, 2015, at 12:37 PM, Paul Sandoz wrote: > > > On May 2, 2015, at 11:31 PM, Remi Forax wrote: > >> Hi all, >> today, I stubble on a variant of JDK-8050818 [1], >> trying to call negate() on a lambda which is not yet a Predicate (due to target typing) which requires either to cast the lambda to a Predicate and everybody knows that cast are evil or to add a local variable. >> >> I think there is a way to fix that, it's not very orthodox so I let you judge. >> The idea is to introduce a static method 'of' on Predicate, >> class Predicate { >> ... >> public static Predicate of(Predicate predicate) { >> return predicate; >> } >> } >> >> so one can write: >> stream.filter(Predicate.of(String::isEmpty).negate()) >> compared to >> stream.filter(((Predicate)String::isEmpty).negate()) >> >> so the question is, does it it worth the cost to introduce a static method that basically do nothing on all functional interfaces of java.util.function. >> > > That does have the virtue of not adding a static method per operation but i still cannot bring myself to add such methods as a work around for seems like a compiler inference problem (albeit one in which might be very tricky or not possible to solve). I think it is firmly in the category of ?very tricky?, but probably still possible, albeit (from my point of view) undesirable. String::isEmpty will not, on its own, have a method named .negate(); the compiler can?t really infer the programmer?s intent to make it into a Predicate, not without a fairly high level reasoning (filter needs a Predicate; should the compiler perform an exhaustive search of the visible functional interfaces to see which one has a method with signature ?Predicate negate()??). So, yeah, it seems like in this case the programmer needs to communicate the intent. I think inference would be *possible*, but it?d be expensive, and would still allow for either ambiguities or accidentally matching something unexpected, so I think it would also be undesirable. I don?t have an opinion of whether we want an ?of? static method on Predicate, as then it would have to indeed be introduced on many other interfaces. It?s more appealing than a cast, certainly; especially since the cast apparently needs to specify the explicit type parameter too. > > In some respects i wonder if the default methods on the functional interfaces are an attractive nuisance. Meaning, if .negate(Predicate) were a static method on the Predicate class instead of a default method, then stream.filter(Predicate.negate(String::isEmpty)) would be possible? Yeah? Attila. > > Paul. > From ben_manes at yahoo.com Wed May 6 12:07:03 2015 From: ben_manes at yahoo.com (Ben Manes) Date: Wed, 6 May 2015 05:07:03 -0700 Subject: Add Predicate.of(), Consumer.of(), etc. In-Reply-To: <2D2F2B20-0FC7-430F-9C4B-696CCE775B29@oracle.com> Message-ID: <1430914023.70092.YahooMailAndroidMobile@web163206.mail.gq1.yahoo.com> Scala provides a filterNot method as a work around. This is a less generic fix, but arguably more pragmatic for the common case of the streams API.? Sent from Yahoo Mail on Android From:"Attila Szegedi" Date:Wed, May 6, 2015 at 4:59 am Subject:Re: Add Predicate.of(), Consumer.of(), etc. On May 6, 2015, at 12:37 PM, Paul Sandoz wrote: > > > On May 2, 2015, at 11:31 PM, Remi Forax wrote: > >> Hi all, >> today, I stubble on a variant of JDK-8050818 [1], >> trying to call negate() on a lambda which is not yet a Predicate (due to target typing) which requires either to cast the lambda to a Predicate and everybody knows that cast are evil or to add a local variable. >> >> I think there is a way to fix that, it's not very orthodox so I let you judge. >> The idea is to introduce a static method 'of' on Predicate, >> class Predicate { >>? ... >>? public static Predicate of(Predicate predicate) { >>? ? return predicate; >>? } >> } >> >> so one can write: >> stream.filter(Predicate.of(String::isEmpty).negate()) >> compared to >> stream.filter(((Predicate)String::isEmpty).negate()) >> >> so the question is, does it it worth the cost to introduce a static method that basically do nothing on all functional interfaces of java.util.function. >> > > That does have the virtue of not adding a static method per operation but i still cannot bring myself to add such methods as a work around for seems like a compiler inference problem (albeit one in which might be very tricky or not possible to solve). I think it is firmly in the category of ?very tricky?, but probably still possible, albeit (from my point of view) undesirable. String::isEmpty will not, on its own, have a method named .negate(); the compiler can?t really infer the programmer?s intent to make it into a Predicate, not without a fairly high level reasoning (filter needs a Predicate; should the compiler perform an exhaustive search of the visible functional interfaces to see which one has a method with signature ?Predicate negate()??). So, yeah, it seems like in this case the programmer needs to communicate the intent. I think inference would be *possible*, but it?d be expensive, and would still allow for either ambiguities or accidentally matching something unexpected, so I think it would also be undesirable. I don?t have an opinion of whether we want an ?of? static method on Predicate, as then it would have to indeed be introduced on many other interfaces. It?s more appealing than a cast, certainly; especially since the cast apparently needs to specify the explicit type parameter too. > > In some respects i wonder if the default methods on the functional interfaces are an attractive nuisance. Meaning, if .negate(Predicate) were a static method on the Predicate class instead of a default method, then stream.filter(Predicate.negate(String::isEmpty)) would be possible? Yeah? Attila. > > Paul. > From peter.levart at gmail.com Wed May 6 12:21:43 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 06 May 2015 14:21:43 +0200 Subject: RFR: JDK-8074002 java.time.ZoneId.systemDefault() should be faster In-Reply-To: References: <553E5513.7010209@gmail.com> Message-ID: <554A0757.2050400@gmail.com> Any official Reviewers with a couple of cycles to spare? Thanks, Peter Levart On 04/27/2015 08:24 PM, Stephen Colebourne wrote: > This seems like a good enhancement. > Stephen > > On 27 April 2015 at 16:26, Peter Levart wrote: >> Hi, >> >> Please review the following improvement that caches default ZoneId object >> and makes the frequently executed ZoneId.systemDefault() method faster: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneId.systemDefault/webrev.04/ >> >> The patch is just a rebased version of webrev.03 + some comments added about >> the importance of defensive cloning in TimeZone.setDefault(). There was >> already a discussion about this patch a while ago and Stephen basically >> approved it in this form: >> >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-February/031714.html >> >> >> Thanks, >> >> Peter Levart From daniel.fuchs at oracle.com Wed May 6 12:44:47 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 06 May 2015 14:44:47 +0200 Subject: RFR: JDK-8074002 java.time.ZoneId.systemDefault() should be faster In-Reply-To: <553E5513.7010209@gmail.com> References: <553E5513.7010209@gmail.com> Message-ID: <554A0CBF.8000207@oracle.com> Hi Peter, The logic looks good to me. But I'm not an expert of the field, despite my small incursions :-) I wish we didn't have to do defensive cloning - but I don't see any way around. best regards, -- daniel On 27/04/15 17:26, Peter Levart wrote: > Hi, > > Please review the following improvement that caches default ZoneId > object and makes the frequently executed ZoneId.systemDefault() method > faster: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneId.systemDefault/webrev.04/ > > > The patch is just a rebased version of webrev.03 + some comments added > about the importance of defensive cloning in TimeZone.setDefault(). > There was already a discussion about this patch a while ago and Stephen > basically approved it in this form: > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-February/031714.html > > > > Thanks, > > Peter Levart From paul.sandoz at oracle.com Wed May 6 13:53:09 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 6 May 2015 15:53:09 +0200 Subject: Add Predicate.of(), Consumer.of(), etc. In-Reply-To: <2D2F2B20-0FC7-430F-9C4B-696CCE775B29@oracle.com> References: <55454241.8030409@univ-mlv.fr> <035D1CE5-592A-4834-AC2E-9FBE0911F122@oracle.com> <2D2F2B20-0FC7-430F-9C4B-696CCE775B29@oracle.com> Message-ID: On May 6, 2015, at 1:58 PM, Attila Szegedi wrote: > On May 6, 2015, at 12:37 PM, Paul Sandoz wrote: >> >> >> On May 2, 2015, at 11:31 PM, Remi Forax wrote: >> >>> Hi all, >>> today, I stubble on a variant of JDK-8050818 [1], >>> trying to call negate() on a lambda which is not yet a Predicate (due to target typing) which requires either to cast the lambda to a Predicate and everybody knows that cast are evil or to add a local variable. >>> >>> I think there is a way to fix that, it's not very orthodox so I let you judge. >>> The idea is to introduce a static method 'of' on Predicate, >>> class Predicate { >>> ... >>> public static Predicate of(Predicate predicate) { >>> return predicate; >>> } >>> } >>> >>> so one can write: >>> stream.filter(Predicate.of(String::isEmpty).negate()) >>> compared to >>> stream.filter(((Predicate)String::isEmpty).negate()) >>> >>> so the question is, does it it worth the cost to introduce a static method that basically do nothing on all functional interfaces of java.util.function. >>> >> >> That does have the virtue of not adding a static method per operation but i still cannot bring myself to add such methods as a work around for seems like a compiler inference problem (albeit one in which might be very tricky or not possible to solve). > > I think it is firmly in the category of ?very tricky?, but probably still possible, albeit (from my point of view) undesirable. > > String::isEmpty will not, on its own, have a method named .negate(); the compiler can?t really infer the programmer?s intent to make it into a Predicate, not without a fairly high level reasoning (filter needs a Predicate; should the compiler perform an exhaustive search of the visible functional interfaces to see which one has a method with signature ?Predicate negate()??). So, yeah, it seems like in this case the programmer needs to communicate the intent. > > I think inference would be *possible*, but it?d be expensive, and would still allow for either ambiguities or accidentally matching something unexpected, so I think it would also be undesirable. > Ok. > I don?t have an opinion of whether we want an ?of? static method on Predicate, as then it would have to indeed be introduced on many other interfaces. It?s more appealing than a cast, certainly; especially since the cast apparently needs to specify the explicit type parameter too. > I guess it's too late to consider an implicitly declared method along the lines of what Remi suggests. FWIW i always found such methods on enum a little too magical. And perhaps it's too confusing to consider an invocation mode where "this" can be an implicit first parameter. >> >> In some respects i wonder if the default methods on the functional interfaces are an attractive nuisance. > > Meaning, if .negate(Predicate) were a static method on the Predicate class instead of a default method, then stream.filter(Predicate.negate(String::isEmpty)) would be possible? Yeah? > Yeah. We are now in the unfortunate position where to alleviate this problem we might require duplicate static and default methods. I have been sitting on the issue a bit and nearly closed it a few times :-) Paul. From scolebourne at joda.org Wed May 6 14:06:18 2015 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 6 May 2015 15:06:18 +0100 Subject: Add Predicate.of(), Consumer.of(), etc. In-Reply-To: References: <55454241.8030409@univ-mlv.fr> <035D1CE5-592A-4834-AC2E-9FBE0911F122@oracle.com> <2D2F2B20-0FC7-430F-9C4B-696CCE775B29@oracle.com> Message-ID: On 6 May 2015 at 14:53, Paul Sandoz wrote: >>> In some respects i wonder if the default methods on the functional interfaces are an attractive nuisance. >> >> Meaning, if .negate(Predicate) were a static method on the Predicate class instead of a default method, then stream.filter(Predicate.negate(String::isEmpty)) would be possible? Yeah? >> > > Yeah. We are now in the unfortunate position where to alleviate this problem we might require duplicate static and default methods. I have been sitting on the issue a bit and nearly closed it a few times :-) I like Remi's solution. It may not be ideal, but it is very practical and easy to explain on Stack Overflow. Duplicate static/default methods would be much worse. I also think that filterNot should be added to stream. Its just too common a case. Stephen From ivan.gerasimov at oracle.com Wed May 6 14:08:08 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 06 May 2015 17:08:08 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <55486EA5.8000009@oracle.com> References: <55486EA5.8000009@oracle.com> Message-ID: <554A2048.6090202@oracle.com> Hello everyone! Here's the second iteration of the fix. BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/1/webrev/ I changed all the sub-list classes to be non internal, but standalone. I think the logic become more obvious now. ArrayList.SubList was renamed to ArraySubList, so it didn't conflict with SubList from AbstractList.java. The test now uses testng. I didn't come up with a good comment for the SubLists constructors yet. I'll update it a bit later. Comments, suggestions are very welcome. Sincerely yours, Ivan On 05.05.2015 10:17, Ivan Gerasimov wrote: > Hello! > > When creating a sublist with List.subList(), it keeps a reference to > its parent. > Then, when accessing (get(), set(), add(), remove(), etc.) the > sublist, it recursively calls the corresponding methods of its parent. > This recursion, when deep enough, can cause StackOverflowError. > > The only reason to do things recursively here, is the need to update > modCount and size of all the parents. > So, the proposal is to update these fields in a loop. > > A few cleanups were done along the way. > > Would you please help review the fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 > WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/0/webrev/ > > Sincerely yours, > Ivan > > From Roger.Riggs at Oracle.com Wed May 6 14:11:02 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 06 May 2015 10:11:02 -0400 Subject: RFR: JDK-8074002 java.time.ZoneId.systemDefault() should be faster In-Reply-To: <554A0757.2050400@gmail.com> References: <553E5513.7010209@gmail.com> <554A0757.2050400@gmail.com> Message-ID: <554A20F6.2040101@Oracle.com> Hi Peter, Yes, looks good. Roger On 5/6/2015 8:21 AM, Peter Levart wrote: > Any official Reviewers with a couple of cycles to spare? > > Thanks, > > Peter Levart > > > On 04/27/2015 08:24 PM, Stephen Colebourne wrote: >> This seems like a good enhancement. >> Stephen >> >> On 27 April 2015 at 16:26, Peter Levart wrote: >>> Hi, >>> >>> Please review the following improvement that caches default ZoneId >>> object >>> and makes the frequently executed ZoneId.systemDefault() method faster: >>> >>> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneId.systemDefault/webrev.04/ >>> >>> >>> The patch is just a rebased version of webrev.03 + some comments >>> added about >>> the importance of defensive cloning in TimeZone.setDefault(). There was >>> already a discussion about this patch a while ago and Stephen basically >>> approved it in this form: >>> >>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-February/031714.html >>> >>> >>> >>> Thanks, >>> >>> Peter Levart > From ivan.gerasimov at oracle.com Wed May 6 14:17:51 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 06 May 2015 17:17:51 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <1176D029-3948-4091-B7C4-0557FF74AD32@oracle.com> References: <55486EA5.8000009@oracle.com> <8CE7C8C6-B31F-4BEB-AD2B-4E0C62FF39A9@oracle.com> <554905B7.6040605@oracle.com> <55498FD7.7030205@oracle.com> <1176D029-3948-4091-B7C4-0557FF74AD32@oracle.com> Message-ID: <554A228F.9020703@oracle.com> Hi Pavel! It was intentional to avoid checking for co-modification for every pair of list-sublist in the chain. It's surely enough to only compare modCount of the root and the sublist we're dealing with. However, I didn't notice that SubList.size() had not checked for comodifications recursively on its parent. And I agree with you that it's done better now, when modifications of the root list are caught faster. Thanks for noticing it! Sincerely yours, Ivan I noticed that it's not necessary to check the difference in modCount in every subList and its immediate parent pair, On 06.05.2015 12:12, Pavel Rappo wrote: > Ivan, > > It looks like your change (I don't know whether it was intentional or not) > brings some more "fail-fast"-ness which is good! For instance, before the > change, this snippet: > > List integers = new LinkedList<>(); > integers.addAll(Arrays.asList(0, 1)); > > List sublist = integers.subList(0, 2).subList(0, 2); > > System.out.print(sublist.size()); > integers.clear(); > System.out.print(" " + sublist.size()); > > would shamelessly produce: 2 2. But now it throws CME. Which is more expected I > believe. The reason is that now `checkForComodification` consults topmost list > rather than an immediate parent. Well to AbstractList's credit it's not a bug as > it falls into the category described in javadoc of java.util.List.subList: > > * The semantics of the list returned by this method become undefined if > * the backing list (i.e., this list) is structurally modified in > * any way other than via the returned list. (Structural modifications are > * those that change the size of this list, or otherwise perturb it in such > * a fashion that iterations in progress may yield incorrect results.) > > But still, it's a nice bonus for safety. > > -Pavel > > > From Roger.Riggs at Oracle.com Wed May 6 14:43:22 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 06 May 2015 10:43:22 -0400 Subject: RFR: JDK-8079063 ZoneOffsetTransition constructor should ignore nanoseconds In-Reply-To: <55474866.3020506@gmail.com> References: <55474866.3020506@gmail.com> Message-ID: <554A288A.4090305@Oracle.com> Hi Peter, Thanks for the analysis and followup. Yes, I think thesimple check as you propose is the desired clarification. I agree that the change should not affect any existing code outside the JDK and does not raise a compatibility issue. Roger On 5/4/2015 6:22 AM, Peter Levart wrote: > Hi, > > Now that JDK-8074003 is in, I'd like to discuss how to tackle > JDK-8079063. > > Package-private ZoneOffsetTransition constructor that takes > LocalDateTime transition is invoked from the following 4 places: > > 1 - the public static factory method: > > /** > * Obtains an instance defining a transition between two offsets. > *

> * Applications should normally obtain an instance from {@link > ZoneRules}. > * This factory is only intended for use when creating {@link > ZoneRules}. > * > * @param transition the transition date-time at the transition, > which never > * actually occurs, expressed local to the before offset, not null > * @param offsetBefore the offset before the transition, not null > * @param offsetAfter the offset at and after the transition, not > null > * @return the transition, not null > * @throws IllegalArgumentException if {@code offsetBefore} and > {@code offsetAfter} > * are equal, or {@code transition.getNano()} returns > non-zero value > */ > public static ZoneOffsetTransition of(LocalDateTime transition, > ZoneOffset offsetBefore, ZoneOffset offsetAfter) { > > ...this one already disallows transition parameters that have > transition.getNano() != 0. > > > 2 - Lines 498..500 of ZoneOffsetTransitionRule: > > LocalDateTime localDT = LocalDateTime.of(date, time); > LocalDateTime transition = > timeDefinition.createDateTime(localDT, standardOffset, offsetBefore); > return new ZoneOffsetTransition(transition, offsetBefore, > offsetAfter); > > ...where 'time' is an instance field of ZoneOffsetTransitionRule. The > ZoneOffsetTransitionRule public static factory method has the > following definition: > > /** > * Obtains an instance defining the yearly rule to create > transitions between two offsets. > *

> * Applications should normally obtain an instance from {@link > ZoneRules}. > * This factory is only intended for use when creating {@link > ZoneRules}. > * > * @param month the month of the month-day of the first day of > the cutover week, not null > * @param dayOfMonthIndicator the day of the month-day of the > cutover week, positive if the week is that > * day or later, negative if the week is that day or earlier, > counting from the last day of the month, > * from -28 to 31 excluding 0 > * @param dayOfWeek the required day-of-week, null if the > month-day should not be changed > * @param time the cutover time in the 'before' offset, not null > * @param timeEndOfDay whether the time is midnight at the end of > day > * @param timeDefnition how to interpret the cutover > * @param standardOffset the standard offset in force at the > cutover, not null > * @param offsetBefore the offset before the cutover, not null > * @param offsetAfter the offset after the cutover, not null > * @return the rule, not null > * @throws IllegalArgumentException if the day of month indicator > is invalid > * @throws IllegalArgumentException if the end of day flag is true > when the time is not midnight > */ > public static ZoneOffsetTransitionRule of( > Month month, > int dayOfMonthIndicator, > DayOfWeek dayOfWeek, > LocalTime time, > boolean timeEndOfDay, > TimeDefinition timeDefnition, > ZoneOffset standardOffset, > ZoneOffset offsetBefore, > ZoneOffset offsetAfter) { > Objects.requireNonNull(month, "month"); > Objects.requireNonNull(time, "time"); > Objects.requireNonNull(timeDefnition, "timeDefnition"); > Objects.requireNonNull(standardOffset, "standardOffset"); > Objects.requireNonNull(offsetBefore, "offsetBefore"); > Objects.requireNonNull(offsetAfter, "offsetAfter"); > if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || > dayOfMonthIndicator == 0) { > throw new IllegalArgumentException("Day of month indicator > must be between -28 and 31 inclusive excluding zero"); > } > if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == false) { > throw new IllegalArgumentException("Time must be midnight > when end of day flag is true"); > } > return new ZoneOffsetTransitionRule(month, > dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay, timeDefnition, > standardOffset, offsetBefore, offsetAfter); > } > > ...which allows 'time' parameter (that becomes > ZoneOffsetTransitionRule's 'time' field) with no restriction as to > whether it can contain nanos != 0 or not. > > > 3, 4 - Lines 668..678 of ZoneRules private getOffsetInfo method: > > LocalDateTime dtBefore = savingsLocalTransitions[index]; > LocalDateTime dtAfter = savingsLocalTransitions[index + 1]; > ZoneOffset offsetBefore = wallOffsets[index / 2]; > ZoneOffset offsetAfter = wallOffsets[index / 2 + 1]; > if (offsetAfter.getTotalSeconds() > > offsetBefore.getTotalSeconds()) { > // gap > return new ZoneOffsetTransition(dtBefore, > offsetBefore, offsetAfter); > } else { > // overlap > return new ZoneOffsetTransition(dtAfter, offsetBefore, > offsetAfter); > } > > ...where dtBefore/dtAfter "transition" parameters are taken from > savingsLocalTransitions[] array that is filled-in in ZoneRules > constructors from passed-in ZoneOffsetTransition objects. So here no > nanos != 0 can sneak in if ZoneOffsetTransition invariant holds. > > The only place where nanos can sneak-in therefore seems to be the > public ZoneOffsetTransitionRule.of() factory method. The question is > whether the spec. could be changed so that > ZoneOffsetTransitionRule.of() factory method would add another @throws > definition: > > * @throws IllegalArgumentException if {@code time.getNano()} > returns non-zero value > > > This, I think, would be consistent with ZoneOffsetTransition.of() > factory method and I believe early enough in the live of the API so > that no custom software would be affected: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneOffsetTransitionRule.time/webrev.01/ > > > What do you think? > > Regards, Peter > From paul.sandoz at oracle.com Wed May 6 14:47:14 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 6 May 2015 16:47:14 +0200 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554A2048.6090202@oracle.com> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> Message-ID: <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> On May 6, 2015, at 4:08 PM, Ivan Gerasimov wrote: > Hello everyone! > > Here's the second iteration of the fix. > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8079136 > WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/1/webrev/ > This is cleaner. For extra bonus test points you could add singleton-list, checked wrappers, and synchronized list wrappers to the test set. Paul. > I changed all the sub-list classes to be non internal, but standalone. > I think the logic become more obvious now. > > ArrayList.SubList was renamed to ArraySubList, so it didn't conflict with SubList from AbstractList.java. > > The test now uses testng. > > I didn't come up with a good comment for the SubLists constructors yet. I'll update it a bit later. > > Comments, suggestions are very welcome. > > Sincerely yours, > Ivan From daniel.fuchs at oracle.com Wed May 6 15:03:53 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 06 May 2015 17:03:53 +0200 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> Message-ID: <554A2D59.7040703@oracle.com> On 06/05/15 16:47, Paul Sandoz wrote: > n May 6, 2015, at 4:08 PM, Ivan Gerasimov wrote: > >> >Hello everyone! >> > >> >Here's the second iteration of the fix. >> > >> >BUGURL:https://bugs.openjdk.java.net/browse/JDK-8079136 >> >WEBREV:http://cr.openjdk.java.net/~igerasim/8079136/1/webrev/ >> > > This is cleaner. > > For extra bonus test points you could add singleton-list, checked wrappers, and synchronized list wrappers to the test set. > > Paul. > +1 :-) I like this version much better too. -- daniel From scolebourne at joda.org Wed May 6 15:06:04 2015 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 6 May 2015 16:06:04 +0100 Subject: RFR: JDK-8079063 ZoneOffsetTransition constructor should ignore nanoseconds In-Reply-To: <554A288A.4090305@Oracle.com> References: <55474866.3020506@gmail.com> <554A288A.4090305@Oracle.com> Message-ID: I am also happy with this change. Stephen On 6 May 2015 at 15:43, Roger Riggs wrote: > Hi Peter, > > Thanks for the analysis and followup. > > Yes, I think thesimple check as you propose is the desired clarification. > I agree that the change should not affect any existing code outside the JDK > and does not raise a compatibility issue. > > Roger > > > > On 5/4/2015 6:22 AM, Peter Levart wrote: >> >> Hi, >> >> Now that JDK-8074003 is in, I'd like to discuss how to tackle JDK-8079063. >> >> Package-private ZoneOffsetTransition constructor that takes LocalDateTime >> transition is invoked from the following 4 places: >> >> 1 - the public static factory method: >> >> /** >> * Obtains an instance defining a transition between two offsets. >> *

>> * Applications should normally obtain an instance from {@link >> ZoneRules}. >> * This factory is only intended for use when creating {@link >> ZoneRules}. >> * >> * @param transition the transition date-time at the transition, >> which never >> * actually occurs, expressed local to the before offset, not null >> * @param offsetBefore the offset before the transition, not null >> * @param offsetAfter the offset at and after the transition, not >> null >> * @return the transition, not null >> * @throws IllegalArgumentException if {@code offsetBefore} and {@code >> offsetAfter} >> * are equal, or {@code transition.getNano()} returns non-zero >> value >> */ >> public static ZoneOffsetTransition of(LocalDateTime transition, >> ZoneOffset offsetBefore, ZoneOffset offsetAfter) { >> >> ...this one already disallows transition parameters that have >> transition.getNano() != 0. >> >> >> 2 - Lines 498..500 of ZoneOffsetTransitionRule: >> >> LocalDateTime localDT = LocalDateTime.of(date, time); >> LocalDateTime transition = timeDefinition.createDateTime(localDT, >> standardOffset, offsetBefore); >> return new ZoneOffsetTransition(transition, offsetBefore, >> offsetAfter); >> >> ...where 'time' is an instance field of ZoneOffsetTransitionRule. The >> ZoneOffsetTransitionRule public static factory method has the following >> definition: >> >> /** >> * Obtains an instance defining the yearly rule to create transitions >> between two offsets. >> *

>> * Applications should normally obtain an instance from {@link >> ZoneRules}. >> * This factory is only intended for use when creating {@link >> ZoneRules}. >> * >> * @param month the month of the month-day of the first day of the >> cutover week, not null >> * @param dayOfMonthIndicator the day of the month-day of the cutover >> week, positive if the week is that >> * day or later, negative if the week is that day or earlier, >> counting from the last day of the month, >> * from -28 to 31 excluding 0 >> * @param dayOfWeek the required day-of-week, null if the month-day >> should not be changed >> * @param time the cutover time in the 'before' offset, not null >> * @param timeEndOfDay whether the time is midnight at the end of day >> * @param timeDefnition how to interpret the cutover >> * @param standardOffset the standard offset in force at the cutover, >> not null >> * @param offsetBefore the offset before the cutover, not null >> * @param offsetAfter the offset after the cutover, not null >> * @return the rule, not null >> * @throws IllegalArgumentException if the day of month indicator is >> invalid >> * @throws IllegalArgumentException if the end of day flag is true >> when the time is not midnight >> */ >> public static ZoneOffsetTransitionRule of( >> Month month, >> int dayOfMonthIndicator, >> DayOfWeek dayOfWeek, >> LocalTime time, >> boolean timeEndOfDay, >> TimeDefinition timeDefnition, >> ZoneOffset standardOffset, >> ZoneOffset offsetBefore, >> ZoneOffset offsetAfter) { >> Objects.requireNonNull(month, "month"); >> Objects.requireNonNull(time, "time"); >> Objects.requireNonNull(timeDefnition, "timeDefnition"); >> Objects.requireNonNull(standardOffset, "standardOffset"); >> Objects.requireNonNull(offsetBefore, "offsetBefore"); >> Objects.requireNonNull(offsetAfter, "offsetAfter"); >> if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || >> dayOfMonthIndicator == 0) { >> throw new IllegalArgumentException("Day of month indicator >> must be between -28 and 31 inclusive excluding zero"); >> } >> if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == false) { >> throw new IllegalArgumentException("Time must be midnight when >> end of day flag is true"); >> } >> return new ZoneOffsetTransitionRule(month, dayOfMonthIndicator, >> dayOfWeek, time, timeEndOfDay, timeDefnition, standardOffset, offsetBefore, >> offsetAfter); >> } >> >> ...which allows 'time' parameter (that becomes ZoneOffsetTransitionRule's >> 'time' field) with no restriction as to whether it can contain nanos != 0 or >> not. >> >> >> 3, 4 - Lines 668..678 of ZoneRules private getOffsetInfo method: >> >> LocalDateTime dtBefore = savingsLocalTransitions[index]; >> LocalDateTime dtAfter = savingsLocalTransitions[index + 1]; >> ZoneOffset offsetBefore = wallOffsets[index / 2]; >> ZoneOffset offsetAfter = wallOffsets[index / 2 + 1]; >> if (offsetAfter.getTotalSeconds() > >> offsetBefore.getTotalSeconds()) { >> // gap >> return new ZoneOffsetTransition(dtBefore, offsetBefore, >> offsetAfter); >> } else { >> // overlap >> return new ZoneOffsetTransition(dtAfter, offsetBefore, >> offsetAfter); >> } >> >> ...where dtBefore/dtAfter "transition" parameters are taken from >> savingsLocalTransitions[] array that is filled-in in ZoneRules constructors >> from passed-in ZoneOffsetTransition objects. So here no nanos != 0 can sneak >> in if ZoneOffsetTransition invariant holds. >> >> The only place where nanos can sneak-in therefore seems to be the public >> ZoneOffsetTransitionRule.of() factory method. The question is whether the >> spec. could be changed so that ZoneOffsetTransitionRule.of() factory method >> would add another @throws definition: >> >> * @throws IllegalArgumentException if {@code time.getNano()} returns >> non-zero value >> >> >> This, I think, would be consistent with ZoneOffsetTransition.of() factory >> method and I believe early enough in the live of the API so that no custom >> software would be affected: >> >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneOffsetTransitionRule.time/webrev.01/ >> >> What do you think? >> >> Regards, Peter >> > From peter.levart at gmail.com Wed May 6 15:38:45 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 06 May 2015 17:38:45 +0200 Subject: RFR: JDK-8074002 java.time.ZoneId.systemDefault() should be faster In-Reply-To: <554A0CBF.8000207@oracle.com> References: <553E5513.7010209@gmail.com> <554A0CBF.8000207@oracle.com> Message-ID: <554A3585.3030503@gmail.com> On 05/06/2015 04:11 PM, Roger Riggs wrote: > Hi Peter, > > Yes, looks good. > > Roger On 05/06/2015 02:44 PM, Daniel Fuchs wrote: > Hi Peter, > > The logic looks good to me. > But I'm not an expert of the field, despite my small incursions :-) > > I wish we didn't have to do defensive cloning - but I don't see > any way around. > > > best regards, > > -- daniel Hi Roger, Daniel, Stephen, Thanks for reviewing. Defensive cloning is a good thing. In particular here. TimeZone is a mutable object and not thread-safe. So the expectation is that only a single thread accesses a particular object. TimeZone.getDefault() already did cloning, now setDefault() also does the same so that no sharing can occur among threads. Any potential code that called setDefault(tz) and then later changed the ID of passed-in tz object was broken anyway, just waiting for data-race to occur. Regards, Peter > > On 27/04/15 17:26, Peter Levart wrote: >> Hi, >> >> Please review the following improvement that caches default ZoneId >> object and makes the frequently executed ZoneId.systemDefault() method >> faster: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneId.systemDefault/webrev.04/ >> >> >> >> The patch is just a rebased version of webrev.03 + some comments added >> about the importance of defensive cloning in TimeZone.setDefault(). >> There was already a discussion about this patch a while ago and Stephen >> basically approved it in this form: >> >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-February/031714.html >> >> >> >> >> Thanks, >> >> Peter Levart > From peter.levart at gmail.com Wed May 6 15:43:56 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 06 May 2015 17:43:56 +0200 Subject: RFR: JDK-8079063 ZoneOffsetTransition constructor should ignore nanoseconds In-Reply-To: References: <55474866.3020506@gmail.com> <554A288A.4090305@Oracle.com> Message-ID: <554A36BC.40004@gmail.com> Cool! Do we need any CCC approval as this *is* a spec change isn't it? I haven't done such a thing yet, so please give me some pointers. I also intend to add a jtreg test that verifies this new behavior. Regards, Peter On 05/06/2015 05:06 PM, Stephen Colebourne wrote: > I am also happy with this change. > > Stephen > > > On 6 May 2015 at 15:43, Roger Riggs wrote: >> Hi Peter, >> >> Thanks for the analysis and followup. >> >> Yes, I think thesimple check as you propose is the desired clarification. >> I agree that the change should not affect any existing code outside the JDK >> and does not raise a compatibility issue. >> >> Roger >> >> >> >> On 5/4/2015 6:22 AM, Peter Levart wrote: >>> Hi, >>> >>> Now that JDK-8074003 is in, I'd like to discuss how to tackle JDK-8079063. >>> >>> Package-private ZoneOffsetTransition constructor that takes LocalDateTime >>> transition is invoked from the following 4 places: >>> >>> 1 - the public static factory method: >>> >>> /** >>> * Obtains an instance defining a transition between two offsets. >>> *

>>> * Applications should normally obtain an instance from {@link >>> ZoneRules}. >>> * This factory is only intended for use when creating {@link >>> ZoneRules}. >>> * >>> * @param transition the transition date-time at the transition, >>> which never >>> * actually occurs, expressed local to the before offset, not null >>> * @param offsetBefore the offset before the transition, not null >>> * @param offsetAfter the offset at and after the transition, not >>> null >>> * @return the transition, not null >>> * @throws IllegalArgumentException if {@code offsetBefore} and {@code >>> offsetAfter} >>> * are equal, or {@code transition.getNano()} returns non-zero >>> value >>> */ >>> public static ZoneOffsetTransition of(LocalDateTime transition, >>> ZoneOffset offsetBefore, ZoneOffset offsetAfter) { >>> >>> ...this one already disallows transition parameters that have >>> transition.getNano() != 0. >>> >>> >>> 2 - Lines 498..500 of ZoneOffsetTransitionRule: >>> >>> LocalDateTime localDT = LocalDateTime.of(date, time); >>> LocalDateTime transition = timeDefinition.createDateTime(localDT, >>> standardOffset, offsetBefore); >>> return new ZoneOffsetTransition(transition, offsetBefore, >>> offsetAfter); >>> >>> ...where 'time' is an instance field of ZoneOffsetTransitionRule. The >>> ZoneOffsetTransitionRule public static factory method has the following >>> definition: >>> >>> /** >>> * Obtains an instance defining the yearly rule to create transitions >>> between two offsets. >>> *

>>> * Applications should normally obtain an instance from {@link >>> ZoneRules}. >>> * This factory is only intended for use when creating {@link >>> ZoneRules}. >>> * >>> * @param month the month of the month-day of the first day of the >>> cutover week, not null >>> * @param dayOfMonthIndicator the day of the month-day of the cutover >>> week, positive if the week is that >>> * day or later, negative if the week is that day or earlier, >>> counting from the last day of the month, >>> * from -28 to 31 excluding 0 >>> * @param dayOfWeek the required day-of-week, null if the month-day >>> should not be changed >>> * @param time the cutover time in the 'before' offset, not null >>> * @param timeEndOfDay whether the time is midnight at the end of day >>> * @param timeDefnition how to interpret the cutover >>> * @param standardOffset the standard offset in force at the cutover, >>> not null >>> * @param offsetBefore the offset before the cutover, not null >>> * @param offsetAfter the offset after the cutover, not null >>> * @return the rule, not null >>> * @throws IllegalArgumentException if the day of month indicator is >>> invalid >>> * @throws IllegalArgumentException if the end of day flag is true >>> when the time is not midnight >>> */ >>> public static ZoneOffsetTransitionRule of( >>> Month month, >>> int dayOfMonthIndicator, >>> DayOfWeek dayOfWeek, >>> LocalTime time, >>> boolean timeEndOfDay, >>> TimeDefinition timeDefnition, >>> ZoneOffset standardOffset, >>> ZoneOffset offsetBefore, >>> ZoneOffset offsetAfter) { >>> Objects.requireNonNull(month, "month"); >>> Objects.requireNonNull(time, "time"); >>> Objects.requireNonNull(timeDefnition, "timeDefnition"); >>> Objects.requireNonNull(standardOffset, "standardOffset"); >>> Objects.requireNonNull(offsetBefore, "offsetBefore"); >>> Objects.requireNonNull(offsetAfter, "offsetAfter"); >>> if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || >>> dayOfMonthIndicator == 0) { >>> throw new IllegalArgumentException("Day of month indicator >>> must be between -28 and 31 inclusive excluding zero"); >>> } >>> if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == false) { >>> throw new IllegalArgumentException("Time must be midnight when >>> end of day flag is true"); >>> } >>> return new ZoneOffsetTransitionRule(month, dayOfMonthIndicator, >>> dayOfWeek, time, timeEndOfDay, timeDefnition, standardOffset, offsetBefore, >>> offsetAfter); >>> } >>> >>> ...which allows 'time' parameter (that becomes ZoneOffsetTransitionRule's >>> 'time' field) with no restriction as to whether it can contain nanos != 0 or >>> not. >>> >>> >>> 3, 4 - Lines 668..678 of ZoneRules private getOffsetInfo method: >>> >>> LocalDateTime dtBefore = savingsLocalTransitions[index]; >>> LocalDateTime dtAfter = savingsLocalTransitions[index + 1]; >>> ZoneOffset offsetBefore = wallOffsets[index / 2]; >>> ZoneOffset offsetAfter = wallOffsets[index / 2 + 1]; >>> if (offsetAfter.getTotalSeconds() > >>> offsetBefore.getTotalSeconds()) { >>> // gap >>> return new ZoneOffsetTransition(dtBefore, offsetBefore, >>> offsetAfter); >>> } else { >>> // overlap >>> return new ZoneOffsetTransition(dtAfter, offsetBefore, >>> offsetAfter); >>> } >>> >>> ...where dtBefore/dtAfter "transition" parameters are taken from >>> savingsLocalTransitions[] array that is filled-in in ZoneRules constructors >>> from passed-in ZoneOffsetTransition objects. So here no nanos != 0 can sneak >>> in if ZoneOffsetTransition invariant holds. >>> >>> The only place where nanos can sneak-in therefore seems to be the public >>> ZoneOffsetTransitionRule.of() factory method. The question is whether the >>> spec. could be changed so that ZoneOffsetTransitionRule.of() factory method >>> would add another @throws definition: >>> >>> * @throws IllegalArgumentException if {@code time.getNano()} returns >>> non-zero value >>> >>> >>> This, I think, would be consistent with ZoneOffsetTransition.of() factory >>> method and I believe early enough in the live of the API so that no custom >>> software would be affected: >>> >>> >>> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneOffsetTransitionRule.time/webrev.01/ >>> >>> What do you think? >>> >>> Regards, Peter >>> From Roger.Riggs at Oracle.com Wed May 6 15:56:26 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 06 May 2015 11:56:26 -0400 Subject: RFR: JDK-8079063 ZoneOffsetTransition constructor should ignore nanoseconds In-Reply-To: <554A36BC.40004@gmail.com> References: <55474866.3020506@gmail.com> <554A288A.4090305@Oracle.com> <554A36BC.40004@gmail.com> Message-ID: <554A39AA.5000303@Oracle.com> Hi Peter, I'll run the CCC side, mostly it follows the similar rationale and structure as the jira entry. And the details are in your webrev. Thanks, Roger On 5/6/2015 11:43 AM, Peter Levart wrote: > Cool! > > Do we need any CCC approval as this *is* a spec change isn't it? > > I haven't done such a thing yet, so please give me some pointers. I > also intend to add a jtreg test that verifies this new behavior. > > Regards, Peter > > On 05/06/2015 05:06 PM, Stephen Colebourne wrote: >> I am also happy with this change. >> >> Stephen >> >> >> On 6 May 2015 at 15:43, Roger Riggs wrote: >>> Hi Peter, >>> >>> Thanks for the analysis and followup. >>> >>> Yes, I think thesimple check as you propose is the desired >>> clarification. >>> I agree that the change should not affect any existing code outside >>> the JDK >>> and does not raise a compatibility issue. >>> >>> Roger >>> >>> >>> >>> On 5/4/2015 6:22 AM, Peter Levart wrote: >>>> Hi, >>>> >>>> Now that JDK-8074003 is in, I'd like to discuss how to tackle >>>> JDK-8079063. >>>> >>>> Package-private ZoneOffsetTransition constructor that takes >>>> LocalDateTime >>>> transition is invoked from the following 4 places: >>>> >>>> 1 - the public static factory method: >>>> >>>> /** >>>> * Obtains an instance defining a transition between two offsets. >>>> *

>>>> * Applications should normally obtain an instance from {@link >>>> ZoneRules}. >>>> * This factory is only intended for use when creating {@link >>>> ZoneRules}. >>>> * >>>> * @param transition the transition date-time at the transition, >>>> which never >>>> * actually occurs, expressed local to the before offset, not >>>> null >>>> * @param offsetBefore the offset before the transition, not >>>> null >>>> * @param offsetAfter the offset at and after the transition, >>>> not >>>> null >>>> * @return the transition, not null >>>> * @throws IllegalArgumentException if {@code offsetBefore} >>>> and {@code >>>> offsetAfter} >>>> * are equal, or {@code transition.getNano()} returns >>>> non-zero >>>> value >>>> */ >>>> public static ZoneOffsetTransition of(LocalDateTime transition, >>>> ZoneOffset offsetBefore, ZoneOffset offsetAfter) { >>>> >>>> ...this one already disallows transition parameters that have >>>> transition.getNano() != 0. >>>> >>>> >>>> 2 - Lines 498..500 of ZoneOffsetTransitionRule: >>>> >>>> LocalDateTime localDT = LocalDateTime.of(date, time); >>>> LocalDateTime transition = >>>> timeDefinition.createDateTime(localDT, >>>> standardOffset, offsetBefore); >>>> return new ZoneOffsetTransition(transition, offsetBefore, >>>> offsetAfter); >>>> >>>> ...where 'time' is an instance field of ZoneOffsetTransitionRule. The >>>> ZoneOffsetTransitionRule public static factory method has the >>>> following >>>> definition: >>>> >>>> /** >>>> * Obtains an instance defining the yearly rule to create >>>> transitions >>>> between two offsets. >>>> *

>>>> * Applications should normally obtain an instance from {@link >>>> ZoneRules}. >>>> * This factory is only intended for use when creating {@link >>>> ZoneRules}. >>>> * >>>> * @param month the month of the month-day of the first day >>>> of the >>>> cutover week, not null >>>> * @param dayOfMonthIndicator the day of the month-day of the >>>> cutover >>>> week, positive if the week is that >>>> * day or later, negative if the week is that day or earlier, >>>> counting from the last day of the month, >>>> * from -28 to 31 excluding 0 >>>> * @param dayOfWeek the required day-of-week, null if the >>>> month-day >>>> should not be changed >>>> * @param time the cutover time in the 'before' offset, not null >>>> * @param timeEndOfDay whether the time is midnight at the >>>> end of day >>>> * @param timeDefnition how to interpret the cutover >>>> * @param standardOffset the standard offset in force at the >>>> cutover, >>>> not null >>>> * @param offsetBefore the offset before the cutover, not null >>>> * @param offsetAfter the offset after the cutover, not null >>>> * @return the rule, not null >>>> * @throws IllegalArgumentException if the day of month >>>> indicator is >>>> invalid >>>> * @throws IllegalArgumentException if the end of day flag is >>>> true >>>> when the time is not midnight >>>> */ >>>> public static ZoneOffsetTransitionRule of( >>>> Month month, >>>> int dayOfMonthIndicator, >>>> DayOfWeek dayOfWeek, >>>> LocalTime time, >>>> boolean timeEndOfDay, >>>> TimeDefinition timeDefnition, >>>> ZoneOffset standardOffset, >>>> ZoneOffset offsetBefore, >>>> ZoneOffset offsetAfter) { >>>> Objects.requireNonNull(month, "month"); >>>> Objects.requireNonNull(time, "time"); >>>> Objects.requireNonNull(timeDefnition, "timeDefnition"); >>>> Objects.requireNonNull(standardOffset, "standardOffset"); >>>> Objects.requireNonNull(offsetBefore, "offsetBefore"); >>>> Objects.requireNonNull(offsetAfter, "offsetAfter"); >>>> if (dayOfMonthIndicator < -28 || dayOfMonthIndicator > 31 || >>>> dayOfMonthIndicator == 0) { >>>> throw new IllegalArgumentException("Day of month >>>> indicator >>>> must be between -28 and 31 inclusive excluding zero"); >>>> } >>>> if (timeEndOfDay && time.equals(LocalTime.MIDNIGHT) == >>>> false) { >>>> throw new IllegalArgumentException("Time must be >>>> midnight when >>>> end of day flag is true"); >>>> } >>>> return new ZoneOffsetTransitionRule(month, >>>> dayOfMonthIndicator, >>>> dayOfWeek, time, timeEndOfDay, timeDefnition, standardOffset, >>>> offsetBefore, >>>> offsetAfter); >>>> } >>>> >>>> ...which allows 'time' parameter (that becomes >>>> ZoneOffsetTransitionRule's >>>> 'time' field) with no restriction as to whether it can contain >>>> nanos != 0 or >>>> not. >>>> >>>> >>>> 3, 4 - Lines 668..678 of ZoneRules private getOffsetInfo method: >>>> >>>> LocalDateTime dtBefore = savingsLocalTransitions[index]; >>>> LocalDateTime dtAfter = savingsLocalTransitions[index >>>> + 1]; >>>> ZoneOffset offsetBefore = wallOffsets[index / 2]; >>>> ZoneOffset offsetAfter = wallOffsets[index / 2 + 1]; >>>> if (offsetAfter.getTotalSeconds() > >>>> offsetBefore.getTotalSeconds()) { >>>> // gap >>>> return new ZoneOffsetTransition(dtBefore, >>>> offsetBefore, >>>> offsetAfter); >>>> } else { >>>> // overlap >>>> return new ZoneOffsetTransition(dtAfter, >>>> offsetBefore, >>>> offsetAfter); >>>> } >>>> >>>> ...where dtBefore/dtAfter "transition" parameters are taken from >>>> savingsLocalTransitions[] array that is filled-in in ZoneRules >>>> constructors >>>> from passed-in ZoneOffsetTransition objects. So here no nanos != 0 >>>> can sneak >>>> in if ZoneOffsetTransition invariant holds. >>>> >>>> The only place where nanos can sneak-in therefore seems to be the >>>> public >>>> ZoneOffsetTransitionRule.of() factory method. The question is >>>> whether the >>>> spec. could be changed so that ZoneOffsetTransitionRule.of() >>>> factory method >>>> would add another @throws definition: >>>> >>>> * @throws IllegalArgumentException if {@code time.getNano()} >>>> returns >>>> non-zero value >>>> >>>> >>>> This, I think, would be consistent with ZoneOffsetTransition.of() >>>> factory >>>> method and I believe early enough in the live of the API so that no >>>> custom >>>> software would be affected: >>>> >>>> >>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/ZoneOffsetTransitionRule.time/webrev.01/ >>>> >>>> >>>> What do you think? >>>> >>>> Regards, Peter >>>> > From martinrb at google.com Wed May 6 16:19:03 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 6 May 2015 09:19:03 -0700 Subject: RFR 8078645: removeIf(filter) in ConcurrentHashMap removes entries for which filter is false In-Reply-To: References: <55481FA5.1060407@oracle.com> Message-ID: OK, we will merge slightly tidier ConcurrentSkip* sources during the Great jsr166 jdk9 Merge. On Wed, May 6, 2015 at 1:14 AM, Paul Sandoz wrote: > On May 5, 2015, at 7:39 PM, Martin Buchholz wrote: > > I'd prefer to go the other way, deleting those trivial methods entirely, > utilizing the rarely used .new syntax. > > > > Very good, even better! > > Paul. > From mandy.chung at oracle.com Wed May 6 16:55:12 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 06 May 2015 09:55:12 -0700 Subject: RFR(M): 8078896: Add @modules as needed to the jdk_svc tests In-Reply-To: <5549F949.4010300@oracle.com> References: <55488794.3060008@oracle.com> <55492917.6010200@oracle.com> <55492F73.2020806@oracle.com> <5549F949.4010300@oracle.com> Message-ID: <554A4770.2060305@oracle.com> On 05/06/2015 04:21 AM, Yekaterina Kantserova wrote: > The new webrev can be found here: > http://cr.openjdk.java.net/~ykantser/8078896/webrev.02/ > Looks good. >> >> About the test selection, one typical aspect of svc tests is to run a >> j* tool in a child process (e.g. jinfo, jstack, jstat, jstatd,jcmd, >> jps etc that are in jdk.jcmd module). I would expect all >> test/sun/tools/jcmd tests should have @modules jdk.jcmd and similiar >> for other sun/tools/j* tests. Are you thinking to come back in the >> next round of test selection update? > > As Alan pointed in his answer to this mail JTreg is not ready yet. I > prefer to do it when it will be possible to test this change. Right the test selection is yet to be supported by jtreg and it's okay to add those in the next round. As the tool analyzing the test dependencies doesn't detect that, these multi-process tests would need to be analyzed in a different way. Anyway, this patch looks good. Mandy From peter.levart at gmail.com Wed May 6 17:13:15 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 06 May 2015 19:13:15 +0200 Subject: RFR: JDK-8066859 java/lang/ref/OOMEInReferenceHandler.java failed with java.lang.Exception: Reference Handler thread died Message-ID: <554A4BAB.4000004@gmail.com> Hi, I might have a closure for this long beard issue [1] and I'd like to propose a change [2]. It all started with [3] discussed here [4] which resulted in the fix for one source of OutOfMemoryError(s) terminating ReferenceHandler thread. With this fix, new test was added which started failing intermittently indicating there is another source of OutOfMemoryError(s) being thrown in ReferenceHandler. At that time, the investigation [6] indicated that the source is "r instanceof Cleaner" check and so another change was pushed [5]. The issue JDK-8022321 is internal - I don't have a link. That change was 2-fold: it added code to preload and pre-initialize Cleaner and InterruptedException classes in ReferenceHandler. and, cowardly, surrounded "r instanceof Cleaner" check with OOME exception handler. I'm pretty certain that pre-loading of the classes would have been enough. At least it would have not sprung the confusion expressed here [7]. But even that was not enough to prevent intermittent failures. I realized that the test I devised still fails because of Cleaner.clean() throwing OOME. Why this is possible is discussed in the issue [1]. I even modified the test to reproduce such failure with 100% chance. So here I propose two things in [2] : - roll-back of the confusing "r instanceof Cleaner" OOME exception handling to the shape of code predating change [5]. - add handling of OOME in the Cleaner.clean() with updated test that checks the behaviour. Regards, Peter [1] https://bugs.openjdk.java.net/browse/JDK-8066859 [2] http://cr.openjdk.java.net/~plevart/jdk9-dev/OOMEInReferenceHandler/Investigation/webrev.04/ [3] https://bugs.openjdk.java.net/browse/JDK-8015434 [4] http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-April/016510.html [5] http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d04102f69d46 [6] https://www.mail-archive.com/core-libs-dev%40openjdk.java.net/msg23596.html [7] https://bugs.openjdk.java.net/browse/JDK-8055232 From ivan.gerasimov at oracle.com Wed May 6 20:25:31 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 06 May 2015 23:25:31 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> Message-ID: <554A78BB.3090501@oracle.com> And here's another update: WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/2/webrev/ > This is cleaner. > > For extra bonus test points you could add singleton-list, checked wrappers, and synchronized list wrappers to the test set. Done. I also added a simple implementation of AbstractList, just to earn a few more points :) I found it much easier to create two separate constructors of SubList, as you Paul had suggested, then to explain how the only universal constructor works. So, in this update each SubList class has a pair of constructors for different purposes. Sincerely yours, Ivan From joe.darcy at oracle.com Wed May 6 22:19:35 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Wed, 06 May 2015 15:19:35 -0700 Subject: JDK 9 RFR of Update to RegEx test to use random number library In-Reply-To: <5549434B.1090003@oracle.com> References: <55493BDB.9090102@oracle.com> <5549434B.1090003@oracle.com> Message-ID: <554A9377.5030004@oracle.com> PS Shortly after I pushed this fix I thought, "it would have been better to add the intermittent keyword to the test too." Please review this change to add the keyword: diff -r a199b72a5b37 test/java/util/regex/RegExTest.java --- a/test/java/util/regex/RegExTest.java Wed May 06 21:15:07 2015 +0400 +++ b/test/java/util/regex/RegExTest.java Wed May 06 15:18:59 2015 -0700 @@ -36,7 +36,7 @@ * @library /lib/testlibrary * @build jdk.testlibrary.* * @run main RegExTest - * @key randomness + * @key intermittent randomness */ import java.util.function.Function; Thanks, -Joe On 5/5/2015 3:25 PM, Xueming Shen wrote: > looks fine. > > On 5/5/15 2:53 PM, Joseph D. Darcy wrote: >> Hello, >> >> The regression test >> >> test/java/util/regex/RegExTest.java >> >> has been observed to intermittently fail. As the test uses >> randomness, I'd like to update to the test to use the random number >> testing library to better identify the cause of any future failures. >> >> Please review the patch below: >> >> diff -r 207c1b0356ea test/java/util/regex/RegExTest.java >> --- a/test/java/util/regex/RegExTest.java Tue May 05 17:55:16 2015 >> +0100 >> +++ b/test/java/util/regex/RegExTest.java Tue May 05 14:50:10 2015 >> -0700 >> @@ -23,7 +23,7 @@ >> >> /** >> * @test >> - * @summary tests RegExp framework >> + * @summary tests RegExp framework (use -Dseed=X to set PRNG seed) >> * @author Mike McCloskey >> * @bug 4481568 4482696 4495089 4504687 4527731 4599621 4631553 4619345 >> * 4630911 4672616 4711773 4727935 4750573 4792284 4803197 4757029 >> 4808962 >> @@ -33,6 +33,9 @@ >> * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 >> 7039066 >> * 7067045 7014640 7189363 8007395 8013252 8013254 8012646 8023647 >> 6559590 >> * 8027645 8035076 8039124 8035975 8074678 >> + * @library /lib/testlibrary >> + * @build jdk.testlibrary.* >> + * @run main RegExTest >> * @key randomness >> */ >> >> @@ -50,7 +53,7 @@ >> */ >> public class RegExTest { >> >> - private static Random generator = new Random(); >> + private static Random generator = RandomFactory.getRandom(); >> private static boolean failure = false; >> private static int failCount = 0; >> private static String firstFailure = null; >> >> Thanks, >> >> -Joe > From xueming.shen at oracle.com Wed May 6 22:41:54 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 06 May 2015 15:41:54 -0700 Subject: JDK 9 RFR of Update to RegEx test to use random number library In-Reply-To: <554A9377.5030004@oracle.com> References: <55493BDB.9090102@oracle.com> <5549434B.1090003@oracle.com> <554A9377.5030004@oracle.com> Message-ID: <554A98B2.2060809@oracle.com> Looks fine. On 05/06/2015 03:19 PM, Joseph D. Darcy wrote: > PS Shortly after I pushed this fix I thought, "it would have been better to add the intermittent keyword to the test too." Please review this change to add the keyword: > > diff -r a199b72a5b37 test/java/util/regex/RegExTest.java > --- a/test/java/util/regex/RegExTest.java Wed May 06 21:15:07 2015 +0400 > +++ b/test/java/util/regex/RegExTest.java Wed May 06 15:18:59 2015 -0700 > @@ -36,7 +36,7 @@ > * @library /lib/testlibrary > * @build jdk.testlibrary.* > * @run main RegExTest > - * @key randomness > + * @key intermittent randomness > */ > > import java.util.function.Function; > > Thanks, > > -Joe > > On 5/5/2015 3:25 PM, Xueming Shen wrote: >> looks fine. >> >> On 5/5/15 2:53 PM, Joseph D. Darcy wrote: >>> Hello, >>> >>> The regression test >>> >>> test/java/util/regex/RegExTest.java >>> >>> has been observed to intermittently fail. As the test uses randomness, I'd like to update to the test to use the random number testing library to better identify the cause of any future failures. >>> >>> Please review the patch below: >>> >>> diff -r 207c1b0356ea test/java/util/regex/RegExTest.java >>> --- a/test/java/util/regex/RegExTest.java Tue May 05 17:55:16 2015 +0100 >>> +++ b/test/java/util/regex/RegExTest.java Tue May 05 14:50:10 2015 -0700 >>> @@ -23,7 +23,7 @@ >>> >>> /** >>> * @test >>> - * @summary tests RegExp framework >>> + * @summary tests RegExp framework (use -Dseed=X to set PRNG seed) >>> * @author Mike McCloskey >>> * @bug 4481568 4482696 4495089 4504687 4527731 4599621 4631553 4619345 >>> * 4630911 4672616 4711773 4727935 4750573 4792284 4803197 4757029 4808962 >>> @@ -33,6 +33,9 @@ >>> * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066 >>> * 7067045 7014640 7189363 8007395 8013252 8013254 8012646 8023647 6559590 >>> * 8027645 8035076 8039124 8035975 8074678 >>> + * @library /lib/testlibrary >>> + * @build jdk.testlibrary.* >>> + * @run main RegExTest >>> * @key randomness >>> */ >>> >>> @@ -50,7 +53,7 @@ >>> */ >>> public class RegExTest { >>> >>> - private static Random generator = new Random(); >>> + private static Random generator = RandomFactory.getRandom(); >>> private static boolean failure = false; >>> private static int failCount = 0; >>> private static String firstFailure = null; >>> >>> Thanks, >>> >>> -Joe >> > From martinrb at google.com Wed May 6 23:23:43 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 6 May 2015 16:23:43 -0700 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554A78BB.3090501@oracle.com> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> Message-ID: Hi Ivan, I'm afraid of these changes - they are hard to review. Can't we fix the SOE with a relatively small change to ArrayList.SubList methods that recursively invoke parent methods to use iteration instead, i.e. can't you implement updateSizeAndModCount in the existing SubList class? --- I would make modCount an argument to updateSizeAndModCount. --- Separate out hot and cold code in subListRangeCheck (although pre-existing code had the same problem) + static void subListRangeCheck(int fromIndex, int toIndex, int size) { + if (fromIndex < 0) + throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); + if (toIndex > size) + throw new IndexOutOfBoundsException("toIndex = " + toIndex); + if (fromIndex > toIndex) + throw new IllegalArgumentException("fromIndex(" + fromIndex + + ") > toIndex(" + toIndex + ")"); + } + if ((fromIndex < 0) | (toIndex > size) | (fromIndex > toIndex)) slowpath(); --- java style consensus has been converging on: java source files should have exactly one top-level class. It seems like you changed inner class SubList to be a top-level class - why? +class ArraySubList extends AbstractList implements RandomAccess { On Wed, May 6, 2015 at 1:25 PM, Ivan Gerasimov wrote: > And here's another update: > > WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/2/webrev/ > From peter.levart at gmail.com Thu May 7 05:53:38 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 07 May 2015 07:53:38 +0200 Subject: RFR: JDK-8066859 java/lang/ref/OOMEInReferenceHandler.java failed with java.lang.Exception: Reference Handler thread died In-Reply-To: <554A4BAB.4000004@gmail.com> References: <554A4BAB.4000004@gmail.com> Message-ID: <554AFDE2.9040400@gmail.com> This is better (fixed a data race in Cleaner.clean()): http://cr.openjdk.java.net/~plevart/jdk9-dev/OOMEInReferenceHandler/Investigation/webrev.05/ Regards, Peter On 05/06/2015 07:13 PM, Peter Levart wrote: > Hi, > > I might have a closure for this long beard issue [1] and I'd like to > propose a change [2]. > > It all started with [3] discussed here [4] which resulted in the fix > for one source of OutOfMemoryError(s) terminating ReferenceHandler > thread. With this fix, new test was added which started failing > intermittently indicating there is another source of > OutOfMemoryError(s) being thrown in ReferenceHandler. At that time, > the investigation [6] indicated that the source is "r instanceof > Cleaner" check and so another change was pushed [5]. The issue > JDK-8022321 is internal - I don't have a link. That change was 2-fold: > it added code to preload and pre-initialize Cleaner and > InterruptedException classes in ReferenceHandler. and, > cowardly, surrounded "r instanceof Cleaner" check with OOME exception > handler. I'm pretty certain that pre-loading of the classes would have > been enough. At least it would have not sprung the confusion expressed > here [7]. > But even that was not enough to prevent intermittent failures. I > realized that the test I devised still fails because of > Cleaner.clean() throwing OOME. Why this is possible is discussed in > the issue [1]. I even modified the test to reproduce such failure with > 100% chance. > > So here I propose two things in [2] : > - roll-back of the confusing "r instanceof Cleaner" OOME exception > handling to the shape of code predating change [5]. > - add handling of OOME in the Cleaner.clean() with updated test that > checks the behaviour. > > Regards, Peter > > > [1] https://bugs.openjdk.java.net/browse/JDK-8066859 > [2] > http://cr.openjdk.java.net/~plevart/jdk9-dev/OOMEInReferenceHandler/Investigation/webrev.04/ > [3] https://bugs.openjdk.java.net/browse/JDK-8015434 > [4] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-April/016510.html > [5] http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d04102f69d46 > [6] > https://www.mail-archive.com/core-libs-dev%40openjdk.java.net/msg23596.html > [7] https://bugs.openjdk.java.net/browse/JDK-8055232 > From bourges.laurent at gmail.com Thu May 7 07:06:41 2015 From: bourges.laurent at gmail.com (=?ISO-8859-1?Q?Laurent_Bourg=E8s?=) Date: Thu, 7 May 2015 09:06:41 +0200 Subject: RFR: JDK-8066859 java/lang/ref/OOMEInReferenceHandler.java failed with java.lang.Exception: Reference Handler thread died In-Reply-To: <554AFDE2.9040400@gmail.com> References: <554A4BAB.4000004@gmail.com> <554AFDE2.9040400@gmail.com> Message-ID: Peter, I looked at Cleaner by curiosity and it seems to be not catching the oome from thunk.run ! If oome1 is thrown by thunk.run at line 150 then it is catched at line 157 but your new try/catch block (oome2) only encapsulates the doPriviledge block. If this block also throws a new oome2 due to the first oome1 (no memory left), it will work but I would have prefered a more explicit solution and check oome1 first ... My 2 cents (I am not a reviewer). Laurent From paul.sandoz at oracle.com Thu May 7 07:35:45 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 7 May 2015 09:35:45 +0200 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> Message-ID: On May 7, 2015, at 1:23 AM, Martin Buchholz wrote: > Hi Ivan, > > I'm afraid of these changes - they are hard to review. > > Can't we fix the SOE with a relatively small change to ArrayList.SubList methods that recursively invoke parent methods to use iteration instead, Since all that would do is eventually modify the underlying list, one might as well go to it directly when one can. I am ok with this changes as long as we have good tests and coverage. > i.e. can't you implement updateSizeAndModCount in the existing SubList class? > > --- > > I would make modCount an argument to updateSizeAndModCount. > That would just repeat the same root mod-count accessor for all calls to updateSizeAndModCount (with such repetition it's easier to introduce inconsistencies). > --- > > Separate out hot and cold code in subListRangeCheck (although pre-existing code had the same problem) > > + static void subListRangeCheck(int fromIndex, int toIndex, int size) { > + if (fromIndex < 0) > + throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); > + if (toIndex > size) > + throw new IndexOutOfBoundsException("toIndex = " + toIndex); > + if (fromIndex > toIndex) > + throw new IllegalArgumentException("fromIndex(" + fromIndex + > + ") > toIndex(" + toIndex + ")"); > + } > + > > if ((fromIndex < 0) | (toIndex > size) | (fromIndex > toIndex)) slowpath(); > > --- > java style consensus has been converging on: java source files should have exactly one top-level class. It seems like you changed inner class SubList to be a top-level class - why? > > +class ArraySubList extends AbstractList implements RandomAccess { > I would usually opt for inner classes too, sometimes there is a good reason not to. I think for the sub-list of AbstractList it is easier to understand when it is not nested due to the confusion over what is the enclosing instance. For the sub-list of ArrayList there we could and probably should stick to usual the convention. Paul. From peter.levart at gmail.com Thu May 7 10:25:21 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 07 May 2015 12:25:21 +0200 Subject: RFR: JDK-8066859 java/lang/ref/OOMEInReferenceHandler.java failed with java.lang.Exception: Reference Handler thread died In-Reply-To: References: <554A4BAB.4000004@gmail.com> <554AFDE2.9040400@gmail.com> Message-ID: <554B3D91.5010802@gmail.com> On 05/07/2015 09:06 AM, Laurent Bourg?s wrote: > > Peter, > > I looked at Cleaner by curiosity and it seems to be not catching the > oome from thunk.run ! > > If oome1 is thrown by thunk.run at line 150 then it is catched at line > 157 but your new try/catch block (oome2) only encapsulates the > doPriviledge block. > > If this block also throws a new oome2 due to the first oome1 (no > memory left), it will work but I would have prefered a more explicit > solution and check oome1 first ... > > My 2 cents (I am not a reviewer). > > Laurent > Laurent, You have a point and I asked myself the same question. The question is how to treat OOME thrown from thunk.run(). Current behavior is to exit() JVM for any exception (Throwable). I maintained that semantics. I only added a handler for OOME thrown in the handler of the 1st exception. I might have just exit()-ed the VM if OOME is thrown, but leaving no trace and just exiting VM would not help anyone diagnose what went wrong. So I opted for keeping the VM running for a while by delaying the handling of 1st exception to "better times". If better times never come, then the application is probably stuck anyway. An alternative would be to catch OOME from thunk.run() and ignore it (printing it out would be ugly if VM is left to run), but that would silently ignore OOMEs thrown from thunk.run() and noone would notice that Cleaner(s) might not have clean-ed up the resources they should. The complete fix would be to inspect the code paths of all Cleaner.thunk's run() methods and see if and where they can throw exceptions (OOMEs in particular) and whether they can be prevented. I did that and found myself wandering deeply in the hotspot code that I don't understand completely. Cleaner's are used in the following places: - in java.lang.invoke.CallSite, to invalidate the dependent nmethods when the context class is GC-ed - that one was added recently. Intermittent failures of the test predate it's addition, so I would not suspect this one immediately. - in sun.misc.Perf, to detach the memory of a native ByteBuffer obtained from Perf.attach() when the ByteBuffer is GC-ed. The Java code-path does not have any allocations and the native code that does detaching is in hotspot/src/share/vm/prims/perf.cpp: static JNINativeMethod perfmethods[] = { ... {CC"detach", CC"("BB")V", FN_PTR(Perf_Detach)},So c ... PERF_ENTRY(void, Perf_Detach(JNIEnv *env, jobject unused, jobject buffer)) PerfWrapper("Perf_Detach"); if (!UsePerfData) { // With -XX:-UsePerfData, detach is just a NOP return; } void* address = 0; jlong capacity = 0; // get buffer address and capacity { ThreadToNativeFromVM ttnfv(thread); address = env->GetDirectBufferAddress(buffer); capacity = env->GetDirectBufferCapacity(buffer); } PerfMemory::detach((char*)address, capacity, CHECK); PERF_END - in sun.nio.ch.IOVecWrapper, to deallocate native memory associated with the wrapper when it is GC-ed. The Java code-path does not perform any allocations and finally just calls native Unsafe.freeMemory(allocationAddress) where allocationAddress was obtained from Unsafe.allocateMemory(size). The native code for Unsafe.freeMemory is in hotspot/src/share/vm/prims/unsafe.cpp: static JNINativeMethod methods[] = { ... {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, ... UNSAFE_ENTRY(void, Unsafe_FreeMemory(JNIEnv *env, jobject unsafe, jlong addr)) UnsafeWrapper("Unsafe_FreeMemory"); void* p = addr_from_java(addr); if (p == NULL) { return; } os::free(p); UNSAFE_END - in sun.nio.fs.NativeBuffer, to deallocate native memory allocated for NativeBuffer by Unsafe.allocateMemory(size) with exactly the same Cleaner.thunk (Deallocator) as used in sun.nio.ch.IOVecWrapper. Can anyone confirm whether the above two native methods can throw any exception or not? Anyway. If none of the Cleaner.thunk's run() methods can throw any exception, then my handling of OOME is redundant and a code-path never taken. But I would still leave it there in case some new Cleaner use comes along which is not verified yet... Regards, Peter From peter.levart at gmail.com Thu May 7 10:57:08 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 07 May 2015 12:57:08 +0200 Subject: RFR: JDK-8066859 java/lang/ref/OOMEInReferenceHandler.java failed with java.lang.Exception: Reference Handler thread died In-Reply-To: <554B3D91.5010802@gmail.com> References: <554A4BAB.4000004@gmail.com> <554AFDE2.9040400@gmail.com> <554B3D91.5010802@gmail.com> Message-ID: <554B4504.1020709@gmail.com> Hi, I see the intermittent failures have already been fixed (I haven't noticed this before) in this issue: https://bugs.openjdk.java.net/browse/JDK-8067751 The fix was simply adding: "-XX:-UseGCOverheadLimit" option to the VM options. So my conclusion that the remaining intermittent test failures stem from Cleaner.clean() throwing OOME were right. It's just that the cause of OOME seems to be the "GC overhead limit exceeded". I always thought that a thread can only get OOME when it tries to allocate something. Now the above issue indicates that OOME can be thrown in a thread at any time. Is my understanding correct? How and when is a thread chosen then for this type of OOME? Regards, Peter On 05/07/2015 12:25 PM, Peter Levart wrote: > > > On 05/07/2015 09:06 AM, Laurent Bourg?s wrote: >> >> Peter, >> >> I looked at Cleaner by curiosity and it seems to be not catching the >> oome from thunk.run ! >> >> If oome1 is thrown by thunk.run at line 150 then it is catched at >> line 157 but your new try/catch block (oome2) only encapsulates the >> doPriviledge block. >> >> If this block also throws a new oome2 due to the first oome1 (no >> memory left), it will work but I would have prefered a more explicit >> solution and check oome1 first ... >> >> My 2 cents (I am not a reviewer). >> >> Laurent >> > > Laurent, > > You have a point and I asked myself the same question. The question is > how to treat OOME thrown from thunk.run(). Current behavior is to > exit() JVM for any exception (Throwable). I maintained that semantics. > I only added a handler for OOME thrown in the handler of the 1st > exception. I might have just exit()-ed the VM if OOME is thrown, but > leaving no trace and just exiting VM would not help anyone diagnose > what went wrong. So I opted for keeping the VM running for a while by > delaying the handling of 1st exception to "better times". If better > times never come, then the application is probably stuck anyway. > > An alternative would be to catch OOME from thunk.run() and ignore it > (printing it out would be ugly if VM is left to run), but that would > silently ignore OOMEs thrown from thunk.run() and noone would notice > that Cleaner(s) might not have clean-ed up the resources they should. > > The complete fix would be to inspect the code paths of all > Cleaner.thunk's run() methods and see if and where they can throw > exceptions (OOMEs in particular) and whether they can be prevented. I > did that and found myself wandering deeply in the hotspot code that I > don't understand completely. Cleaner's are used in the following places: > > - in java.lang.invoke.CallSite, to invalidate the dependent nmethods > when the context class is GC-ed - that one was added recently. > Intermittent failures of the test predate it's addition, so I would > not suspect this one immediately. > > - in sun.misc.Perf, to detach the memory of a native ByteBuffer > obtained from Perf.attach() when the ByteBuffer is GC-ed. The Java > code-path does not have any allocations and the native code that does > detaching is in hotspot/src/share/vm/prims/perf.cpp: > > static JNINativeMethod perfmethods[] = { > ... > {CC"detach", CC"("BB")V", FN_PTR(Perf_Detach)},So c > ... > > PERF_ENTRY(void, Perf_Detach(JNIEnv *env, jobject unused, jobject > buffer)) > > PerfWrapper("Perf_Detach"); > > if (!UsePerfData) { > // With -XX:-UsePerfData, detach is just a NOP > return; > } > > void* address = 0; > jlong capacity = 0; > > // get buffer address and capacity > { > ThreadToNativeFromVM ttnfv(thread); > address = env->GetDirectBufferAddress(buffer); > capacity = env->GetDirectBufferCapacity(buffer); > } > > PerfMemory::detach((char*)address, capacity, CHECK); > > PERF_END > > - in sun.nio.ch.IOVecWrapper, to deallocate native memory associated > with the wrapper when it is GC-ed. The Java code-path does not perform > any allocations and finally just calls native > Unsafe.freeMemory(allocationAddress) where allocationAddress was > obtained from Unsafe.allocateMemory(size). The native code for > Unsafe.freeMemory is in hotspot/src/share/vm/prims/unsafe.cpp: > > static JNINativeMethod methods[] = { > ... > {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, > ... > > UNSAFE_ENTRY(void, Unsafe_FreeMemory(JNIEnv *env, jobject unsafe, > jlong addr)) > UnsafeWrapper("Unsafe_FreeMemory"); > void* p = addr_from_java(addr); > if (p == NULL) { > return; > } > os::free(p); > UNSAFE_END > > - in sun.nio.fs.NativeBuffer, to deallocate native memory allocated > for NativeBuffer by Unsafe.allocateMemory(size) with exactly the same > Cleaner.thunk (Deallocator) as used in sun.nio.ch.IOVecWrapper. > > Can anyone confirm whether the above two native methods can throw any > exception or not? > > Anyway. If none of the Cleaner.thunk's run() methods can throw any > exception, then my handling of OOME is redundant and a code-path never > taken. But I would still leave it there in case some new Cleaner use > comes along which is not verified yet... > > Regards, Peter > From vladimir.x.ivanov at oracle.com Thu May 7 11:28:49 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Thu, 07 May 2015 14:28:49 +0300 Subject: RFR: JDK-8066859 java/lang/ref/OOMEInReferenceHandler.java failed with java.lang.Exception: Reference Handler thread died In-Reply-To: <554B3D91.5010802@gmail.com> References: <554A4BAB.4000004@gmail.com> <554AFDE2.9040400@gmail.com> <554B3D91.5010802@gmail.com> Message-ID: <554B4C71.5060608@oracle.com> Peter, > - in java.lang.invoke.CallSite, to invalidate the dependent nmethods > when the context class is GC-ed - that one was added recently. > Intermittent failures of the test predate it's addition, so I would not > suspect this one immediately. FYI it's a known problem (JDK-8079205 [1]). The CallSite context logic is broken after sun.misc.Cleaner was made automatically clearable. Best regards, Vladimir Ivanov [1] https://bugs.openjdk.java.net/browse/JDK-8079205 From chris.hegarty at oracle.com Thu May 7 14:10:11 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 7 May 2015 15:10:11 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <55489355.9010601@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> Message-ID: <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> Thanks for the comments. All have been considered and incorporated ( where applicable ). I sketched out a readAllBytes, added some basic tests, and moved this into a webrev. I have not created a specdiff, as the changes simply add two new methods, that are easily readable. I think this version, less review comments, covers the most common use-cases. http://cr.openjdk.java.net/~chegar/readBytes/webrev.00/ -Chris. On 5 May 2015, at 10:54, Alan Bateman wrote: > On 02/05/2015 09:27, Chris Hegarty wrote: >> : >> Thanks, this was an editing issue. Removed. > I think the javadoc looks quite good now, except may be the first statement "Reads some bytes ...". It might be clearer to start with "Reads a given number of bytes ...". The subsequent text makes the short read case and the return value clear. > >> >> As Alan has commented, another readAllBytes() returning a byte[] maybe useful too ( but a different use case ). Let?s park this momentarily, while I sketch up the readAllBytes variant, so we can ensure that the typical use cases have been addressed. Doing so may feedback into the spec of this method. I?ll push this latest draft into the sandbox so it is not lost. > Yes, a separate use-case but once that I would expect to be common. > > -Alan. > From Roger.Riggs at Oracle.com Thu May 7 14:11:48 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 07 May 2015 10:11:48 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <5530BECF.60903@gmail.com> References: <5526DA4A.6030808@Oracle.com> <55296E19.3040204@Oracle.com> <5530BECF.60903@gmail.com> Message-ID: <554B72A4.5050705@Oracle.com> fyi, with respect to using the start time to uniquely identify a process. It turns out that on Linux[1] looking at st_mtime from stat(/proc/pid/status) doesn't always produce the same value (and the inode number can change). When spawning large number of processes (< 500) it appears the pseudo inode entries are not kept around and are re-initialized. In a brief peek at the Linux code in fs/proc/inode.c it appears always to initialize st_mtime/st_atime/st_ctime from the current time. It seems a slightly more expensive read and parse of the file will be needed to get and check the start time. fyi, Roger [1] Ubuntu 14.04. (Linux-3.13.0) sources On 4/17/2015 4:05 AM, Peter Levart wrote: > > At least on Linux (/proc//stat) and Solaris (/proc//status) > it is not necessary to open those special files and read them. Just > doing stat() on them and using the st_mtime will get you the process > start time. I see AIX shares native code with Linux (unix), so perhaps > AIX does the same. Mac OSX and Windows have special calls... From Roger.Riggs at Oracle.com Thu May 7 14:20:47 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 07 May 2015 10:20:47 -0400 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> Message-ID: <554B74BF.4020104@Oracle.com> Hi Chris, Is it really impossible to specify at least that closing the stream will terminate the read? A thread that is blocking on some I/O needs to have some way to interrupt it. Terminating the VM because a read is stuck or to leave the thread around indefinately is too severe. + *

The behavior for the case where the input stream is asynchronously + * closed, or the thread interrupted during the read, is highly input + * stream specific, and therefore not specified. + * Roger On 5/7/2015 10:10 AM, Chris Hegarty wrote: > Thanks for the comments. All have been considered and incorporated ( where applicable ). > > I sketched out a readAllBytes, added some basic tests, and moved this into a webrev. I have not created a specdiff, as the changes simply add two new methods, that are easily readable. > > I think this version, less review comments, covers the most common use-cases. > > http://cr.openjdk.java.net/~chegar/readBytes/webrev.00/ > > -Chris. > > On 5 May 2015, at 10:54, Alan Bateman wrote: > >> On 02/05/2015 09:27, Chris Hegarty wrote: >>> : >>> Thanks, this was an editing issue. Removed. >> I think the javadoc looks quite good now, except may be the first statement "Reads some bytes ...". It might be clearer to start with "Reads a given number of bytes ...". The subsequent text makes the short read case and the return value clear. >> >>> As Alan has commented, another readAllBytes() returning a byte[] maybe useful too ( but a different use case ). Let?s park this momentarily, while I sketch up the readAllBytes variant, so we can ensure that the typical use cases have been addressed. Doing so may feedback into the spec of this method. I?ll push this latest draft into the sandbox so it is not lost. >> Yes, a separate use-case but once that I would expect to be common. >> >> -Alan. >> From Alan.Bateman at oracle.com Thu May 7 14:29:07 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 07 May 2015 15:29:07 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <554B74BF.4020104@Oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> <554B74BF.4020104@Oracle.com> Message-ID: <554B76B3.5080905@oracle.com> On 07/05/2015 15:20, Roger Riggs wrote: > Hi Chris, > > Is it really impossible to specify at least that closing the stream > will terminate the read? The wording that Chris has is wording that we use elsewhere too. In general then the InputStream could be to anything and no guarantee that all InputStream implementations could preempt the read. -Alan. From Roger.Riggs at Oracle.com Thu May 7 14:36:37 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 07 May 2015 10:36:37 -0400 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <554B76B3.5080905@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> <554B74BF.4020104@Oracle.com> <554B76B3.5080905@oracle.com> Message-ID: <554B7875.9050105@Oracle.com> Hi Alan, I recognize that this utility function can't compensate for failings of the underlying stream. But I thought async close was the one common action that did work on streams to avoid indefinite blocking. It would be more appropriate to say that the behavior depends on the underlying stream and not propagate the under specification. Roger On 5/7/2015 10:29 AM, Alan Bateman wrote: > > On 07/05/2015 15:20, Roger Riggs wrote: >> Hi Chris, >> >> Is it really impossible to specify at least that closing the stream >> will terminate the read? > The wording that Chris has is wording that we use elsewhere too. In > general then the InputStream could be to anything and no guarantee > that all InputStream implementations could preempt the read. > > -Alan. From Alan.Bateman at oracle.com Thu May 7 14:46:10 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 07 May 2015 15:46:10 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <554B7875.9050105@Oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> <554B74BF.4020104@Oracle.com> <554B76B3.5080905@oracle.com> <554B7875.9050105@Oracle.com> Message-ID: <554B7AB2.9080000@oracle.com> On 07/05/2015 15:36, Roger Riggs wrote: > Hi Alan, > > I recognize that this utility function can't compensate for failings > of the underlying > stream. But I thought async close was the one common action that did > work on streams > to avoid indefinite blocking. No, not generally for InputStreams so it's very possible that the close might block until the read completes. -Alan From Ulf.Zibis at CoSoCo.de Thu May 7 15:00:59 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Thu, 07 May 2015 17:00:59 +0200 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <55490240.1080206@oracle.com> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> <5543B58F.6020105@Oracle.com> <55487FE9.5010606@oracle.com> <5548C6C7.9000308@Oracle.com> <55490240.1080206@oracle.com> Message-ID: <554B7E2B.5020702@CoSoCo.de> May be: ..., then a new internal array becomes allocated and refilled with greater capacity. ... to give a hint, that this action may be expensive. -Ulf Am 05.05.2015 um 19:47 schrieb Aleksey Shipilev: > Hi again, > > Here is a new webrev: > http://cr.openjdk.java.net/~shade/8076759/webrev.01/ > > Pruned the implementation details from expandCapacity Javadoc, and about > to submit a CCC for it. > > Thanks, > -Aleksey. > > On 05.05.2015 16:33, Roger Riggs wrote: >> Hi Aleksey, >> >> Thanks for checking the rounding alternative. >> >> As for the CCC, since the implementation details are in the javadoc >> then it will be needed either to remove the details or to update them. >> I'd be inclined to try to remove them since they are there primarily for >> performance. >> >> Thanks, Roger >> >> >> >> On 5/5/2015 4:31 AM, Aleksey Shipilev wrote: >>> Hi Roger, >>> >>> On 05/01/2015 08:19 PM, Roger Riggs wrote: >>>> Is there any additional benefit by rounding up the next multiple of 4 >>>> or 8. >>>> That would avoid a few wasted bytes at the end of the buffer modulo the >>>> allocation size. >>> It does not seem to help any further. Tried "plus32-round8", as in: >>> http://cr.openjdk.java.net/~shade/8076759/patches.txt >>> >>> ...and it performs similar to "plus32": >>> http://cr.openjdk.java.net/~shade/8076759/data-foot.png >>> http://cr.openjdk.java.net/~shade/8076759/data-perf.png >>> >>>> Otherwise, looks fine to me also. >>> I actually wonder if my change in ensureCapacity Javadoc requires a CCC? >>> On that topic, I also tempted to remove the implementation details from >>> the Javadoc there, since it does not play well with "describe what you >>> will do, not how would you do it". >>> >>> Thanks, >>> -Aleksey. >>> > > From aleksej.efimov at oracle.com Thu May 7 15:33:56 2015 From: aleksej.efimov at oracle.com (Aleksej Efimov) Date: Thu, 07 May 2015 18:33:56 +0300 Subject: RFR: 8062518: AIOBE occurs when accessing to document function in extended function in JAXP In-Reply-To: <54BCF7F1.3010404@oracle.com> References: <54BCF7F1.3010404@oracle.com> Message-ID: <554B85E4.1080908@oracle.com> Hi, Please, review the second version of the fix for JDK-8062518 [1] The previously proposed fix for the reported bug was slightly incorrect - it solves the problem by providing the access to the node from other DTM and it was not a good/proper solution. New fix [2] properly prepares a nodeList using a node's dtm, not the main one. Testing: JCK, JTREG with new test and JAXP testset shows no failures Thank you, Aleksej [1] JBS: https://bugs.openjdk.java.net/browse/JDK-8062518 [2] Webrev: http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.01 On 01/19/2015 03:26 PM, Aleksej Efimov wrote: > Please, review the fix for the failure observed while accessing > external document during xsl transformation: > https://bugs.openjdk.java.net/browse/JDK-8062518 > The jaxp code limits the access to external documents, but there is a > possibility to access such documents from the xsl code - new > regression test checks this functionality. The fix removes this > restriction and AIOBE: > http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.00/ > > Testing: > xml related regression tests (with new test) - no failures (from jdk > and jaxp repos). > JCK xml related tests - no failures. > > With Best Regards, > Aleksej From ivan.gerasimov at oracle.com Thu May 7 16:18:35 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 07 May 2015 19:18:35 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> Message-ID: <554B905B.7040605@oracle.com> Hi Martin! > > I'm afraid of these changes - they are hard to review. > > Can't we fix the SOE with a relatively small change to > ArrayList.SubList methods that recursively invoke parent methods to > use iteration instead, i.e. can't you implement updateSizeAndModCount > in the existing SubList class? > Well. Another minor goal I had was to possibly unify two implementations of sublists in AbstractList.java and ArrayList.java. Let me do another try in that direction. What if sublist classes are made static inner classes, will it look better? Please see the updated webrev: WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/03/webrev/ > --- > > I would make modCount an argument to updateSizeAndModCount. > I did that initially, but later realized that this argument should never be different from root.modCount. > --- > > Separate out hot and cold code in subListRangeCheck (although > pre-existing code had the same problem) > > + static void subListRangeCheck(int fromIndex, int toIndex, int size) { > + if (fromIndex < 0) > + throw new IndexOutOfBoundsException("fromIndex = " + > fromIndex); > + if (toIndex > size) > + throw new IndexOutOfBoundsException("toIndex = " + toIndex); > + if (fromIndex > toIndex) > + throw new IllegalArgumentException("fromIndex(" + fromIndex + > + ") > toIndex(" + > toIndex + ")"); > + } > + > > if ((fromIndex < 0) | (toIndex > size) | (fromIndex > toIndex)) > slowpath(); > Recently, I investigated this possible way of optimization, and I was surprised to discover that javac generates more compact code for logical operators, comparing to bitwise operators for booleans. I've just tried it again to refresh my memory and here are results for a simple function: This >>> void f(int index) { if (index < 0 || index >= size) throw new Error(); } <<< compiles into 20 bytecode commads. This >>> void f(int index) { if (index < 0 | index >= size) throw new Error(); } <<< produces 34 commads. This is because the bitwise or operator really operates on integers. So, javac first conditionally initializes an auxiliary integer variables to either 0 or 1, then ORs them, and then checks the result. As the result, we have 3 branches in the code above. Another approach would be to do something like this: void f(int index) { int x = index | (size - 1 - index); if (x < 0) throw new Error(); } The code length (23) is still a bit greater, comparing to the first version, but on the other hand it's got only one branch. It's still not clear though, if this going to be more efficient or not. I recommend to leave this code as is for now, and investigate the ways to optimize it in a different CR. > --- > java style consensus has been converging on: java source files should > have exactly one top-level class. It seems like you changed inner > class SubList to be a top-level class - why? > Until now, SubList and RandomAccessSubList were top-level classes in AbstractList.java. ArrayList.SubList was an inner class. Wanting to make their implementations similar, I either had to make all of them inner classes (webrev #1), or top-level classes (like in webrev #2). In my last attempt I made them inner static classes. Number of changes is relatively small, so it might be easier to review. Would you please take a look? http://cr.openjdk.java.net/~igerasim/8079136/03/webrev/ Sincerely yours, Ivan From mcnepp02 at googlemail.com Thu May 7 17:09:30 2015 From: mcnepp02 at googlemail.com (Gernot Neppert) Date: Thu, 07 May 2015 19:09:30 +0200 Subject: Add Predicate.of(), Consumer.of(), etc. In-Reply-To: References: <55454241.8030409@univ-mlv.fr> <035D1CE5-592A-4834-AC2E-9FBE0911F122@oracle.com> <2D2F2B20-0FC7-430F-9C4B-696CCE775B29@oracle.com> Message-ID: <554B9C4A.3070204@googlemail.com> Yeah, this is what came to my mind first. Just seems more elegant that a static helper method in Predicate. (Even though I'd prefer the name "without" over "filterNot".) Should be a default method implemented in terms of "filter". Am 06.05.2015 16:06, schrieb Stephen Colebourne: > I also think that filterNot should be added to stream. Its just too > common a case. Stephen From bourges.laurent at gmail.com Thu May 7 18:06:48 2015 From: bourges.laurent at gmail.com (=?ISO-8859-1?Q?Laurent_Bourg=E8s?=) Date: Thu, 7 May 2015 20:06:48 +0200 Subject: RFR: JDK-8066859 java/lang/ref/OOMEInReferenceHandler.java failed with java.lang.Exception: Reference Handler thread died In-Reply-To: <554B3D91.5010802@gmail.com> References: <554A4BAB.4000004@gmail.com> <554AFDE2.9040400@gmail.com> <554B3D91.5010802@gmail.com> Message-ID: Peter, Thanks for long and detailled answer. I know now better why OOME should not happen. However any application may also use phantom references and the ReferenceHandler thread will call Cleaner.run () which could catch OOME from the application code implementing thunk.run (). Am I right ? >> If this block also throws a new oome2 due to the first oome1 (no memory left), it will work but I would have prefered a more explicit solution and check oome1 first ... I looked back at your patch and it is fine. Howevdr I wonder if it would be possible to avoid any allocation in the catch(Throwable) block: - preallocate the PriviledgeAction - avoid new Error(x) to get its stack trace ? Do you know any trick like ones in SharedSecrets that could dump the stack without any allocation in case of urgency ? > You have a point and I asked myself the same question. The question is how to treat OOME thrown from thunk.run(). Current behavior is to exit() JVM for any exception (Throwable). I maintained that semantics. I only added a handler for OOME thrown in the handler of the 1st exception. I might have just exit()-ed the VM if OOME is thrown, but leaving no trace and just exiting VM would not help anyone diagnose what went wrong. So I opted for keeping the VM running for a while by delaying the handling of 1st exception to "better times". If better times never come, then the application is probably stuck anyway. Seems very good after a 2nd look. However, it could loop for a while if no more memory left ? For example: oome1 => oome2 (catch) => throw x=> oome2 (catch) => .... > An alternative would be to catch OOME from thunk.run() and ignore it (printing it out would be ugly if VM is left to run), but that would silently ignore OOMEs thrown from thunk.run() and noone would notice that Cleaner(s) might not have clean-ed up the resources they should. I am a bit lost but I like logging such exceptional case but if no allocation can happen, how to ensure logging such case anyway ? ... > Anyway. If none of the Cleaner.thunk's run() methods can throw any exception, then my handling of OOME is redundant and a code-path never taken. But I would still leave it there in case some new Cleaner use comes along which is not verified yet... Agreed. It is always better to handle such exceptional case if you can at least log them... Best regards, Laurent From patrick at reini.net Thu May 7 18:13:13 2015 From: patrick at reini.net (Patrick Reinhart) Date: Thu, 7 May 2015 20:13:13 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() Message-ID: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> Hi there, A couple months ago the transferTo() method was added to the JDK. I?m regularly joining the local hacker garten and wanted to ask if it maybe would be a good task to clean up the JDK code to use this method in such a session. Would someone sponsor such changes to be checked in? I would suggest that I would post a diff for each changed class to the core-libs-dev list. Cheers Patrick From pavel.rappo at oracle.com Thu May 7 18:44:17 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Thu, 7 May 2015 19:44:17 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> Message-ID: <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Hi Patrick, That's a good idea! I can sponsor them no problem. -Pavel > On 7 May 2015, at 19:13, Patrick Reinhart wrote: > > Hi there, > > A couple months ago the transferTo() method was added to the JDK. I?m regularly joining the local hacker garten and wanted to ask if it maybe would be a good task to clean up the JDK code to use this method in such a session. Would someone sponsor such changes to be checked in? I would suggest that I would post a diff for each changed class to the core-libs-dev list. > > Cheers > > Patrick From dl at cs.oswego.edu Thu May 7 19:23:38 2015 From: dl at cs.oswego.edu (Doug Lea) Date: Thu, 07 May 2015 15:23:38 -0400 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> Message-ID: <554BBBBA.9050804@cs.oswego.edu> On 05/06/2015 07:23 PM, Martin Buchholz wrote: > Hi Ivan, > > I'm afraid of these changes - they are hard to review. I believe that they also break the AbstractList.subList spec. http://docs.oracle.com/javase/8/docs/api/java/util/AbstractList.html#subList-int-int- The reason that flattened forms were not used is that each layer does not in general know the class of its parent. However, flattened forms are used in java.util.ArrayList.SubList. It would be possible (and easy) to create a specialization for the java.util.Arrays.ArrayList class (i.e., the kind returned by Arrays.asList(a).subList), which would also fix the SOE problem in this particular case. -Doug > > Can't we fix the SOE with a relatively small change to ArrayList.SubList > methods that recursively invoke parent methods to use iteration instead, > i.e. can't you implement updateSizeAndModCount in the existing SubList > class? > > --- > > I would make modCount an argument to updateSizeAndModCount. > > --- > > Separate out hot and cold code in subListRangeCheck (although pre-existing > code had the same problem) > > + static void subListRangeCheck(int fromIndex, int toIndex, int size) { > + if (fromIndex < 0) > + throw new IndexOutOfBoundsException("fromIndex = " + > fromIndex); > + if (toIndex > size) > + throw new IndexOutOfBoundsException("toIndex = " + toIndex); > + if (fromIndex > toIndex) > + throw new IllegalArgumentException("fromIndex(" + fromIndex + > + ") > toIndex(" + toIndex + > ")"); > + } > + > > if ((fromIndex < 0) | (toIndex > size) | (fromIndex > toIndex)) slowpath(); > > --- > java style consensus has been converging on: java source files should have > exactly one top-level class. It seems like you changed inner class SubList > to be a top-level class - why? > > +class ArraySubList extends AbstractList implements RandomAccess { > > > > > > On Wed, May 6, 2015 at 1:25 PM, Ivan Gerasimov > wrote: > >> And here's another update: >> >> WEBREV: http://cr.openjdk.java.net/~igerasim/8079136/2/webrev/ >> > From forax at univ-mlv.fr Thu May 7 19:26:32 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 07 May 2015 21:26:32 +0200 Subject: Add Predicate.of(), Consumer.of(), etc. In-Reply-To: References: <55454241.8030409@univ-mlv.fr> <035D1CE5-592A-4834-AC2E-9FBE0911F122@oracle.com> <2D2F2B20-0FC7-430F-9C4B-696CCE775B29@oracle.com> Message-ID: <554BBC68.3010408@univ-mlv.fr> On 05/06/2015 03:53 PM, Paul Sandoz wrote: > On May 6, 2015, at 1:58 PM, Attila Szegedi wrote: > >> On May 6, 2015, at 12:37 PM, Paul Sandoz wrote: >>> >>> On May 2, 2015, at 11:31 PM, Remi Forax wrote: >>> >>>> Hi all, >>>> today, I stubble on a variant of JDK-8050818 [1], >>>> trying to call negate() on a lambda which is not yet a Predicate (due to target typing) which requires either to cast the lambda to a Predicate and everybody knows that cast are evil or to add a local variable. >>>> >>>> I think there is a way to fix that, it's not very orthodox so I let you judge. >>>> The idea is to introduce a static method 'of' on Predicate, >>>> class Predicate { >>>> ... >>>> public static Predicate of(Predicate predicate) { >>>> return predicate; >>>> } >>>> } >>>> >>>> so one can write: >>>> stream.filter(Predicate.of(String::isEmpty).negate()) >>>> compared to >>>> stream.filter(((Predicate)String::isEmpty).negate()) >>>> >>>> so the question is, does it it worth the cost to introduce a static method that basically do nothing on all functional interfaces of java.util.function. >>>> >>> That does have the virtue of not adding a static method per operation but i still cannot bring myself to add such methods as a work around for seems like a compiler inference problem (albeit one in which might be very tricky or not possible to solve). >> I think it is firmly in the category of ?very tricky?, but probably still possible, albeit (from my point of view) undesirable. >> >> String::isEmpty will not, on its own, have a method named .negate(); the compiler can?t really infer the programmer?s intent to make it into a Predicate, not without a fairly high level reasoning (filter needs a Predicate; should the compiler perform an exhaustive search of the visible functional interfaces to see which one has a method with signature ?Predicate negate()??). So, yeah, it seems like in this case the programmer needs to communicate the intent. >> >> I think inference would be *possible*, but it?d be expensive, and would still allow for either ambiguities or accidentally matching something unexpected, so I think it would also be undesirable. >> > Ok. I agree with Atilla, basically, the compiler can only infer the function type corresponding to a lambda so the compiler need to bridge the gap between the function type and the corresponding interface by using some vodoo incantation based on the types currently imported (at least). > > >> I don?t have an opinion of whether we want an ?of? static method on Predicate, as then it would have to indeed be introduced on many other interfaces. It?s more appealing than a cast, certainly; especially since the cast apparently needs to specify the explicit type parameter too. >> > I guess it's too late to consider an implicitly declared method along the lines of what Remi suggests. FWIW i always found such methods on enum a little too magical. about values() and valueOf(), the main issue for my students is that these methods have no javadoc. > And perhaps it's too confusing to consider an invocation mode where "this" can be an implicit first parameter. The opposite of the C# extension method, write an instance method and you can use it as a static method, funny until someone will see when debugging that a call to a static method can run a method deep in the hierarchy :( > > >>> In some respects i wonder if the default methods on the functional interfaces are an attractive nuisance. Function composition is an important concept and being able to specify an implementation of an operation on a function is exactly what a default method on a functional interface is, by example: interface Logger { void log(String msg); default Logger filter(Predicate filter) { return msg -> { if (filter.accept(msg) { log(msg); } }; } } // a Logger Logger logger = System.err::println; // a Logger that logs only message that starts with 'W' Logger wLogger = logger.filter(msg -> msg.startsWith("W")); >> Meaning, if .negate(Predicate) were a static method on the Predicate class instead of a default method, then stream.filter(Predicate.negate(String::isEmpty)) would be possible? Yeah? >> > Yeah. We are now in the unfortunate position where to alleviate this problem we might require duplicate static and default methods. I have been sitting on the issue a bit and nearly closed it a few times :-) > > Paul. R?mi From peter.levart at gmail.com Thu May 7 19:40:33 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 07 May 2015 21:40:33 +0200 Subject: RFR: JDK-8066859 java/lang/ref/OOMEInReferenceHandler.java failed with java.lang.Exception: Reference Handler thread died In-Reply-To: References: <554A4BAB.4000004@gmail.com> <554AFDE2.9040400@gmail.com> <554B3D91.5010802@gmail.com> Message-ID: <554BBFB1.7070804@gmail.com> On 05/07/2015 08:06 PM, Laurent Bourg?s wrote: > > Peter, > > Thanks for long and detailled answer. > > I know now better why OOME should not happen. However any application > may also use phantom references and the ReferenceHandler thread will > call Cleaner.run () which could catch OOME from the application code > implementing thunk.run (). Am I right ? > Any application may use PhantomReference(s) but not Cleaner(s). Cleaner is a PhantoReference, but it is a JDK-internal API. I belive in JDK9 it will not be visible at all (sun.misc.Cleaner). The Cleaner(s) are reserved for JDK-internal use in particular because they utilize a single ReferenceHandler thread that also serves a vital role of dispatching of cleared Reference(s) to their ReferenceQueue(s)... > >> If this block also throws a new oome2 due to the first oome1 (no > memory left), it will work but I would have prefered a more explicit > solution and check oome1 first ... > > I looked back at your patch and it is fine. Howevdr I wonder if it > would be possible to avoid any allocation in the catch(Throwable) block: > - preallocate the PriviledgeAction > - avoid new Error(x) to get its stack trace ? Do you know any trick > like ones in SharedSecrets that could dump the stack without any > allocation in case of urgency ? > What about the printing path? Who can guarantee that it doesn't use any allocation? The diagnostic print-out that precedes System.exit() should preferably be equipped with a stack-trace of the original exception. Formatting a stack trace needs allocation. But it's a good idea to try in that direction too. Perhaps 1st try to print like now and if OOME #2 is thrown, resort to minimal printing that doesn't allocate... > > You have a point and I asked myself the same question. The question > is how to treat OOME thrown from thunk.run(). Current behavior is to > exit() JVM for any exception (Throwable). I maintained that semantics. > I only added a handler for OOME thrown in the handler of the 1st > exception. I might have just exit()-ed the VM if OOME is thrown, but > leaving no trace and just exiting VM would not help anyone diagnose > what went wrong. So I opted for keeping the VM running for a while by > delaying the handling of 1st exception to "better times". If better > times never come, then the application is probably stuck anyway. > > Seems very good after a 2nd look. > However, it could loop for a while if no more memory left ? > For example: oome1 => oome2 (catch) => throw x=> oome2 (catch) => .... > The retries are based on Cleaner processing code-path liveness. So it's not really looping and doing nothing. Each time some Cleaner is found to be processed, the pending exception is checked too. If no Cleaner(s) are dequeued by ReferenceHandler thread after the one that 'saved' the exception, the exception will not be handled and VM will not exit. I'm aware of that, so your idea of trying to print something minimal without allocation immediately if it can't be printed nicely, seems even more attractive. > > An alternative would be to catch OOME from thunk.run() and ignore it > (printing it out would be ugly if VM is left to run), but that would > silently ignore OOMEs thrown from thunk.run() and noone would notice > that Cleaner(s) might not have clean-ed up the resources they should. > > I am a bit lost but I like logging such exceptional case but if no > allocation can happen, how to ensure logging such case anyway ? > ... > I must check printing code-path. Perhaps it doesn't need to allocate anything. > > Anyway. If none of the Cleaner.thunk's run() methods can throw any > exception, then my handling of OOME is redundant and a code-path never > taken. But I would still leave it there in case some new Cleaner use > comes along which is not verified yet... > > Agreed. It is always better to handle such exceptional case if you can > at least log them... > > Best regards, > Laurent > Regards, Peter From chris.hegarty at oracle.com Thu May 7 19:45:04 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 7 May 2015 20:45:04 +0100 Subject: RFR [9] RandomFactory should be in the jdk.testlibrary package Message-ID: When trying to use the recently added RandomFactory test library utility, I noticed that it is missing a package declaration. The pattern to date has been for these test library utilities to be declared in the jdk.testlibrary package, and imported by tests requiring them. This is a simple patch that does just that. I think this was a minor oversight, as opposed to a deliberate decision to put RandomFactory in the unnamed package. diff --git a/test/lib/testlibrary/jdk/testlibrary/RandomFactory.java b/test/lib/testlibrary/jdk/testlibrary/RandomFactory.java --- a/test/lib/testlibrary/jdk/testlibrary/RandomFactory.java +++ b/test/lib/testlibrary/jdk/testlibrary/RandomFactory.java @@ -21,6 +21,8 @@ * questions. */ +package jdk.testlibrary; + import java.util.Random; import java.util.SplittableRandom; diff --git a/test/java/lang/Double/ParseHexFloatingPoint.java b/test/java/lang/Double/ParseHexFloatingPoint.java --- a/test/java/lang/Double/ParseHexFloatingPoint.java +++ b/test/java/lang/Double/ParseHexFloatingPoint.java @@ -32,6 +32,8 @@ * @key randomness */ +import jdk.testlibrary.RandomFactory; + public class ParseHexFloatingPoint { private ParseHexFloatingPoint(){} diff --git a/test/java/lang/Integer/BitTwiddle.java b/test/java/lang/Integer/BitTwiddle.java --- a/test/java/lang/Integer/BitTwiddle.java +++ b/test/java/lang/Integer/BitTwiddle.java @@ -33,6 +33,7 @@ */ import java.util.Random; +import jdk.testlibrary.RandomFactory; import static java.lang.Integer.*; public class BitTwiddle { diff --git a/test/java/lang/Long/BitTwiddle.java b/test/java/lang/Long/BitTwiddle.java --- a/test/java/lang/Long/BitTwiddle.java +++ b/test/java/lang/Long/BitTwiddle.java @@ -33,6 +33,7 @@ */ import java.util.Random; +import jdk.testlibrary.RandomFactory; import static java.lang.Long.*; public class BitTwiddle { diff --git a/test/java/lang/Math/CubeRootTests.java b/test/java/lang/Math/CubeRootTests.java --- a/test/java/lang/Math/CubeRootTests.java +++ b/test/java/lang/Math/CubeRootTests.java @@ -32,6 +32,8 @@ * @key randomness */ +import jdk.testlibrary.RandomFactory; + public class CubeRootTests { private CubeRootTests(){} diff --git a/test/java/lang/Math/HypotTests.java b/test/java/lang/Math/HypotTests.java --- a/test/java/lang/Math/HypotTests.java +++ b/test/java/lang/Math/HypotTests.java @@ -32,6 +32,8 @@ * @key randomness */ +import jdk.testlibrary.RandomFactory; + public class HypotTests { private HypotTests(){} diff --git a/test/java/lang/Math/IeeeRecommendedTests.java b/test/java/lang/Math/IeeeRecommendedTests.java --- a/test/java/lang/Math/IeeeRecommendedTests.java +++ b/test/java/lang/Math/IeeeRecommendedTests.java @@ -32,6 +32,8 @@ * @key randomness */ +import jdk.testlibrary.RandomFactory; + public class IeeeRecommendedTests { private IeeeRecommendedTests(){} diff --git a/test/java/lang/Math/Log1pTests.java b/test/java/lang/Math/Log1pTests.java --- a/test/java/lang/Math/Log1pTests.java +++ b/test/java/lang/Math/Log1pTests.java @@ -32,6 +32,8 @@ * @key randomness */ +import jdk.testlibrary.RandomFactory; + public class Log1pTests { private Log1pTests(){} diff --git a/test/java/math/BigDecimal/StringConstructor.java b/test/java/math/BigDecimal/StringConstructor.java --- a/test/java/math/BigDecimal/StringConstructor.java +++ b/test/java/math/BigDecimal/StringConstructor.java @@ -33,6 +33,7 @@ import java.math.*; import java.util.Random; +import jdk.testlibrary.RandomFactory; public class StringConstructor { diff --git a/test/java/math/BigInteger/BigIntegerTest.java b/test/java/math/BigInteger/BigIntegerTest.java --- a/test/java/math/BigInteger/BigIntegerTest.java +++ b/test/java/math/BigInteger/BigIntegerTest.java @@ -40,6 +40,7 @@ import java.io.ObjectOutputStream; import java.math.BigInteger; import java.util.Random; +import jdk.testlibrary.RandomFactory; /** * This is a simple test class created to ensure that the results diff --git a/test/java/math/BigInteger/ModPow65537.java b/test/java/math/BigInteger/ModPow65537.java --- a/test/java/math/BigInteger/ModPow65537.java +++ b/test/java/math/BigInteger/ModPow65537.java @@ -37,6 +37,7 @@ import java.security.*; import java.security.spec.*; import java.util.Random; +import jdk.testlibrary.RandomFactory; public class ModPow65537 { diff --git a/test/java/math/BigInteger/PrimeTest.java b/test/java/math/BigInteger/PrimeTest.java --- a/test/java/math/BigInteger/PrimeTest.java +++ b/test/java/math/BigInteger/PrimeTest.java @@ -40,6 +40,7 @@ import java.util.Set; import java.util.SplittableRandom; import java.util.TreeSet; +import jdk.testlibrary.RandomFactory; import static java.util.stream.Collectors.toCollection; import static java.util.stream.Collectors.toList; diff --git a/test/java/math/BigInteger/SymmetricRangeTests.java b/test/java/math/BigInteger/SymmetricRangeTests.java --- a/test/java/math/BigInteger/SymmetricRangeTests.java +++ b/test/java/math/BigInteger/SymmetricRangeTests.java @@ -40,6 +40,7 @@ import java.util.Arrays; import java.math.BigInteger; import java.util.Random; +import jdk.testlibrary.RandomFactory; public class SymmetricRangeTests { diff --git a/test/java/util/regex/RegExTest.java b/test/java/util/regex/RegExTest.java --- a/test/java/util/regex/RegExTest.java +++ b/test/java/util/regex/RegExTest.java @@ -46,6 +46,7 @@ import java.util.*; import java.nio.CharBuffer; import java.util.function.Predicate; +import jdk.testlibrary.RandomFactory; /** * This is a test class created to check the operation of -Chris. From huizhe.wang at oracle.com Thu May 7 20:02:58 2015 From: huizhe.wang at oracle.com (huizhe wang) Date: Thu, 07 May 2015 13:02:58 -0700 Subject: RFR: 8062518: AIOBE occurs when accessing to document function in extended function in JAXP In-Reply-To: <554B85E4.1080908@oracle.com> References: <54BCF7F1.3010404@oracle.com> <554B85E4.1080908@oracle.com> Message-ID: <554BC4F2.6070709@oracle.com> Hi Aleksej, The fix looks good. For the test, it would be better to add an externalDoc: static final String externalDoc= "External Doc" so that the expectedResult becomes [Test:Doc][Test:External Doc] instead of [Test:Doc][Test:Doc] thus verifies the external document is correctly read. Please also move the test to jaxp/test/javax/xml/jaxp/unittest/javax/xml/transform, follow the TestNG format as other tests in the package, and name it XSLTFunctionsTest. Add the xml, xsl, externalDoc and expectedResult in a dataProvider called "document". Change the test method to testDocument(with these parameters), and Javadoc /** * @bug 8062518 * Verifies that a reference to the DTM created by XSLT document function is actually read from the DTM by an extension function. * @param ... */ Move make all data static and move them to the bottom of the class so that tests are at the top. The summary of the test would look something like the following, allowing function tests to be added and grouped. /* * @summary This class contains tests for XSLT functions. */ Thanks, Joe On 5/7/2015 8:33 AM, Aleksej Efimov wrote: > Hi, > Please, review the second version of the fix for JDK-8062518 [1] > The previously proposed fix for the reported bug was slightly > incorrect - it solves the problem by providing the access to the node > from other DTM and it was not a good/proper solution. > New fix [2] properly prepares a nodeList using a node's dtm, not the > main one. > Testing: JCK, JTREG with new test and JAXP testset shows no failures > > Thank you, > Aleksej > > [1] JBS: https://bugs.openjdk.java.net/browse/JDK-8062518 > [2] Webrev: http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.01 > > > On 01/19/2015 03:26 PM, Aleksej Efimov wrote: >> Please, review the fix for the failure observed while accessing >> external document during xsl transformation: >> https://bugs.openjdk.java.net/browse/JDK-8062518 >> The jaxp code limits the access to external documents, but there is a >> possibility to access such documents from the xsl code - new >> regression test checks this functionality. The fix removes this >> restriction and AIOBE: >> http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.00/ >> >> Testing: >> xml related regression tests (with new test) - no failures (from jdk >> and jaxp repos). >> JCK xml related tests - no failures. >> >> With Best Regards, >> Aleksej > From brian.burkhalter at oracle.com Thu May 7 20:19:43 2015 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 7 May 2015 13:19:43 -0700 Subject: RFR [9] RandomFactory should be in the jdk.testlibrary package In-Reply-To: References: Message-ID: <38FEB42B-A044-491E-A352-2EF03C1D75FA@oracle.com> Chris, On May 7, 2015, at 12:45 PM, Chris Hegarty wrote: > When trying to use the recently added RandomFactory test library utility, I noticed that it is missing a package declaration. The pattern to date has been for these test library utilities to be declared in the jdk.testlibrary package, and imported by tests requiring them. This is a simple patch that does just that. > > I think this was a minor oversight, as opposed to a deliberate decision to put RandomFactory in the unnamed package. Indeed it was an oversight on my part having been the first time I work with the jdk.testlibrary package. Your changes look fine to me assuming that the affected tests all still succeed. Thanks, Brian From pavel.rappo at oracle.com Thu May 7 20:51:34 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Thu, 7 May 2015 21:51:34 +0100 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554BBBBA.9050804@cs.oswego.edu> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> Message-ID: Hi Doug, > The reason that flattened forms were not used is that each > layer does not in general know the class of its parent. Could you please explain this a bit more? I'm afraid I don't quite understand how this is possible. Thanks. -Pavel From martinrb at google.com Thu May 7 22:07:05 2015 From: martinrb at google.com (Martin Buchholz) Date: Thu, 7 May 2015 15:07:05 -0700 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554B905B.7040605@oracle.com> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554B905B.7040605@oracle.com> Message-ID: On Thu, May 7, 2015 at 9:18 AM, Ivan Gerasimov wrote: > > --- >> >> I would make modCount an argument to updateSizeAndModCount. >> >> I did that initially, but later realized that this argument should never > be different from root.modCount. > > Sure, but you'd keep it in a local variable in the loop instead of a field read. No big deal either way. > --- >> >> Separate out hot and cold code in subListRangeCheck (although >> pre-existing code had the same problem) >> >> + static void subListRangeCheck(int fromIndex, int toIndex, int size) { >> + if (fromIndex < 0) >> + throw new IndexOutOfBoundsException("fromIndex = " + >> fromIndex); >> + if (toIndex > size) >> + throw new IndexOutOfBoundsException("toIndex = " + toIndex); >> + if (fromIndex > toIndex) >> + throw new IllegalArgumentException("fromIndex(" + fromIndex + >> + ") > toIndex(" + toIndex >> + ")"); >> + } >> + >> >> if ((fromIndex < 0) | (toIndex > size) | (fromIndex > toIndex)) >> slowpath(); >> >> Recently, I investigated this possible way of optimization, and I was > surprised to discover that javac generates more compact code for logical > operators, comparing to bitwise operators for booleans. > > I've just tried it again to refresh my memory and here are results for a > simple function: > > This >>> void f(int index) { if (index < 0 || index >= size) throw new > Error(); } <<< compiles into 20 bytecode commads. > This >>> void f(int index) { if (index < 0 | index >= size) throw new > Error(); } <<< produces 34 commads. > > This is because the bitwise or operator really operates on integers. > So, javac first conditionally initializes an auxiliary integer variables > to either 0 or 1, then ORs them, and then checks the result. > As the result, we have 3 branches in the code above. > > Another approach would be to do something like this: > void f(int index) { > int x = index | (size - 1 - index); > if (x < 0) > throw new Error(); > } > The code length (23) is still a bit greater, comparing to the first > version, but on the other hand it's got only one branch. > It's still not clear though, if this going to be more efficient or not. > > I recommend to leave this code as is for now, and investigate the ways to > optimize it in a different CR. You make a good point about code size of logical operations on booleans. I don't know which will be more efficient in practice - it depends on the hotspot implementation. I agree with your analysis. From martinrb at google.com Thu May 7 22:26:25 2015 From: martinrb at google.com (Martin Buchholz) Date: Thu, 7 May 2015 15:26:25 -0700 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554BBBBA.9050804@cs.oswego.edu> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> Message-ID: On Thu, May 7, 2015 at 12:23 PM, Doug Lea

wrote: > > It would be possible (and easy) to create a specialization for the > java.util.Arrays.ArrayList class (i.e., the kind returned by > Arrays.asList(a).subList), which would also fix the SOE problem > in this particular case. It seems it would be a fairly clean win to no longer have Arrays.ArrayList subclass AbstractList, getting rid of modCount (no structural modifications are possible!), at the cost of more copying. Maybe it could subclass AbstractCollection instead? From martinrb at google.com Thu May 7 22:30:12 2015 From: martinrb at google.com (Martin Buchholz) Date: Thu, 7 May 2015 15:30:12 -0700 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554B905B.7040605@oracle.com> Message-ID: On Thu, May 7, 2015 at 3:07 PM, Martin Buchholz wrote: > >>> if ((fromIndex < 0) | (toIndex > size) | (fromIndex > toIndex)) >>> slowpath(); >>> >>> Yeah, the refined proposal would be if ((fromIndex | (size - toIndex) | (toIndex - fromIndex)) < 0) slowpath(); considering that here performance is more important than the small loss of readability. From aleksej.efimov at oracle.com Thu May 7 22:42:15 2015 From: aleksej.efimov at oracle.com (Aleksej Efimov) Date: Fri, 08 May 2015 01:42:15 +0300 Subject: RFR: 8062518: AIOBE occurs when accessing to document function in extended function in JAXP In-Reply-To: <554BC4F2.6070709@oracle.com> References: <54BCF7F1.3010404@oracle.com> <554B85E4.1080908@oracle.com> <554BC4F2.6070709@oracle.com> Message-ID: <554BEA47.3000707@oracle.com> Hi Joe, Thank you for reviewing the fix - I addressed all your comments: 1. External doc was added and expected result modified accordingly 2. Test renamed and moved to jaxp repo 3. xml, xsl, external document and expected result were moved to data provider 4. Test method renamed and parameters were added. New webrev is located here: http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.02 New test passes on JDK9 build with integrated fix. Best Regards, Aleksej On 05/07/2015 11:02 PM, huizhe wang wrote: > Hi Aleksej, > > The fix looks good. > > For the test, it would be better to add an externalDoc: > static final String externalDoc= " encoding=\"UTF-8\"?>External Doc" > > so that the expectedResult becomes [Test:Doc][Test:External Doc] > instead of [Test:Doc][Test:Doc] thus verifies the external document is > correctly read. > > Please also move the test to > jaxp/test/javax/xml/jaxp/unittest/javax/xml/transform, follow the > TestNG format as other tests in the package, and name it > XSLTFunctionsTest. Add the xml, xsl, externalDoc and expectedResult in > a dataProvider called "document". Change the test method to > testDocument(with these parameters), and Javadoc > > /** > * @bug 8062518 > * Verifies that a reference to the DTM created by XSLT document > function is actually read from the DTM by an extension function. > * @param ... > */ > > Move make all data static and move them to the bottom of the class so > that tests are at the top. > > The summary of the test would look something like the following, > allowing function tests to be added and grouped. > > /* > * @summary This class contains tests for XSLT functions. > */ > > Thanks, > Joe > > On 5/7/2015 8:33 AM, Aleksej Efimov wrote: >> Hi, >> Please, review the second version of the fix for JDK-8062518 [1] >> The previously proposed fix for the reported bug was slightly >> incorrect - it solves the problem by providing the access to the node >> from other DTM and it was not a good/proper solution. >> New fix [2] properly prepares a nodeList using a node's dtm, not the >> main one. >> Testing: JCK, JTREG with new test and JAXP testset shows no failures >> >> Thank you, >> Aleksej >> >> [1] JBS: https://bugs.openjdk.java.net/browse/JDK-8062518 >> [2] Webrev: http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.01 >> >> >> On 01/19/2015 03:26 PM, Aleksej Efimov wrote: >>> Please, review the fix for the failure observed while accessing >>> external document during xsl transformation: >>> https://bugs.openjdk.java.net/browse/JDK-8062518 >>> The jaxp code limits the access to external documents, but there is >>> a possibility to access such documents from the xsl code - new >>> regression test checks this functionality. The fix removes this >>> restriction and AIOBE: >>> http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.00/ >>> >>> Testing: >>> xml related regression tests (with new test) - no failures (from jdk >>> and jaxp repos). >>> JCK xml related tests - no failures. >>> >>> With Best Regards, >>> Aleksej >> > From huizhe.wang at oracle.com Thu May 7 23:21:37 2015 From: huizhe.wang at oracle.com (huizhe wang) Date: Thu, 07 May 2015 16:21:37 -0700 Subject: RFR: 8062518: AIOBE occurs when accessing to document function in extended function in JAXP In-Reply-To: <554BEA47.3000707@oracle.com> References: <54BCF7F1.3010404@oracle.com> <554B85E4.1080908@oracle.com> <554BC4F2.6070709@oracle.com> <554BEA47.3000707@oracle.com> Message-ID: <554BF381.3030205@oracle.com> Hi Aleksej, Looks good. Thanks for working so hard on this and other customer reported issues! If we need tests for any other functions in the future, we can add them to this class. Best, Joe On 5/7/2015 3:42 PM, Aleksej Efimov wrote: > Hi Joe, > Thank you for reviewing the fix - I addressed all your comments: > 1. External doc was added and expected result modified accordingly > 2. Test renamed and moved to jaxp repo > 3. xml, xsl, external document and expected result were moved to data > provider > 4. Test method renamed and parameters were added. > New webrev is located here: > http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.02 > New test passes on JDK9 build with integrated fix. > > Best Regards, > Aleksej > > On 05/07/2015 11:02 PM, huizhe wang wrote: >> Hi Aleksej, >> >> The fix looks good. >> >> For the test, it would be better to add an externalDoc: >> static final String externalDoc= "> encoding=\"UTF-8\"?>External Doc" >> >> so that the expectedResult becomes [Test:Doc][Test:External Doc] >> instead of [Test:Doc][Test:Doc] thus verifies the external document >> is correctly read. >> >> Please also move the test to >> jaxp/test/javax/xml/jaxp/unittest/javax/xml/transform, follow the >> TestNG format as other tests in the package, and name it >> XSLTFunctionsTest. Add the xml, xsl, externalDoc and expectedResult >> in a dataProvider called "document". Change the test method to >> testDocument(with these parameters), and Javadoc >> >> /** >> * @bug 8062518 >> * Verifies that a reference to the DTM created by XSLT document >> function is actually read from the DTM by an extension function. >> * @param ... >> */ >> >> Move make all data static and move them to the bottom of the class so >> that tests are at the top. >> >> The summary of the test would look something like the following, >> allowing function tests to be added and grouped. >> >> /* >> * @summary This class contains tests for XSLT functions. >> */ >> >> Thanks, >> Joe >> >> On 5/7/2015 8:33 AM, Aleksej Efimov wrote: >>> Hi, >>> Please, review the second version of the fix for JDK-8062518 [1] >>> The previously proposed fix for the reported bug was slightly >>> incorrect - it solves the problem by providing the access to the >>> node from other DTM and it was not a good/proper solution. >>> New fix [2] properly prepares a nodeList using a node's dtm, not the >>> main one. >>> Testing: JCK, JTREG with new test and JAXP testset shows no failures >>> >>> Thank you, >>> Aleksej >>> >>> [1] JBS: https://bugs.openjdk.java.net/browse/JDK-8062518 >>> [2] Webrev: http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.01 >>> >>> >>> On 01/19/2015 03:26 PM, Aleksej Efimov wrote: >>>> Please, review the fix for the failure observed while accessing >>>> external document during xsl transformation: >>>> https://bugs.openjdk.java.net/browse/JDK-8062518 >>>> The jaxp code limits the access to external documents, but there is >>>> a possibility to access such documents from the xsl code - new >>>> regression test checks this functionality. The fix removes this >>>> restriction and AIOBE: >>>> http://cr.openjdk.java.net/~aefimov/8062518/9/webrev.00/ >>>> >>>> Testing: >>>> xml related regression tests (with new test) - no failures (from >>>> jdk and jaxp repos). >>>> JCK xml related tests - no failures. >>>> >>>> With Best Regards, >>>> Aleksej >>> >> > From attila.szegedi at oracle.com Fri May 8 09:41:56 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Fri, 8 May 2015 11:41:56 +0200 Subject: AbstractList etc. functionality as interfaces with default methods? Message-ID: So I?m in a position where I?d need to have a class implement List, but it already extends something else, so I can?t have it extend AbstractList, which leaves me with a lot of boilerplate methods to implement. Would it seem like a good idea to reimagine AbstractList and friends as interfaces with default methods? Of course, I know that technically for backwards compatibility we can?t really do this, but what we could do is: public interface DefaultList extends List { ? add all methods from AbstractList here as default methods ? } public abstract class AbstractList implements DefaultList { } (I?ll hand-wave the issue of ?protected int modCount? issue for now.) Actually, this seems like such an obvious idea that I?m 100% sure it must?ve been considered before, but I can?t find any related discussion. Attila. From pavel.rappo at oracle.com Fri May 8 09:50:52 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Fri, 8 May 2015 10:50:52 +0100 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: Message-ID: > I?m in a position where I?d need to have a class implement List, but it already extends something else, so I can?t have it extend AbstractList Would composition help you instead of inheritance? (I might be missing something obvious) -Pavel From pavel.rappo at oracle.com Fri May 8 10:15:14 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Fri, 8 May 2015 11:15:14 +0100 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: Message-ID: > (I?ll hand-wave the issue of ?protected int modCount? issue for now.) Not only. Consider this: java.util.AbstractList overrides some methods from java.lang.Object such as equals and hashCode. And this is a no-no [1]: ...It is a compile-time error if a default method is override-equivalent with a non-private method of the class Object, because any class implementing the interface will inherit its own implementation of the method... ------------------------------------------------------------------------------- [1] https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.4.1.2 From ivan.gerasimov at oracle.com Fri May 8 10:38:08 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 08 May 2015 13:38:08 +0300 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: Message-ID: <554C9210.7020206@oracle.com> I was just going to propose something similar: A base abstract class for AbstractList, which implements everything but SubList-related stuff (including modCount). This way we could easily create specializations for sublists of Arrays.ArrayList and Collections.SingleToneList, which do not need to track structural modifications. Please see the sibling thread 'RFR: 8079136: Accessing a nested sublist leads to StackOverflowError'. This new base class shouldn't be a part of public API, of course. Sincerely yours, Ivan On 08.05.2015 12:41, Attila Szegedi wrote: > So I?m in a position where I?d need to have a class implement List, but it already extends something else, so I can?t have it extend AbstractList, which leaves me with a lot of boilerplate methods to implement. > > Would it seem like a good idea to reimagine AbstractList and friends as interfaces with default methods? > > Of course, I know that technically for backwards compatibility we can?t really do this, but what we could do is: > > public interface DefaultList extends List { > ? add all methods from AbstractList here as default methods ? > } > > public abstract class AbstractList implements DefaultList { > } > > (I?ll hand-wave the issue of ?protected int modCount? issue for now.) > > Actually, this seems like such an obvious idea that I?m 100% sure it must?ve been considered before, but I can?t find any related discussion. > > Attila. > From aleksey.shipilev at oracle.com Fri May 8 11:28:13 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Fri, 08 May 2015 14:28:13 +0300 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <554B7E2B.5020702@CoSoCo.de> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> <5543B58F.6020105@Oracle.com> <55487FE9.5010606@oracle.com> <5548C6C7.9000308@Oracle.com> <55490240.1080206@oracle.com> <554B7E2B.5020702@CoSoCo.de> Message-ID: <554C9DCD.5090202@oracle.com> On 05/07/2015 06:00 PM, Ulf Zibis wrote: > May be: > ..., then a new internal array becomes allocated and refilled with > greater capacity. > > ... to give a hint, that this action may be expensive. The Javadoc already says "If the current capacity is less than the argument, then a new internal array is allocated with greater capacity", which seems to be what you are saying. Anyway, CCC request is in flight, and changes there will require re-spinning. I am not tempted to do that if the current language is good and already fits your concerns. Thanks, -Aleksey. From pavel.rappo at oracle.com Fri May 8 12:13:51 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Fri, 8 May 2015 13:13:51 +0100 Subject: RFR JDK-8029689: (spec) Reader.read(char[], int, int) throws unspecified IndexOutOfBoundsException In-Reply-To: <82418788-57BC-48B1-A6B2-DB760AB9FE47@oracle.com> References: <397916B4-BE8B-43F4-8380-366312EFED39@oracle.com> <83C8ED6F-B6C5-4231-97DA-02876435CE42@oracle.com> <55351A1F.3030206@oracle.com> <5535AF22.1090500@oracle.com> <82418788-57BC-48B1-A6B2-DB760AB9FE47@oracle.com> Message-ID: <5D98E887-7BBA-4440-AFF7-8F8DD5608901@oracle.com> Here's the latest update: http://cr.openjdk.java.net/~prappo/8029689/webrev.01/ -Pavel > On 21 Apr 2015, at 09:08, Chris Hegarty wrote: > > On 21 Apr 2015, at 03:00, David Holmes wrote: > >> On 21/04/2015 1:24 AM, Chris Hegarty wrote: >>> >>> On 20/04/15 16:17, Lance Andersen wrote: >>>> Hi Pavel, >>>> >>>> So we are just documenting/clarifying the current behavior from what I >>>> can tell from the change? >>> >>> Looking at the testcase, it passes with the current JDK 9 ( and 8 ), so >>> this is just documenting existing behavior. >> >> Right. The assumption is that original authors overlooked the fact that the @exception/@throws for unchecked exceptions would not automatically be inherited by subclasses, and that in fact those subclasses (in this case) should indeed have inherited the same preconditions from the parent. > > All subclasses of java.io.Reader are documenting existing behaviour ( such documentation of uncheck exceptions was not the norm when these classes were originally written, but seems reasonable in this case ). But java.io.Reader.read(String,int,int) is abstract, and as such is having additional specification added ( which should be fine ). > > The only question is about third party implementations of Reader ( or other non Java SE implementations in the JDK), which may need to be amended to confirm to this ?new? bounds check. Again, I think this should be fine, and seems in line with the evolution policy of core libraries. > > -Chris. > >> David >> >>>> If so, this looks OK assuming you have an approved CCC? The test >>> seems fine. >>> >>> A CCC will be needed, and should be submitted after successful review. >>> >>>> I am assuming there should not be any issues here but would be good to >>>> hear from others on this change as well >>> >>> Right. We do this ( clarify spec from existing behavior) in other areas >>> too. >>> >>> Given that this is the current behavior of existing platform subtypes, >>> then this change is only specifying existing behavior. Since there are >>> no implementation changes, then Third party Reader subtypes will >>> continue to function as before, but they may need to be updated at some >>> point in the future. >>> >>> -Chris. >>> >>>> Best >>>> Lance >>>> On Apr 20, 2015, at 11:10 AM, Pavel Rappo wrote: >>>> >>>>> >>>>> Hi everyone, >>>>> >>>>> Could you please review my change for JDK-8029689 >>>>> >>>>> http://cr.openjdk.java.net/~prappo/8029689/webrev.00/ >>>>> >>>>> ------------------------------------------------------------------------------- >>>>> >>>>> There is a long-standing issue when platform implementations of >>>>> java.io.Reader >>>>> throw IndexOutOfBoundsException for bounds checks from inherited >>>>> java.io.Reader.read(char[], int, int) method though java.io.Reader >>>>> itself does >>>>> not specify this situation. >>>>> >>>>> Suggested solution is to update the contract of >>>>> java.io.Reader.read(char[], int, >>>>> int) and its publicly exported descendants to capture the implied >>>>> preconditions >>>>> for reading range and the array size. >>>>> >>>>> Given that throwing IOBE in this situation is a de facto standard, >>>>> this change >>>>> won't bring any kind of incompatibility, though to stay compliant 3rd >>>>> party >>>>> implementations may need to be updated. >>>>> >>>>> -Pavel >>>>> >>>> >>>> >>>> >>>> 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 Ulf.Zibis at CoSoCo.de Fri May 8 12:46:13 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Fri, 08 May 2015 14:46:13 +0200 Subject: RFR (XS) 8076759: AbstractStringBuilder.append(...) should ensure enough capacity for the upcoming "trivial" append calls In-Reply-To: <554C9DCD.5090202@oracle.com> References: <553A85EA.5090603@oracle.com> <55438902.4000307@oracle.com> <5543B58F.6020105@Oracle.com> <55487FE9.5010606@oracle.com> <5548C6C7.9000308@Oracle.com> <55490240.1080206@oracle.com> <554B7E2B.5020702@CoSoCo.de> <554C9DCD.5090202@oracle.com> Message-ID: <554CB015.9040503@CoSoCo.de> Am 08.05.2015 um 13:28 schrieb Aleksey Shipilev: > On 05/07/2015 06:00 PM, Ulf Zibis wrote: >> May be: >> ..., then a new internal array becomes allocated and refilled with >> greater capacity. >> >> ... to give a hint, that this action may be expensive. > The Javadoc already says "If the current capacity is less than the > argument, then a new internal array is allocated with greater capacity", > which seems to be what you are saying. Allocating a new array is one thing, but copying the old data into the new one is another story where the cost is dependent on it's size. Also theoretically, AbstractStringBuilder could hold multiple arrays to avoid the copying and solve memory fragmentation issues. Both aspects are implementation details, so when mentioned in Javadoc, my thought is, to do that in completeness. Maybe there is a better wording than "refill" to indicate the internal copying. -Ulf From chris.hegarty at oracle.com Fri May 8 12:51:02 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Fri, 08 May 2015 13:51:02 +0100 Subject: RFR JDK-8029689: (spec) Reader.read(char[], int, int) throws unspecified IndexOutOfBoundsException In-Reply-To: <5D98E887-7BBA-4440-AFF7-8F8DD5608901@oracle.com> References: <397916B4-BE8B-43F4-8380-366312EFED39@oracle.com> <83C8ED6F-B6C5-4231-97DA-02876435CE42@oracle.com> <55351A1F.3030206@oracle.com> <5535AF22.1090500@oracle.com> <82418788-57BC-48B1-A6B2-DB760AB9FE47@oracle.com> <5D98E887-7BBA-4440-AFF7-8F8DD5608901@oracle.com> Message-ID: <554CB136.7030605@oracle.com> On 08/05/15 13:13, Pavel Rappo wrote: > Here's the latest update: > > http://cr.openjdk.java.net/~prappo/8029689/webrev.01/ The source changes look good to me Pavel. Just a few minor comments on the test: 1) There is a trivial System.out on L143 that could be removed. 2) L157, is this referring to computeIfAbsent? I think a small comment about concurrency would be sufficient. -Chris. > -Pavel > >> On 21 Apr 2015, at 09:08, Chris Hegarty wrote: >> >> On 21 Apr 2015, at 03:00, David Holmes wrote: >> >>> On 21/04/2015 1:24 AM, Chris Hegarty wrote: >>>> >>>> On 20/04/15 16:17, Lance Andersen wrote: >>>>> Hi Pavel, >>>>> >>>>> So we are just documenting/clarifying the current behavior from what I >>>>> can tell from the change? >>>> >>>> Looking at the testcase, it passes with the current JDK 9 ( and 8 ), so >>>> this is just documenting existing behavior. >>> >>> Right. The assumption is that original authors overlooked the fact that the @exception/@throws for unchecked exceptions would not automatically be inherited by subclasses, and that in fact those subclasses (in this case) should indeed have inherited the same preconditions from the parent. >> >> All subclasses of java.io.Reader are documenting existing behaviour ( such documentation of uncheck exceptions was not the norm when these classes were originally written, but seems reasonable in this case ). But java.io.Reader.read(String,int,int) is abstract, and as such is having additional specification added ( which should be fine ). >> >> The only question is about third party implementations of Reader ( or other non Java SE implementations in the JDK), which may need to be amended to confirm to this ?new? bounds check. Again, I think this should be fine, and seems in line with the evolution policy of core libraries. >> >> -Chris. >> >>> David >>> >>>>> If so, this looks OK assuming you have an approved CCC? The test >>>> seems fine. >>>> >>>> A CCC will be needed, and should be submitted after successful review. >>>> >>>>> I am assuming there should not be any issues here but would be good to >>>>> hear from others on this change as well >>>> >>>> Right. We do this ( clarify spec from existing behavior) in other areas >>>> too. >>>> >>>> Given that this is the current behavior of existing platform subtypes, >>>> then this change is only specifying existing behavior. Since there are >>>> no implementation changes, then Third party Reader subtypes will >>>> continue to function as before, but they may need to be updated at some >>>> point in the future. >>>> >>>> -Chris. >>>> >>>>> Best >>>>> Lance >>>>> On Apr 20, 2015, at 11:10 AM, Pavel Rappo wrote: >>>>> >>>>>> >>>>>> Hi everyone, >>>>>> >>>>>> Could you please review my change for JDK-8029689 >>>>>> >>>>>> http://cr.openjdk.java.net/~prappo/8029689/webrev.00/ >>>>>> >>>>>> ------------------------------------------------------------------------------- >>>>>> >>>>>> There is a long-standing issue when platform implementations of >>>>>> java.io.Reader >>>>>> throw IndexOutOfBoundsException for bounds checks from inherited >>>>>> java.io.Reader.read(char[], int, int) method though java.io.Reader >>>>>> itself does >>>>>> not specify this situation. >>>>>> >>>>>> Suggested solution is to update the contract of >>>>>> java.io.Reader.read(char[], int, >>>>>> int) and its publicly exported descendants to capture the implied >>>>>> preconditions >>>>>> for reading range and the array size. >>>>>> >>>>>> Given that throwing IOBE in this situation is a de facto standard, >>>>>> this change >>>>>> won't bring any kind of incompatibility, though to stay compliant 3rd >>>>>> party >>>>>> implementations may need to be updated. >>>>>> >>>>>> -Pavel >>>>>> >>>>> >>>>> >>>>> >>>>> 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 ivan.gerasimov at oracle.com Fri May 8 14:49:19 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 08 May 2015 17:49:19 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554BBBBA.9050804@cs.oswego.edu> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> Message-ID: <554CCCEF.8060503@oracle.com> Hi Doug! On 07.05.2015 22:23, Doug Lea wrote: > On 05/06/2015 07:23 PM, Martin Buchholz wrote: >> Hi Ivan, >> >> I'm afraid of these changes - they are hard to review. > > > I believe that they also break the AbstractList.subList spec. > http://docs.oracle.com/javase/8/docs/api/java/util/AbstractList.html#subList-int-int- > > The @implSpec section currently says: * The subclass stores, in private fields, the * offset of the subList within the backing list, the size of the subList * (which can change over its lifetime), and the expected * {@code modCount} value of the backing list. With the proposed change, the sublist will still store the same information: offset withing the backing list := this.offset - (parent == null ? 0 : parent.offset), size is stored as before, expected modCount of the backing list is stored as before, but now it is compared with root.modCount. I think that the proposed fix formally conforms to the spec. However, I'm not really sure why all this details have to be listed in the javadoc. Can we just remove them? (with the CCC, of course) > The reason that flattened forms were not used is that each > layer does not in general know the class of its parent. > I'm inclined to create another regression test which will systematically check the behavior of sublists. Even though the changes in the fix are quite straight-forward, it's still better to make sure nothing is broken. > However, flattened forms are used in java.util.ArrayList.SubList. > > It would be possible (and easy) to create a specialization for the > java.util.Arrays.ArrayList class (i.e., the kind returned by > Arrays.asList(a).subList), which would also fix the SOE problem > in this particular case. > Yes. The same can be done for Collections.SingletonList too. If AbstractList had a base class, that implements sublists without tracking down any structural modifications, it could be used as the base class for Arrays.ArrayList and Collections.SingletonList. I think it should better be done as a separate enhancement, though. Sincerely yours, Ivan From felix.yang at oracle.com Fri May 8 14:57:00 2015 From: felix.yang at oracle.com (FELIX YANG) Date: Fri, 08 May 2015 22:57:00 +0800 Subject: RFR JDK-8079778: Mark intermittently failing: java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java Message-ID: <554CCEBC.6080805@oracle.com> Hi all, java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java has been observed to fail intermittently. This fix is to mark it with keyword 'intermittent'. Bug: https://bugs.openjdk.java.net/browse/JDK-8079778 thanks, -Felix diff -r d18205a1ef80 test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java --- a/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java Fri May 08 09:05:15 2015 -0400 +++ b/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java Fri May 08 15:47:53 2015 +0100 @@ -29,6 +29,7 @@ * @library ../../testlibrary * @build TestLibrary RMID ActivationLibrary * @run main/othervm/timeout=240 RmidViaInheritedChannel + * @key intermittent */ import java.io.IOException; From chris.hegarty at oracle.com Fri May 8 15:01:41 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Fri, 08 May 2015 16:01:41 +0100 Subject: RFR JDK-8079778: Mark intermittently failing: java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java In-Reply-To: <554CCEBC.6080805@oracle.com> References: <554CCEBC.6080805@oracle.com> Message-ID: <554CCFD5.8090605@oracle.com> Looks ok to me Felix. -Chris. On 08/05/15 15:57, FELIX YANG wrote: > Hi all, > java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java > has been observed to fail intermittently. This fix is to mark it with > keyword 'intermittent'. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8079778 > > thanks, > -Felix > > diff -r d18205a1ef80 > test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java > > --- > a/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java > Fri May 08 09:05:15 2015 -0400 > +++ > b/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java > Fri May 08 15:47:53 2015 +0100 > @@ -29,6 +29,7 @@ > * @library ../../testlibrary > * @build TestLibrary RMID ActivationLibrary > * @run main/othervm/timeout=240 RmidViaInheritedChannel > + * @key intermittent > */ > > import java.io.IOException; > From ivan.gerasimov at oracle.com Fri May 8 15:02:13 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 08 May 2015 18:02:13 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> Message-ID: <554CCFF5.4050605@oracle.com> On 08.05.2015 1:26, Martin Buchholz wrote: > On Thu, May 7, 2015 at 12:23 PM, Doug Lea
wrote: >> It would be possible (and easy) to create a specialization for the >> java.util.Arrays.ArrayList class (i.e., the kind returned by >> Arrays.asList(a).subList), which would also fix the SOE problem >> in this particular case. > > It seems it would be a fairly clean win to no longer have Arrays.ArrayList > subclass AbstractList, getting rid of modCount (no structural modifications > are possible!), at the cost of more copying. Maybe it could subclass > AbstractCollection instead? > We can introduce an intermediate abstract base class for AbstractList, which will implement a simpler version of sublists. This BaseAbstractList could then be used for implementing Arrays.ArrayList and Collections.SingletonList without paying too much for copying code. I wouldn't include such a change in this fix, however, and would leave if for a separate enhancement. Sincerely yours, Ivan From attila.szegedi at oracle.com Fri May 8 15:25:42 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Fri, 8 May 2015 17:25:42 +0200 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: Message-ID: Well then those would obviously be left out, documenting that it?s the responsibility of the implementor to provide them. This would be true in general for other interfaces as well that have a specification for expected meaning of equals/hashCode. There?s still a lot of boilerplate code that could be saved from repetition, though. > On May 8, 2015, at 12:15 PM, Pavel Rappo wrote: > > >> (I?ll hand-wave the issue of ?protected int modCount? issue for now.) > > Not only. Consider this: java.util.AbstractList overrides some methods from > java.lang.Object such as equals and hashCode. And this is a no-no [1]: > > ...It is a compile-time error if a default method is override-equivalent > with a non-private method of the class Object, because any class > implementing the interface will inherit its own implementation of the > method... > > ------------------------------------------------------------------------------- > [1] https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.4.1.2 From derek.white at oracle.com Wed May 6 21:51:42 2015 From: derek.white at oracle.com (Derek White) Date: Wed, 06 May 2015 17:51:42 -0400 Subject: RFR(M): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5548D65C.8040304@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> Message-ID: <554A8CEE.2090009@oracle.com> Hi Dmitry, Staffan, Lots of good comments here. On the topic of what list should be printed out, I think we should focus on objects waiting to be finalized - e.g. the contents of the ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you could add a summerizeQueue(TreeMap) method, or a general iterator and lambda. A histogram of objects with finalize methods might also be interesting, but you can get most of the same information from a heap histogram (ClassHistogramDCmd, and search for count of Finalizer instances). BTW, by only locking the ReferenceQueue, we should only be blocking the FinalizerThread from making progress (and I think there's a GC thread that runs after GC that sorts found References objects that need processing into their respective ReferenceQueues). But locking the "unfinalized" list blocks initializing any object with a finalize() method. The sorting suggestion is a nice touch. - Derek White, GC team On 5/5/15 10:40 AM, Peter Levart wrote: > Hi Dmitry, Staffan, > > On 05/05/2015 12:38 PM, Staffan Larsen wrote: >> Dmitry, >> >> I think this should be reviewed on hotspot-gc and core-libs-dev as >> well considering the changes to Finalizer. >> >> I?m a little worried about the potentially very large String that is >> returned from printFinalizationQueue(). A possible different approach >> would be to write printFinalizationQueue() in C++ inside Hotspot. >> That would allow for outputting one line at a time. The output would >> still be saved in memory (since the stream is buffered), but at least >> the data is only saved once in memory, then. It would make the code a >> bit harder to write, so its a question of how scared we are of >> running out of memory. > > If the output is just a histogram of # of instances per class name, > then it should not be too large, as there are not many different > classes overriding finalize() method (I counted 72 overriddings of > finalize() method in the whole jdk/src tree). > > I'm more concerned about the fact that while traversing the list, a > lock is held, which might impact prompt finalization(). Is it > acceptable for diagnostic output to impact performance and/or > interfere with synchronization? > > It might be possible to scan the list without holding a lock for > diagnostic purposes if Finalizer.remove() didn't set the removed > Finalizer.next pointer to point back to itself: > > private void remove() { > synchronized (lock) { > if (unfinalized == this) { > if (this.next != null) { > unfinalized = this.next; > } else { > unfinalized = this.prev; > } > } > if (this.next != null) { > this.next.prev = this.prev; > } > if (this.prev != null) { > this.prev.next = this.next; > } > // this.next = this; must not be set so that we can > traverse the list unsynchronized > this.prev = this; /* Indicates that this has been > finalized */ > } > } > > For detecting whether a Finalizer is already processed, the 'prev' > pointer could be used instead: > > private boolean hasBeenFinalized() { > return (prev == this); > } > > Also, to make sure a data race dereferencing 'unfinalized' in > unsynchronized printFinalizationQueue() would get you a fully > initialized Finalizer instance (in particular the next pointer), you > would have to make the 'unfinalized' field volatile or insert an > Unsafe.storeFence() before assigning to 'unfinalized': > > private void add() { > synchronized (lock) { > if (unfinalized != null) { > this.next = unfinalized; > unfinalized.prev = this; > } > // make sure a data race dereferencing 'unfinalized' > // in printFinalizationQueue() does see the Finalizer > // instance fully initialized > // (in particular the 'next' pointer) > U.storeFence(); > unfinalized = this; > } > } > > > By doing these modifications, I think you can remove > synchronized(lock) {} from printFinalizationQueue(). > >> >> I see you are traversing the ?unfinalized? list in Finalizer, whereas >> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >> not sure of the difference, perhaps someone from the GC team can help >> out? > > The 'queue' is a ReferenceQueue of Finalizer (FinalReference) > instances pending processing by finalizer thread because their > referents are eligible for finalization (they are not reachable any > more). The 'unfinalized' is a doubly-linked list of all Finalizer > instances for which their referents have not been finalized yet > (including those that are still reachable and alive). The later serves > two purposes: > - it keeps Finalizer instances reachable until they are processed > - it is a source of unfinalized instances for > running-finalizers-on-exit if requested by > System.runFinalizersOnExit(true); > > So it really depends on what one would like to see. Showing the queue > may be interesting if one wants to see how the finalizer thread is > coping with processing the finalize() invocations. Showing unfinalized > list may be interesting if one wants to know how many live + > finalization pending instances are there on the heap that override > finalize() method. > > Regards, Peter > >> >> For the output, it would be a nice touch to sort it on the number of >> references for each type. Perhaps outputting it more like a table >> (see the old code again) would also make it easier to digest. >> >> In diagnosticCommand.hpp, the new commands should override >> permission() and limit access: >> >> static const JavaPermission permission() { >> JavaPermission p = {"java.lang.management.ManagementPermission", >> "monitor", NULL}; >> return p; >> } >> >> The two tests don?t validate the output in any way. Would it be >> possible to add validation? Perhaps hard to make sure an object is on >> the finalizer queue? Hmm. >> >> Thanks, >> /Staffan >> >> >>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>> wrote: >>> >>> Everyone, >>> >>> Please review the fix: >>> >>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>> >>> heap dcmd outputs the same information as SIGBREAK >>> >>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>> with count >>> >>> -Dmitry >>> >>> -- >>> Dmitry Samersoff >>> Oracle Java development team, Saint Petersburg, Russia >>> * I would love to change the world, but they won't give me the sources. > From dl at cs.oswego.edu Fri May 8 17:10:47 2015 From: dl at cs.oswego.edu (Doug Lea) Date: Fri, 08 May 2015 13:10:47 -0400 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554CCCEF.8060503@oracle.com> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> <554CCCEF.8060503@oracle.com> Message-ID: <554CEE17.50203@cs.oswego.edu> On 05/08/2015 10:49 AM, Ivan Gerasimov wrote: >> I believe that they also break the AbstractList.subList spec. >> http://docs.oracle.com/javase/8/docs/api/java/util/AbstractList.html#subList-int-int- >> > I think that the proposed fix formally conforms to the spec. That would surprise me. The spec says "The returned list is backed by this list" and "The subclass's set(int, E), get(int), add(int, E), remove(int), addAll(int, Collection) and removeRange(int, int) methods all delegate to the corresponding methods on the backing abstract list". It is possible that no differences could be detected, but it would take some effort to prove. > > However, I'm not really sure why all this details have to be listed in the javadoc. > Can we just remove them? (with the CCC, of course) You can't remove specs that subclass implementations were allowed to depend on unless you can prove (not just test) that there are no consequences. (I suppose the CCC might decide otherwise.) > >> The reason that flattened forms were not used is that each >> layer does not in general know the class of its parent. >> > > I'm inclined to create another regression test which will systematically check > the behavior of sublists. How would you do so for arbitrary AbstractList subclasses? >> It would be possible (and easy) to create a specialization for the >> java.util.Arrays.ArrayList class (i.e., the kind returned by >> Arrays.asList(a).subList), which would also fix the SOE problem >> in this particular case. >> > > Yes. The same can be done for Collections.SingletonList too. > If AbstractList had a base class, that implements sublists without tracking down > any structural modifications, it could be used as the base class for > Arrays.ArrayList and Collections.SingletonList. > > I think it should better be done as a separate enhancement, though. > Conservatively, this solution seems OK as the *only* enhancement; it avoids the reported SOE, and has no further unintended consequences. -Doug From vladimir.x.ivanov at oracle.com Fri May 8 17:16:38 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 08 May 2015 20:16:38 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared Message-ID: <554CEF76.8090903@oracle.com> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.01 https://bugs.openjdk.java.net/browse/JDK-8079205 Recent change in sun.misc.Cleaner behavior broke CallSite context cleanup. CallSite references context class through a Cleaner to avoid its unnecessary retention. The problem is the following: to do a cleanup (invalidate all affected nmethods) VM needs a pointer to a context class. Until Cleaner is cleared (and it was a manual action, since Cleaner extends PhantomReference isn't automatically cleared according to the docs), VM can extract it from CallSite.context.referent field. I experimented with moving cleanup logic into VM [1], but Peter Levart came up with a clever idea and implemented FinalReference-based cleaner-like Finalizator. Classes don't have finalizers, but Finalizator allows to attach a finalization action to them. And it is guaranteed that the referent is alive when finalization happens. Also, Peter spotted another problem with Cleaner-based implementation. Cleaner cleanup action is strongly referenced, since it is registered in Cleaner class. CallSite context cleanup action keeps a reference to CallSite class (it is passed to MHN.invalidateDependentNMethods). Users are free to extend CallSite and many do so. If a context class and a call site class are loaded by a custom class loader, such loader will never be unloaded, causing a memory leak. Finalizator doesn't suffer from that, since the action is referenced only from Finalizator instance. The downside is that cleanup action can be missed if Finalizator becomes unreachable. It's not a problem for CallSite context, because a context is always referenced from some CallSite and if a CallSite becomes unreachable, there's no need to perform a cleanup. Testing: jdk/test/java/lang/invoke, hotspot/test/compiler/jsr292 Contributed-by: plevart, vlivanov Best regards, Vladimir Ivanov PS: frankly speaking, I would move Finalizator from java.lang.ref to java.lang.invoke and call it Context, if there were a way to extend package-private FinalReference from another package :-) [1] http://cr.openjdk.java.net/~vlivanov/8079205/webrev.00 From jeremymanson at google.com Fri May 8 17:58:31 2015 From: jeremymanson at google.com (Jeremy Manson) Date: Fri, 8 May 2015 10:58:31 -0700 Subject: RFR: 8079841: Buffer underflow with empty zip entry names Message-ID: There's a fairly harmless buffer underflow with empty zip names in libzip. Martin has offered to sponsor this (right, Martin?). We detected this with ASan, an automatic memory error and leak checking tool built into Clang/LLVM. This is one of the reasons that Alexander Smundak asked if we could backport clang support to JDK8. Bug: https://bugs.openjdk.java.net/browse/JDK-8079841 Webrev: http://cr.openjdk.java.net/~jmanson/8079841/webrev.00/ From ivan.gerasimov at oracle.com Fri May 8 18:17:01 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 08 May 2015 21:17:01 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554CEE17.50203@cs.oswego.edu> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> <554CCCEF.8060503@oracle.com> <554CEE17.50203@cs.oswego.edu> Message-ID: <554CFD9D.9000208@oracle.com> Thank you Doug for your comments! On 08.05.2015 20:10, Doug Lea wrote: > On 05/08/2015 10:49 AM, Ivan Gerasimov wrote: >>> I believe that they also break the AbstractList.subList spec. >>> http://docs.oracle.com/javase/8/docs/api/java/util/AbstractList.html#subList-int-int- >>> >>> > >> I think that the proposed fix formally conforms to the spec. > > That would surprise me. The spec says "The returned list is backed by > this list" > and "The subclass's set(int, E), get(int), add(int, E), remove(int), > addAll(int, Collection) and removeRange(int, int) methods all delegate > to the corresponding methods on the backing abstract list". > > It is possible that no differences could be detected, but it would take > some effort to prove. > Hm. Let me try. We have two options: 1) Sublist of an arbitrary AbstractList, which is not SubList itself. 2) Sublist of another SubList. For the first option the conformance is almost obvious: The AbstractList is referenced as root, and all the methods mentioned above delegate to the corresponding methods of the root. Basically, for this case, all the changes can be though as the field rename (l -> root) and minor code rearrangements. For the second option, the proof can be done by induction. We have a base case (a sublist of the very first level) proven above. Now, suppose we sublist a, whose parent is another sublist (so that a.parent is not null). We want to see that a call to a.add(index, e) will be delegated to a.parent.set(). That's true, because: - it's easy to see that if the check a.rangeCheckForAdd(index) passed, then a.parent.rangeCheckForAdd(index) will pass too, because the allowed range of indices for a is enclosed into the allowed range of indices for a.parent. - it's also easy to see that if the check a.checkForComodification() passed, then a.parent.checkForComodification() will pass too, because it compares a.modCount with the root.modCount, and a.parent.modCount could not be updated without also modifying root.modCount. - calling a.add(index, e) results in a call to root.add(index + a.offset, e). We can think of it as a call to a.parent.add(index + a.parent.offset, e). Thus, taking into account the difference between a.offset and a.parent.offset (which is the index of the sublist a in the list a.parent), we have a clear delegation here from a to a.parent. - updating a.parent.size and a.parent.modCount is done after the call to root.add() comples, in the same way it was done in a recursive call. The same reasoning can be given for all other methods: set(), get(), remove() and so on. As we've done the induction step, we've completed the proof. Didn't I miss something? > >> >> However, I'm not really sure why all this details have to be listed >> in the javadoc. >> Can we just remove them? (with the CCC, of course) > > You can't remove specs that subclass implementations were allowed to > depend on unless you can prove (not just test) that there are no > consequences. (I suppose the CCC might decide otherwise.) > What I meant was that it's not clear how the subclasses of AbstractList can depend on the fact that the SubList class has some *private* fields. >> >>> The reason that flattened forms were not used is that each >>> layer does not in general know the class of its parent. >>> >> >> I'm inclined to create another regression test which will >> systematically check >> the behavior of sublists. > > How would you do so for arbitrary AbstractList subclasses? > An arbitrary AbstractList can either use the default AbstractList.subList() method, or override it. In the first case, all the sublists (and sublists of sublists, and so on) are going to be of type SubList (or RandomAccessSubList). Any operation on a sublist ends up as a call to the corresponding method of the root AbstractList, no matter how the sublists are organized. Thus, we can test their behavior and check if the corresponding methods of the root are called correctly or not. If, on the other hand, the AbstractList.subList() was overridden, the sublists must be of some type independent from our SubList. So, we're not interested in this case. > >>> It would be possible (and easy) to create a specialization for the >>> java.util.Arrays.ArrayList class (i.e., the kind returned by >>> Arrays.asList(a).subList), which would also fix the SOE problem >>> in this particular case. >>> >> >> Yes. The same can be done for Collections.SingletonList too. >> If AbstractList had a base class, that implements sublists without >> tracking down >> any structural modifications, it could be used as the base class for >> Arrays.ArrayList and Collections.SingletonList. >> >> I think it should better be done as a separate enhancement, though. >> > > Conservatively, this solution seems OK as the *only* enhancement; > it avoids the reported SOE, and has no further unintended consequences. > Thanks. I think I'll file an enhancement request for this. However, I'm still hoping to have the fix for the AbstractList/ArrayList approved too. Sincerely yours, Ivan From xueming.shen at oracle.com Fri May 8 18:33:50 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 08 May 2015 11:33:50 -0700 Subject: RFR: 8079841: Buffer underflow with empty zip entry names In-Reply-To: References: Message-ID: <554D018E.7020203@oracle.com> looks good! On 5/8/15 10:58 AM, Jeremy Manson wrote: > There's a fairly harmless buffer underflow with empty zip names in libzip. > Martin has offered to sponsor this (right, Martin?). > > We detected this with ASan, an automatic memory error and leak checking > tool built into Clang/LLVM. This is one of the reasons that Alexander > Smundak asked if we could backport clang support to JDK8. > > Bug: > https://bugs.openjdk.java.net/browse/JDK-8079841 > > Webrev: > http://cr.openjdk.java.net/~jmanson/8079841/webrev.00/ From patrick at reini.net Fri May 8 22:53:25 2015 From: patrick at reini.net (Patrick Reinhart) Date: Sat, 9 May 2015 00:53:25 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Message-ID: Hi Pavel, I have changed the most obvious files and made a patch of each repo. I hope the patches will not be removed? Cheers Patrick -------------- next part -------------- > Am 07.05.2015 um 20:44 schrieb Pavel Rappo : > > Hi Patrick, > > That's a good idea! I can sponsor them no problem. > > -Pavel > >> On 7 May 2015, at 19:13, Patrick Reinhart wrote: >> >> Hi there, >> >> A couple months ago the transferTo() method was added to the JDK. I?m regularly joining the local hacker garten and wanted to ask if it maybe would be a good task to clean up the JDK code to use this method in such a session. Would someone sponsor such changes to be checked in? I would suggest that I would post a diff for each changed class to the core-libs-dev list. >> >> Cheers >> >> Patrick > From patrick at reini.net Fri May 8 23:00:15 2015 From: patrick at reini.net (Patrick Reinhart) Date: Sat, 9 May 2015 01:00:15 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Message-ID: Here the first batch of changes Cheers Patrick > Am 07.05.2015 um 20:44 schrieb Pavel Rappo : > > Hi Patrick, > > That's a good idea! I can sponsor them no problem. > > -Pavel diff -r 7101bcceb43d make/src/classes/build/tools/module/ModuleArchive.java --- a/make/src/classes/build/tools/module/ModuleArchive.java Thu May 07 10:19:34 2015 -0700 +++ b/make/src/classes/build/tools/module/ModuleArchive.java Sat May 09 00:45:32 2015 +0200 @@ -186,7 +186,7 @@ switch (section) { case CLASSES: if (!filename.startsWith("_the.") && !filename.equals("javac_state")) - writeEntry(in); + in.transferTo(out); break; case LIBS: writeEntry(in, destFile(nativeDir(filename), filename)); @@ -218,13 +218,6 @@ Files.copy(in, dstFile); } - private void writeEntry(InputStream in) throws IOException { - byte[] buf = new byte[8192]; - int n; - while ((n = in.read(buf)) > 0) - out.write(buf, 0, n); - } - private static String nativeDir(String filename) { if (System.getProperty("os.name").startsWith("Windows")) { if (filename.endsWith(".dll") || filename.endsWith(".diz") diff -r 7101bcceb43d src/java.base/share/classes/java/nio/file/Files.java --- a/src/java.base/share/classes/java/nio/file/Files.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.base/share/classes/java/nio/file/Files.java Sat May 09 00:45:32 2015 +0200 @@ -2904,22 +2904,6 @@ } /** - * Reads all bytes from an input stream and writes them to an output stream. - */ - private static long copy(InputStream source, OutputStream sink) - throws IOException - { - long nread = 0L; - byte[] buf = new byte[BUFFER_SIZE]; - int n; - while ((n = source.read(buf)) > 0) { - sink.write(buf, 0, n); - nread += n; - } - return nread; - } - - /** * Copies all bytes from an input stream to a file. On return, the input * stream will be at end of stream. * @@ -3031,7 +3015,7 @@ // do the copy try (OutputStream out = ostream) { - return copy(in, out); + return in.transferTo(out); } } @@ -3073,7 +3057,7 @@ Objects.requireNonNull(out); try (InputStream in = newInputStream(source)) { - return copy(in, out); + return in.transferTo(out); } } diff -r 7101bcceb43d src/java.base/share/classes/java/util/jar/JarInputStream.java --- a/src/java.base/share/classes/java/util/jar/JarInputStream.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.base/share/classes/java/util/jar/JarInputStream.java Sat May 09 00:45:32 2015 +0200 @@ -106,12 +106,8 @@ private byte[] getBytes(InputStream is) throws IOException { - byte[] buffer = new byte[8192]; ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); - int n; - while ((n = is.read(buffer, 0, buffer.length)) != -1) { - baos.write(buffer, 0, n); - } + is.transferTo(baos); return baos.toByteArray(); } diff -r 7101bcceb43d src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java --- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Sat May 09 00:45:32 2015 +0200 @@ -829,11 +829,7 @@ target.createDirectory(); } else { try (InputStream is = jrtfs.newInputStream(getResolvedPath()); OutputStream os = target.newOutputStream()) { - byte[] buf = new byte[8192]; - int n; - while ((n = is.read(buf)) != -1) { - os.write(buf, 0, n); - } + is.transferTo(os); } } if (copyAttrs) { diff -r 7101bcceb43d src/java.base/share/classes/sun/net/www/MimeLauncher.java --- a/src/java.base/share/classes/sun/net/www/MimeLauncher.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.base/share/classes/sun/net/www/MimeLauncher.java Sat May 09 00:45:32 2015 +0200 @@ -108,30 +108,20 @@ public void run() { try { + if (is == null) { + return; + } + String ofn = m.getTempFileTemplate(); if (ofn == null) { ofn = genericTempFileTemplate; } ofn = getTempFileName(uc.getURL(), ofn); - try { - OutputStream os = new FileOutputStream(ofn); - byte buf[] = new byte[2048]; - int i = 0; - try { - while ((i = is.read(buf)) >= 0) { - os.write(buf, 0, i); - } - } catch(IOException e) { - //System.err.println("Exception in write loop " + i); - //e.printStackTrace(); - } finally { - os.close(); - is.close(); - } - } catch(IOException e) { - //System.err.println("Exception in input or output stream"); - //e.printStackTrace(); + try (OutputStream os = new FileOutputStream(ofn)) { + is.transferTo(os); + } finally { + is.close(); } int inx = 0; diff -r 7101bcceb43d src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java --- a/src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java Sat May 09 00:45:32 2015 +0200 @@ -256,12 +256,8 @@ * @return the bytes read from the InputStream */ private static byte[] readAllBytes(InputStream is) throws IOException { - byte[] buffer = new byte[8192]; - ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); - int n; - while ((n = is.read(buffer)) != -1) { - baos.write(buffer, 0, n); - } + ByteArrayOutputStream baos = new ByteArrayOutputStream(8192); + is.transferTo(baos); return baos.toByteArray(); } diff -r 7101bcceb43d src/java.base/share/classes/sun/security/tools/keytool/Main.java --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java Sat May 09 00:45:32 2015 +0200 @@ -2194,12 +2194,7 @@ // might not work properly, since -gencrl is slow // and there's no data in the pipe at the beginning. ByteArrayOutputStream bout = new ByteArrayOutputStream(); - byte[] b = new byte[4096]; - while (true) { - int len = in.read(b); - if (len < 0) break; - bout.write(b, 0, len); - } + in.transferTo(bout); return CertificateFactory.getInstance("X509").generateCRLs( new ByteArrayInputStream(bout.toByteArray())); } finally { diff -r 7101bcceb43d src/java.desktop/share/classes/com/sun/media/sound/DLSSoundbank.java --- a/src/java.desktop/share/classes/com/sun/media/sound/DLSSoundbank.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/share/classes/com/sun/media/sound/DLSSoundbank.java Sat May 09 00:45:32 2015 +0200 @@ -984,11 +984,7 @@ RIFFWriter data_chunk = writer.writeChunk("data"); AudioInputStream stream = AudioSystem.getAudioInputStream( audioformat, (AudioInputStream)sample.getData()); - byte[] buff = new byte[1024]; - int ret; - while ((ret = stream.read(buff)) != -1) { - data_chunk.write(buff, 0, ret); - } + stream.transferTo(data_chunk); } else { RIFFWriter data_chunk = writer.writeChunk("data"); ModelByteBuffer databuff = sample.getDataBuffer(); diff -r 7101bcceb43d src/java.desktop/share/classes/com/sun/media/sound/ModelByteBuffer.java --- a/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBuffer.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/share/classes/com/sun/media/sound/ModelByteBuffer.java Sat May 09 00:45:32 2015 +0200 @@ -190,11 +190,7 @@ public void writeTo(OutputStream out) throws IOException { if (root.file != null && root.buffer == null) { - InputStream is = getInputStream(); - byte[] buff = new byte[1024]; - int ret; - while ((ret = is.read(buff)) != -1) - out.write(buff, 0, ret); + getInputStream().transferTo(out); } else out.write(array(), (int) arrayOffset(), (int) capacity()); } diff -r 7101bcceb43d src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java --- a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java Sat May 09 00:45:32 2015 +0200 @@ -125,11 +125,6 @@ } public int write(Sequence in, int type, OutputStream out) throws IOException { - byte [] buffer = null; - - int bytesRead = 0; - long bytesWritten = 0; - if( !isFileTypeSupported(type,in) ) { throw new IllegalArgumentException("Could not write MIDI file"); } @@ -138,14 +133,8 @@ if (fileStream == null) { throw new IllegalArgumentException("Could not write MIDI file"); } - buffer = new byte[bufferSize]; - - while( (bytesRead = fileStream.read( buffer )) >= 0 ) { - out.write( buffer, 0, bytesRead ); - bytesWritten += bytesRead; - } // Done....return bytesWritten - return (int) bytesWritten; + return (int) fileStream.transferTo(out); } public int write(Sequence in, int type, File out) throws IOException { diff -r 7101bcceb43d src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileWriter.java --- a/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileWriter.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileWriter.java Sat May 09 00:45:32 2015 +0200 @@ -66,23 +66,20 @@ public void write(AudioInputStream stream, RIFFWriter writer) throws IOException { - RIFFWriter fmt_chunk = writer.writeChunk("fmt "); + try (RIFFWriter fmt_chunk = writer.writeChunk("fmt ")) { + AudioFormat format = stream.getFormat(); + fmt_chunk.writeUnsignedShort(3); // WAVE_FORMAT_IEEE_FLOAT + fmt_chunk.writeUnsignedShort(format.getChannels()); + fmt_chunk.writeUnsignedInt((int) format.getSampleRate()); + fmt_chunk.writeUnsignedInt(((int) format.getFrameRate()) + * format.getFrameSize()); + fmt_chunk.writeUnsignedShort(format.getFrameSize()); + fmt_chunk.writeUnsignedShort(format.getSampleSizeInBits()); + } - AudioFormat format = stream.getFormat(); - fmt_chunk.writeUnsignedShort(3); // WAVE_FORMAT_IEEE_FLOAT - fmt_chunk.writeUnsignedShort(format.getChannels()); - fmt_chunk.writeUnsignedInt((int) format.getSampleRate()); - fmt_chunk.writeUnsignedInt(((int) format.getFrameRate()) - * format.getFrameSize()); - fmt_chunk.writeUnsignedShort(format.getFrameSize()); - fmt_chunk.writeUnsignedShort(format.getSampleSizeInBits()); - fmt_chunk.close(); - RIFFWriter data_chunk = writer.writeChunk("data"); - byte[] buff = new byte[1024]; - int len; - while ((len = stream.read(buff, 0, buff.length)) != -1) - data_chunk.write(buff, 0, len); - data_chunk.close(); + try (RIFFWriter data_chunk = writer.writeChunk("data")) { + stream.transferTo(data_chunk); + } } private static class NoCloseOutputStream extends OutputStream { diff -r 7101bcceb43d src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java Sat May 09 00:45:32 2015 +0200 @@ -2073,19 +2073,13 @@ if (resource == null) { return null; } - BufferedInputStream in = - new BufferedInputStream(resource); ByteArrayOutputStream out = new ByteArrayOutputStream(1024); - byte[] buffer = new byte[1024]; - int n; - while ((n = in.read(buffer)) > 0) { - out.write(buffer, 0, n); + try (BufferedInputStream in = + new BufferedInputStream(resource)) { + in.transferTo(out); } - in.close(); - out.flush(); - buffer = out.toByteArray(); - return buffer; + return out.toByteArray(); } catch (IOException ioe) { System.err.println(ioe.toString()); return null; diff -r 7101bcceb43d src/java.desktop/share/classes/javax/swing/text/rtf/AbstractFilter.java --- a/src/java.desktop/share/classes/javax/swing/text/rtf/AbstractFilter.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/share/classes/javax/swing/text/rtf/AbstractFilter.java Sat May 09 00:45:32 2015 +0200 @@ -93,18 +93,7 @@ public void readFromStream(InputStream in) throws IOException { - byte buf[]; - int count; - - buf = new byte[16384]; - - while(true) { - count = in.read(buf); - if (count < 0) - break; - - this.write(buf, 0, count); - } + in.transferTo(this); } public void readFromReader(Reader in) diff -r 7101bcceb43d src/java.desktop/share/classes/sun/swing/SwingUtilities2.java --- a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java Sat May 09 00:45:32 2015 +0200 @@ -1568,11 +1568,7 @@ = new BufferedInputStream(resource); ByteArrayOutputStream out = new ByteArrayOutputStream(1024)) { - byte[] buffer = new byte[1024]; - int n; - while ((n = in.read(buffer)) > 0) { - out.write(buffer, 0, n); - } + in.transferTo(out); out.flush(); return out.toByteArray(); } diff -r 7101bcceb43d src/java.desktop/unix/classes/sun/print/UnixPrintJob.java --- a/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java Sat May 09 00:45:32 2015 +0200 @@ -591,18 +591,10 @@ } } } else if (instream != null) { - BufferedInputStream bin = new BufferedInputStream(instream); - BufferedOutputStream bout = new BufferedOutputStream(output); - byte[] buffer = new byte[1024]; - int bread = 0; - - try { - while ((bread = bin.read(buffer)) >= 0) { - bout.write(buffer, 0, bread); - } - bin.close(); + try (BufferedInputStream bin = new BufferedInputStream(instream); + BufferedOutputStream bout = new BufferedOutputStream(output)) { + bin.transferTo(bout); bout.flush(); - bout.close(); } catch (IOException e) { notifyEvent(PrintJobEvent.JOB_FAILED); throw new PrintException (e); diff -r 7101bcceb43d src/java.desktop/windows/classes/sun/print/Win32PrintJob.java --- a/src/java.desktop/windows/classes/sun/print/Win32PrintJob.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.desktop/windows/classes/sun/print/Win32PrintJob.java Sat May 09 00:45:32 2015 +0200 @@ -436,16 +436,9 @@ } if (mDestination != null) { // if destination attribute is set - try { - FileOutputStream fos = new FileOutputStream(mDestination); - byte []buffer = new byte[1024]; - int cread; - - while ((cread = instream.read(buffer, 0, buffer.length)) >=0) { - fos.write(buffer, 0, cread); - } + try (FileOutputStream fos = new FileOutputStream(mDestination)) { + instream.transferTo(fos); fos.flush(); - fos.close(); } catch (FileNotFoundException fnfe) { notifyEvent(PrintJobEvent.JOB_FAILED); throw new PrintException(fnfe.toString()); diff -r 7101bcceb43d src/java.management/share/classes/javax/management/loading/MLet.java --- a/src/java.management/share/classes/javax/management/loading/MLet.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.management/share/classes/javax/management/loading/MLet.java Sat May 09 00:45:32 2015 +0200 @@ -1158,28 +1158,19 @@ InputStream is = getResourceAsStream( libname.replace(File.separatorChar,'/')); if (is != null) { - try { + try (is) { File directory = new File(libraryDirectory); directory.mkdirs(); File file = Files.createTempFile(directory.toPath(), libname + ".", null) .toFile(); file.deleteOnExit(); - FileOutputStream fileOutput = new FileOutputStream(file); - try { - byte[] buf = new byte[4096]; - int n; - while ((n = is.read(buf)) >= 0) { - fileOutput.write(buf, 0, n); - } - } finally { - fileOutput.close(); + try (FileOutputStream fileOutput = new FileOutputStream(file)) { + is.transferTo(fileOutput); } if (file.exists()) { return file.getAbsolutePath(); } - } finally { - is.close(); } } } catch (Exception e) { diff -r 7101bcceb43d src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java Sat May 09 00:45:32 2015 +0200 @@ -59,32 +59,11 @@ */ public static byte[] getBytesFromFile(String fileName) throws FileNotFoundException, IOException { - - byte refBytes[] = null; - - FileInputStream fisRef = null; - UnsyncByteArrayOutputStream baos = null; - try { - fisRef = new FileInputStream(fileName); - baos = new UnsyncByteArrayOutputStream(); - byte buf[] = new byte[1024]; - int len; - - while ((len = fisRef.read(buf)) > 0) { - baos.write(buf, 0, len); - } - - refBytes = baos.toByteArray(); - } finally { - if (baos != null) { - baos.close(); - } - if (fisRef != null) { - fisRef.close(); - } + try (FileInputStream fisRef = new FileInputStream(fileName); + UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream()) { + fisRef.transferTo(baos); + return baos.toByteArray(); } - - return refBytes; } /** @@ -94,30 +73,17 @@ * @param bytes */ public static void writeBytesToFilename(String filename, byte[] bytes) { - FileOutputStream fos = null; - try { - if (filename != null && bytes != null) { - File f = new File(filename); - - fos = new FileOutputStream(f); - + if (filename != null && bytes != null) { + File f = new File(filename); + try (FileOutputStream fos = new FileOutputStream(f)) { fos.write(bytes); - fos.close(); - } else { + } catch (IOException ex) { if (log.isLoggable(java.util.logging.Level.FINE)) { - log.log(java.util.logging.Level.FINE, "writeBytesToFilename got null byte[] pointed"); + log.log(java.util.logging.Level.FINE, ex.getMessage(), ex); } } - } catch (IOException ex) { - if (fos != null) { - try { - fos.close(); - } catch (IOException ioe) { - if (log.isLoggable(java.util.logging.Level.FINE)) { - log.log(java.util.logging.Level.FINE, ioe.getMessage(), ioe); - } - } - } + } else if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, "writeBytesToFilename got null byte[] pointed"); } } @@ -132,22 +98,11 @@ * @throws IOException */ public static byte[] getBytesFromStream(InputStream inputStream) throws IOException { - UnsyncByteArrayOutputStream baos = null; - byte[] retBytes = null; - try { - baos = new UnsyncByteArrayOutputStream(); - byte buf[] = new byte[4 * 1024]; - int len; - - while ((len = inputStream.read(buf)) > 0) { - baos.write(buf, 0, len); - } + try (UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream()) { + inputStream.transferTo(baos); retBytes = baos.toByteArray(); - } finally { - baos.close(); } - return retBytes; } diff -r 7101bcceb43d src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java Sat May 09 00:45:32 2015 +0200 @@ -142,14 +142,7 @@ String mimeType = urlConnection.getHeaderField("Content-Type"); inputStream = urlConnection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte buf[] = new byte[4096]; - int read = 0; - int summarized = 0; - - while ((read = inputStream.read(buf)) >= 0) { - baos.write(buf, 0, read); - summarized += read; - } + long summarized = inputStream.transferTo(baos); if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "Fetched " + summarized + " bytes from URI " + uriNew.toString()); diff -r 7101bcceb43d src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java Thu May 07 10:19:34 2015 -0700 +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java Sat May 09 00:45:32 2015 +0200 @@ -49,17 +49,7 @@ throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buf = new byte[1024]; - while (true) { - int read = is.read(buf); - if (read == -1) { // EOF - break; - } - baos.write(buf, 0, read); - if (read < 1024) { - break; - } - } + is.transferTo(baos); return baos.toByteArray(); } diff -r 7101bcceb43d src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java Thu May 07 10:19:34 2015 -0700 +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java Sat May 09 00:45:32 2015 +0200 @@ -834,20 +834,9 @@ // create directory or file target.createDirectory(); } else { - InputStream is = zfs.newInputStream(getResolvedPath()); - try { - OutputStream os = target.newOutputStream(); - try { - byte[] buf = new byte[8192]; - int n = 0; - while ((n = is.read(buf)) != -1) { - os.write(buf, 0, n); - } - } finally { - os.close(); - } - } finally { - is.close(); + try (InputStream is = zfs.newInputStream(getResolvedPath()); + OutputStream os = target.newOutputStream()) { + is.transferTo(os); } } if (copyAttrs) { From peter.levart at gmail.com Sat May 9 09:33:43 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sat, 09 May 2015 11:33:43 +0200 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <554CEF76.8090903@oracle.com> References: <554CEF76.8090903@oracle.com> Message-ID: <554DD477.7000703@gmail.com> Hi Vladimir, On 05/08/2015 07:16 PM, Vladimir Ivanov wrote: > http://cr.openjdk.java.net/~vlivanov/8079205/webrev.01 > https://bugs.openjdk.java.net/browse/JDK-8079205 Your Finalizator touches are good. Supplier interface is not needed as there is a public Reference superclass that can be used for return type of JavaLangRefAccess.createFinalizator(). You can remove the import for Supplier in Reference now. > > Recent change in sun.misc.Cleaner behavior broke CallSite context > cleanup. > > CallSite references context class through a Cleaner to avoid its > unnecessary retention. > > The problem is the following: to do a cleanup (invalidate all affected > nmethods) VM needs a pointer to a context class. Until Cleaner is > cleared (and it was a manual action, since Cleaner extends > PhantomReference isn't automatically cleared according to the docs), > VM can extract it from CallSite.context.referent field. If PhantomReference.referent wasn't cleared by VM when PhantomReference was equeued, could it happen that the referent pointer was still != null and the referent object's heap memory was already reclaimed by GC? Is that what JDK-8071931 is about? (I cant't see the bug - it's internal). In that respect the Cleaner based solution was broken from the start, as you did dereference the referent after Cleaner was enqueued. You could get a != null pointer which was pointing to reclaimed heap. In Java this dereference is prevented by PhantomReference.get() always returning null (well, nothing prevents one to read the referent field with reflection though). FinalReference(s) are different in that their referent is not reclaimed while it is still reachable through FinalReference, which means that finalizable objects must undergo at least two GC cycles, with processing in the reference handler and finalizer threads inbetween the cycles, to be reclaimed. PhantomReference(s), on the other hand, can be enqueued and their referents reclaimed in the same GC cycle, can't they? > > I experimented with moving cleanup logic into VM [1], What's the downside of that approach? I mean, why is GC-assisted approach better? Simpler? > but Peter Levart came up with a clever idea and implemented > FinalReference-based cleaner-like Finalizator. Classes don't have > finalizers, but Finalizator allows to attach a finalization action to > them. And it is guaranteed that the referent is alive when > finalization happens. > > Also, Peter spotted another problem with Cleaner-based implementation. > Cleaner cleanup action is strongly referenced, since it is registered > in Cleaner class. CallSite context cleanup action keeps a reference to > CallSite class (it is passed to MHN.invalidateDependentNMethods). > Users are free to extend CallSite and many do so. If a context class > and a call site class are loaded by a custom class loader, such loader > will never be unloaded, causing a memory leak. > > Finalizator doesn't suffer from that, since the action is referenced > only from Finalizator instance. The downside is that cleanup action > can be missed if Finalizator becomes unreachable. It's not a problem > for CallSite context, because a context is always referenced from some > CallSite and if a CallSite becomes unreachable, there's no need to > perform a cleanup. > > Testing: jdk/test/java/lang/invoke, hotspot/test/compiler/jsr292 > > Contributed-by: plevart, vlivanov > > Best regards, > Vladimir Ivanov > > PS: frankly speaking, I would move Finalizator from java.lang.ref to > java.lang.invoke and call it Context, if there were a way to extend > package-private FinalReference from another package :-) Modules may have an answer for that. FinalReference could be moved to a package (java.lang.ref.internal or jdk.lang.ref) that is not exported to the world and made public. On the other hand, I don't see a reason why FinalReference couldn't be part of JDK public API. I know it's currently just a private mechanism to implement finalization which has issues and many would like to see it gone, but Java has learned to live with it, and, as you see, it can be a solution to some problems too ;-) Regards, Peter > > [1] http://cr.openjdk.java.net/~vlivanov/8079205/webrev.00 From dl at cs.oswego.edu Sat May 9 11:15:10 2015 From: dl at cs.oswego.edu (Doug Lea) Date: Sat, 09 May 2015 07:15:10 -0400 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554CFD9D.9000208@oracle.com> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> <554CCCEF.8060503@oracle.com> <554CEE17.50203@cs.oswego.edu> <554CFD9D.9000208@oracle.com> Message-ID: <554DEC3E.2060108@cs.oswego.edu> On 05/08/2015 02:17 PM, Ivan Gerasimov wrote: >> The spec says "The returned list is backed by this list" >> and "The subclass's set(int, E), get(int), add(int, E), remove(int), >> addAll(int, Collection) and removeRange(int, int) methods all delegate to the >> corresponding methods on the backing abstract list". >> >> It is possible that no differences could be detected, but it would take >> some effort to prove. >> > > Hm. Let me try. > > We have two options: > 1) Sublist of an arbitrary AbstractList, which is not SubList itself. > 2) Sublist of another SubList. Plus: 3) An arbitrary wrapping of SubList, as seen for example in Collections utilities like synchronizedList: public List subList(int fromIndex, int toIndex) { synchronized (mutex) { return new SynchronizedList<>(list.subList(fromIndex, toIndex), mutex); } } ... which can define methods relying on the specified full cascade. (I'm not trying to be hostile about this; just trying to avoid the usual problems seen when trying to change many Java 1.0-1.2 era classes that over-specified behavior. Luckily, people have learned since then not to do this so much.) -Doug From ivan.gerasimov at oracle.com Sat May 9 14:36:30 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sat, 09 May 2015 17:36:30 +0300 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554DEC3E.2060108@cs.oswego.edu> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> <554CCCEF.8060503@oracle.com> <554CEE17.50203@cs.oswego.edu> <554CFD9D.9000208@oracle.com> <554DEC3E.2060108@cs.oswego.edu> Message-ID: <554E1B6E.1040201@oracle.com> On 09.05.2015 14:15, Doug Lea wrote: > On 05/08/2015 02:17 PM, Ivan Gerasimov wrote: > >>> The spec says "The returned list is backed by this list" >>> and "The subclass's set(int, E), get(int), add(int, E), remove(int), >>> addAll(int, Collection) and removeRange(int, int) methods all >>> delegate to the >>> corresponding methods on the backing abstract list". >>> >>> It is possible that no differences could be detected, but it would take >>> some effort to prove. >>> >> >> Hm. Let me try. >> >> We have two options: >> 1) Sublist of an arbitrary AbstractList, which is not SubList itself. >> 2) Sublist of another SubList. > > Plus: > > 3) An arbitrary wrapping of SubList, as seen for example in Collections > utilities like synchronizedList: > public List subList(int fromIndex, int toIndex) { > synchronized (mutex) { > return new SynchronizedList<>(list.subList(fromIndex, > toIndex), > mutex); > } > } > > ... which can define methods relying on the specified full cascade. > Sorry, I cannot see how wrapping of SubList is different from any other dealing with the sublist's API. Shouldn't it remain as before, as long as we preserve the list's behavior? The consistency of the behavior of the sublist was what I was trying to prove. I've just checked the last webrev at http://cr.openjdk.java.net/~igerasim/8079136/03/webrev/ and I could find only a few minor behavioral differences: - SubList.size() checks for co-modifications more severely (it could easily be restored, but I agree with Pavel that now it's done better); - validity of the index is only checked the for the inner-most sublist (it's surely enough, since the sublist is fully enclosed into its parent); - when updating size and modCount, the sublist chain is traversed in the loop and not recursively (not really a behavioral change, as it hardly be noticed from outside). Another argument, supporting the proposed fix for AbstractList.SubList is that it is very similar to what was implemented in ArrayList.SubList. If the later was conforming to the spec, why are there doubts that the new version AbstractList.SubList break it? Sincerely yours, Ivan > (I'm not trying to be hostile about this; just trying to avoid the > usual problems seen when trying to change many Java 1.0-1.2 era > classes that over-specified behavior. Luckily, people > have learned since then not to do this so much.) > > -Doug > > > From ivan.gerasimov at oracle.com Sat May 9 16:03:43 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sat, 09 May 2015 19:03:43 +0300 Subject: RFR: 8077242: Add default method CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) Message-ID: <554E2FDF.40603@oracle.com> Hi everyone! The String class has getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) which is used to efficiently extract substrings, avoiding unnecessary copying. The AbstractStringBuilder has the method with the same signature. I propose to add a default implementation of this method to the CharSequence interface. It can used, for example, in AbstractStringBuilder.append(CharSequence s, int start, int end) instead of the for-loop. This, in turn, allows to simplify AbstractStringBuilder.append(CharSequence s). In the webrev, I also included a few optimizations of the kind: stringBuilder.append(string.substring(from, to)) => stringBuilder.append(string, from, to). The later variant becomes more effective after the proposed fix. BUGURL: https://bugs.openjdk.java.net/browse/JDK-8077242 WEBREV: http://cr.openjdk.java.net/~igerasim/8077242/00/webrev/ If people agree that this change is useful, I'll file a CCC request. Sincerely yours, Ivan From Alan.Bateman at oracle.com Sat May 9 16:14:06 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sat, 09 May 2015 17:14:06 +0100 Subject: RFR: 8077242: Add default method CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) In-Reply-To: <554E2FDF.40603@oracle.com> References: <554E2FDF.40603@oracle.com> Message-ID: <554E324E.3090205@oracle.com> On 09/05/2015 17:03, Ivan Gerasimov wrote: > Hi everyone! > > The String class has getChars(int srcBegin, int srcEnd, char[] dst, > int dstBegin) which is used to efficiently extract substrings, > avoiding unnecessary copying. This has come up a few times, here's the last thread (and patch) that I could find: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-April/015889.html From ivan.gerasimov at oracle.com Sat May 9 17:07:44 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sat, 09 May 2015 20:07:44 +0300 Subject: RFR: 8077242: Add default method CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) In-Reply-To: <554E324E.3090205@oracle.com> References: <554E2FDF.40603@oracle.com> <554E324E.3090205@oracle.com> Message-ID: <554E3EE0.5020400@oracle.com> Thank you Alan for the pointer! I marked my bug as yet another duplicate of JDK-6813523. It's not clear, why Martin's fix hadn't been pushed then. Martin can you recollect if there were any concerns? Sincerely yours, Ivan On 09.05.2015 19:14, Alan Bateman wrote: > On 09/05/2015 17:03, Ivan Gerasimov wrote: >> Hi everyone! >> >> The String class has getChars(int srcBegin, int srcEnd, char[] dst, >> int dstBegin) which is used to efficiently extract substrings, >> avoiding unnecessary copying. > > This has come up a few times, here's the last thread (and patch) that > I could find: > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-April/015889.html > > > From peter.levart at gmail.com Sat May 9 19:02:54 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sat, 09 May 2015 21:02:54 +0200 Subject: RFR: 8079136: Accessing a nested sublist leads to StackOverflowError In-Reply-To: <554E1B6E.1040201@oracle.com> References: <55486EA5.8000009@oracle.com> <554A2048.6090202@oracle.com> <3A39009A-1211-42C2-B1C2-FFCDE244D4B6@oracle.com> <554A78BB.3090501@oracle.com> <554BBBBA.9050804@cs.oswego.edu> <554CCCEF.8060503@oracle.com> <554CEE17.50203@cs.oswego.edu> <554CFD9D.9000208@oracle.com> <554DEC3E.2060108@cs.oswego.edu> <554E1B6E.1040201@oracle.com> Message-ID: <554E59DE.1080607@gmail.com> Hi, On 05/09/2015 04:36 PM, Ivan Gerasimov wrote: > > > On 09.05.2015 14:15, Doug Lea wrote: >> On 05/08/2015 02:17 PM, Ivan Gerasimov wrote: >> >>>> The spec says "The returned list is backed by this list" >>>> and "The subclass's set(int, E), get(int), add(int, E), remove(int), >>>> addAll(int, Collection) and removeRange(int, int) methods all >>>> delegate to the >>>> corresponding methods on the backing abstract list". >>>> >>>> It is possible that no differences could be detected, but it would >>>> take >>>> some effort to prove. >>>> >>> >>> Hm. Let me try. >>> >>> We have two options: >>> 1) Sublist of an arbitrary AbstractList, which is not SubList itself. >>> 2) Sublist of another SubList. >> >> Plus: >> >> 3) An arbitrary wrapping of SubList, as seen for example in Collections >> utilities like synchronizedList: >> public List subList(int fromIndex, int toIndex) { >> synchronized (mutex) { >> return new SynchronizedList<>(list.subList(fromIndex, >> toIndex), >> mutex); >> } >> } >> >> ... which can define methods relying on the specified full cascade. >> > Sorry, I cannot see how wrapping of SubList is different from any > other dealing with the sublist's API. > Shouldn't it remain as before, as long as we preserve the list's > behavior? I think Ivan is right here and this is safe, because SubList and RandomAccessSubList can not be overridden outside AbstractList. In a chain of sub-lists, there can be runs of consecutive [RandomAccess]SubList(s) intermingled with custom implementations that can not be SubList subclasses: SubList at 1 -> SubList at 2 -> CustomSubListA -> CustomSubListB -> SubList at 3 -> SubList at 4 -> ListImpl It is guaranteed that SubList.root pointers in above scenario will be (see SubList(AbstractList, ...) constructor): SubList at 1.root == CustomSubListA SubList at 2.root == CustomSubListA SubList at 3.root == ListImpl SubList at 4.root == ListImpl In order for a sub-list to be skipped with add,get,... invocations, it has to be a SubList (see SubList(SubList, ...) constructor). And there can be not custom SubList subclasses. So no invocation of any custom method can be skipped. Regards, Peter From martinrb at google.com Sat May 9 22:17:47 2015 From: martinrb at google.com (Martin Buchholz) Date: Sat, 9 May 2015 15:17:47 -0700 Subject: RFR: 8077242: Add default method CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) In-Reply-To: <554E3EE0.5020400@oracle.com> References: <554E2FDF.40603@oracle.com> <554E324E.3090205@oracle.com> <554E3EE0.5020400@oracle.com> Message-ID: On Sat, May 9, 2015 at 10:07 AM, Ivan Gerasimov wrote: > Thank you Alan for the pointer! > > I marked my bug as yet another duplicate of JDK-6813523. > It's not clear, why Martin's fix hadn't been pushed then. > Martin can you recollect if there were any concerns? > It's absolutely true that I dropped the ball on this in jdk8, discouraged by David's message here: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-May/017174.html No one seemed to want to tackle the issue that caling getChars with an evil charsequence could result in the char[] being retained with possible nefarious consequences. David (or others), do you have an opinion on what we *should* do, if anything? Should we be writing ugliferous code of the form if (charSequence.getClass().getClassLoader() == null) /* trusted */ use getChars() (High level: I feel that trying to have untrusted code coexist safely in the same process with trusted code hasn't really worked out for Java) > Sincerely yours, > Ivan > > > On 09.05.2015 19:14, Alan Bateman wrote: > >> On 09/05/2015 17:03, Ivan Gerasimov wrote: >> >>> Hi everyone! >>> >>> The String class has getChars(int srcBegin, int srcEnd, char[] dst, int >>> dstBegin) which is used to efficiently extract substrings, avoiding >>> unnecessary copying. >>> >> >> This has come up a few times, here's the last thread (and patch) that I >> could find: >> >> >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-April/015889.html >> >> >> > From ivan.gerasimov at oracle.com Sat May 9 23:40:49 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sun, 10 May 2015 02:40:49 +0300 Subject: RFR: 8077242: Add default method CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) In-Reply-To: References: <554E2FDF.40603@oracle.com> <554E324E.3090205@oracle.com> <554E3EE0.5020400@oracle.com> Message-ID: <554E9B01.3000504@oracle.com> Thanks Martin for quick reply! On 10.05.2015 1:17, Martin Buchholz wrote: > > Martin can you recollect if there were any concerns? > > > It's absolutely true that I dropped the ball on this in jdk8, > discouraged by David's message here: > http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-May/017174.html Ah, yes. I see the problem. I'm not going to suggest a general solution, but would it make sense to at least create an overloaded method AbstractStringBuilder.append(String str, int start, int end)? Here's a draft webrev for this proposal: BUGURL: https://bugs.openjdk.java.net/browse/JDK-8077242 WEBREV: http://cr.openjdk.java.net/~igerasim/8077242/01/webrev/ Sincerely yours, Ivan From martijnverburg at gmail.com Sun May 10 11:45:43 2015 From: martijnverburg at gmail.com (Martijn Verburg) Date: Sun, 10 May 2015 12:45:43 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Message-ID: Hi Patrick, Have you posted the webrev somewhere for review? Cheers, Martijn On 8 May 2015 at 23:53, Patrick Reinhart wrote: > Hi Pavel, > > I have changed the most obvious files and made a patch of each repo. I > hope the patches will not be removed? > > Cheers > > Patrick > > > > > > Am 07.05.2015 um 20:44 schrieb Pavel Rappo : > > > > Hi Patrick, > > > > That's a good idea! I can sponsor them no problem. > > > > -Pavel > > > >> On 7 May 2015, at 19:13, Patrick Reinhart wrote: > >> > >> Hi there, > >> > >> A couple months ago the transferTo() method was added to the JDK. I?m > regularly joining the local hacker garten and wanted to ask if it maybe > would be a good task to clean up the JDK code to use this method in such a > session. Would someone sponsor such changes to be checked in? I would > suggest that I would post a diff for each changed class to the > core-libs-dev list. > >> > >> Cheers > >> > >> Patrick > > > > > From patrick at reini.net Sun May 10 19:05:10 2015 From: patrick at reini.net (Patrick Reinhart) Date: Sun, 10 May 2015 21:05:10 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Message-ID: Hi Martijn, I posted the patch within the email on the core-libs-dev. I think it?s time to apply for the editor state so I can post it directly to cr.openjdk.java.net ;-) Cheers, Patrick > Am 10.05.2015 um 13:45 schrieb Martijn Verburg : > > Hi Patrick, > > Have you posted the webrev somewhere for review? > > Cheers, > Martijn > > On 8 May 2015 at 23:53, Patrick Reinhart > wrote: > Hi Pavel, > > I have changed the most obvious files and made a patch of each repo. I hope the patches will not be removed? > > Cheers > > Patrick > > > > > > Am 07.05.2015 um 20:44 schrieb Pavel Rappo >: > > > > Hi Patrick, > > > > That's a good idea! I can sponsor them no problem. > > > > -Pavel > > > >> On 7 May 2015, at 19:13, Patrick Reinhart > wrote: > >> > >> Hi there, > >> > >> A couple months ago the transferTo() method was added to the JDK. I?m regularly joining the local hacker garten and wanted to ask if it maybe would be a good task to clean up the JDK code to use this method in such a session. Would someone sponsor such changes to be checked in? I would suggest that I would post a diff for each changed class to the core-libs-dev list. > >> > >> Cheers > >> > >> Patrick > > > > > From chris.hegarty at oracle.com Sun May 10 19:16:47 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Sun, 10 May 2015 20:16:47 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Message-ID: <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> I have not looked at the changes in detail yet, but I think it is going in the right direction. Just a few comments: > On 9 May 2015, at 00:00, Patrick Reinhart wrote: > > diff -r 7101bcceb43d make/src/classes/build/tools/module/ModuleArchive.java > --- a/make/src/classes/build/tools/module/ModuleArchive.java Thu May 07 10:19:34 2015 -0700 > +++ b/make/src/classes/build/tools/module/ModuleArchive.java Sat May 09 00:45:32 2015 +0200 > @@ -186,7 +186,7 @@ > switch (section) { > case CLASSES: > if (!filename.startsWith("_the.") && !filename.equals("javac_state")) > - writeEntry(in); > + in.transferTo(out); > break; > case LIBS: > writeEntry(in, destFile(nativeDir(filename), filename)); > @@ -218,13 +218,6 @@ > Files.copy(in, dstFile); > } > > - private void writeEntry(InputStream in) throws IOException { > - byte[] buf = new byte[8192]; > - int n; > - while ((n = in.read(buf)) > 0) > - out.write(buf, 0, n); > - } > - > private static String nativeDir(String filename) { > if (System.getProperty("os.name").startsWith("Windows")) { > if (filename.endsWith(".dll") || filename.endsWith(".diz?) This is an internal build tool, and compiles with the boot JDK, 8, so cannot use a new 9 API. > diff -r 7101bcceb43d src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java > --- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Thu May 07 10:19:34 2015 -0700 > +++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Sat May 09 00:45:32 2015 +0200 > @@ -829,11 +829,7 @@ > target.createDirectory(); > } else { > try (InputStream is = jrtfs.newInputStream(getResolvedPath()); OutputStream os = target.newOutputStream()) { > - byte[] buf = new byte[8192]; > - int n; > - while ((n = is.read(buf)) != -1) { > - os.write(buf, 0, n); > - } > + is.transferTo(os); > } > } > if (copyAttrs) { The JRT file system needs to be able to run against 8, so should not use a new 9 API. -Chris. From patrick at reini.net Sun May 10 19:28:54 2015 From: patrick at reini.net (Patrick Reinhart) Date: Sun, 10 May 2015 21:28:54 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> Message-ID: <2460B239-BBF8-422C-8815-03D2235C46CD@reini.net> Hi Chris, > Am 10.05.2015 um 21:16 schrieb Chris Hegarty : > > I have not looked at the changes in detail yet, but I think it is going in the right direction. Just a few comments: > >> On 9 May 2015, at 00:00, Patrick Reinhart > wrote: >> >> diff -r 7101bcceb43d make/src/classes/build/tools/module/ModuleArchive.java >> --- a/make/src/classes/build/tools/module/ModuleArchive.java Thu May 07 10:19:34 2015 -0700 >> +++ b/make/src/classes/build/tools/module/ModuleArchive.java Sat May 09 00:45:32 2015 +0200 >> @@ -186,7 +186,7 @@ >> switch (section) { >> case CLASSES: >> if (!filename.startsWith("_the.") && !filename.equals("javac_state")) >> - writeEntry(in); >> + in.transferTo(out); >> break; >> case LIBS: >> writeEntry(in, destFile(nativeDir(filename), filename)); >> @@ -218,13 +218,6 @@ >> Files.copy(in, dstFile); >> } >> >> - private void writeEntry(InputStream in) throws IOException { >> - byte[] buf = new byte[8192]; >> - int n; >> - while ((n = in.read(buf)) > 0) >> - out.write(buf, 0, n); >> - } >> - >> private static String nativeDir(String filename) { >> if (System.getProperty("os.name").startsWith("Windows")) { >> if (filename.endsWith(".dll") || filename.endsWith(".diz?) > > This is an internal build tool, and compiles with the boot JDK, 8, so cannot use a new 9 API. > I see. Seems that when I used a JDK 9 as boot JDK, it worked for me :-) Thanks for the input? >> diff -r 7101bcceb43d src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java >> --- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Thu May 07 10:19:34 2015 -0700 >> +++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Sat May 09 00:45:32 2015 +0200 >> @@ -829,11 +829,7 @@ >> target.createDirectory(); >> } else { >> try (InputStream is = jrtfs.newInputStream(getResolvedPath()); OutputStream os = target.newOutputStream()) { >> - byte[] buf = new byte[8192]; >> - int n; >> - while ((n = is.read(buf)) != -1) { >> - os.write(buf, 0, n); >> - } >> + is.transferTo(os); >> } >> } >> if (copyAttrs) { > > The JRT file system needs to be able to run against 8, so should not use a new 9 API. > Same as above? > -Chris. > From daniel.fuchs at oracle.com Mon May 11 13:52:42 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Mon, 11 May 2015 15:52:42 +0200 Subject: RFR: 8079773: java/util/logging/LogManager/TestLoggerNames.java Message-ID: <5550B42A.8010707@oracle.com> Please find below a fix for: 8079773: java/util/logging/LogManager/TestLoggerNames.java The issue arises from a race condition in the test logic. The test calls LogManager.getLoggerNames(), reset, and adds and remove loggers concurrently - mostly for the purpose of validating that no CME will be thrown. It also attempts to partially validate the logger names enumeration returned by LogManager - but the validation logic left a small opportunity for a race condition to appear (and it did). http://cr.openjdk.java.net/~dfuchs/webrev_8079773/webrev.00/ best regards, -- daniel From aph at redhat.com Mon May 11 14:14:07 2015 From: aph at redhat.com (Andrew Haley) Date: Mon, 11 May 2015 15:14:07 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 Message-ID: <5550B92F.30101@redhat.com> I mixed up my nextPutIndex and nextGetIndex. Sorry. http://cr.openjdk.java.net/~aph/8079459/ This is also the cause of Bug https://bugs.openjdk.java.net/browse/JDK-8079860 Andrew. From Alan.Bateman at oracle.com Mon May 11 15:39:37 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 11 May 2015 16:39:37 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5550B92F.30101@redhat.com> References: <5550B92F.30101@redhat.com> Message-ID: <5550CD39.2010103@oracle.com> On 11/05/2015 15:14, Andrew Haley wrote: > I mixed up my nextPutIndex and nextGetIndex. Sorry. > > http://cr.openjdk.java.net/~aph/8079459/ > > This is also the cause of Bug https://bugs.openjdk.java.net/browse/JDK-8079860 > > This looks good, easy to miss when looking at a big patch. It would be good to extend the test coverage. In this case it was caught by JCK so not an OpenJDK test. -Alan. From Roger.Riggs at Oracle.com Mon May 11 15:49:53 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 11 May 2015 11:49:53 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review Message-ID: <5550CFA1.9010606@Oracle.com> Please review clarifications and updates to the proposed Precess API. A few loose ends in the ProcessHandle API were identified. 1) The ProcessHandle.parent() method currently returns null if the parent cannot be determined and the ProcessHandle.of(PID) method returns null if the PID does not exist. It has been suggested to return an Optional to make these methods more flexible and allow a fluent style and work better with streams. 2) The behavior of Processhandle.destroy and destroyForcibly are different than Process.destroy and destroyForcibly. Those functions always succeed because they are children of the spawning process. In contrast, ProcessHandle.destroy and destroyForcible are requests to destroy the process and may not succeed due to operating system restrictions such as the process not being a child or not having enough privilege. The description of the methods needs to be clarified that it is a request to destroy and it may not succeed, In that case the destroy and destroyForcibly methods should indicate that the request was not successful. In particular, the caller may not want to wait for the process to terminate (its not going to). The proposed update is to return an Optional . It can be streamed and can take advantage of the conditional operations on the Optional. 3) Using Optional is also attractive for the return values of the information about a ProcessHandles, since not all values are available from every OS. The returns values of Info.command, arguments, startInstant, totalDuration, and user are proposed to be updated to return Optional. It allows for more compact code and fewer explicit checks for null. Please review and comment: Webrev: http://cr.openjdk.java.net/~rriggs/webrev-ph/ javadoc: http://cr.openjdk.java.net/~rriggs/ph-apidraft/ Diffs of the spec/javadoc from previous draft: http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-11/overview-summary.html Thanks, Roger From paul.sandoz at oracle.com Mon May 11 16:18:28 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 11 May 2015 18:18:28 +0200 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5550B92F.30101@redhat.com> References: <5550B92F.30101@redhat.com> Message-ID: <21379D2E-620F-4994-B63F-5398C41B8F17@oracle.com> On May 11, 2015, at 4:14 PM, Andrew Haley wrote: > I mixed up my nextPutIndex and nextGetIndex. Sorry. > > http://cr.openjdk.java.net/~aph/8079459/ > > This is also the cause of Bug https://bugs.openjdk.java.net/browse/JDK-8079860 > Oops, i missed this in review. Looks good. Paul. From aph at redhat.com Mon May 11 16:25:34 2015 From: aph at redhat.com (Andrew Haley) Date: Mon, 11 May 2015 17:25:34 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5550CD39.2010103@oracle.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> Message-ID: <5550D7FE.4030903@redhat.com> On 05/11/2015 04:39 PM, Alan Bateman wrote: > On 11/05/2015 15:14, Andrew Haley wrote: >> I mixed up my nextPutIndex and nextGetIndex. Sorry. >> >> http://cr.openjdk.java.net/~aph/8079459/ >> >> This is also the cause of Bug https://bugs.openjdk.java.net/browse/JDK-8079860 >> > This looks good, easy to miss when looking at a big patch. > > It would be good to extend the test coverage. In this case it was caught > by JCK so not an OpenJDK test. Well, that's something of a philosophical issue: should we really duplicate TCK tests in our regression test suite? Also, I must point out that there is an OpenJDK TCK licence available. But I'll do it if you want. Do you want me to do that as part of this bug? Andrew. From brian.burkhalter at oracle.com Mon May 11 16:46:35 2015 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 11 May 2015 09:46:35 -0700 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5550D7FE.4030903@redhat.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> Message-ID: On May 11, 2015, at 9:25 AM, Andrew Haley wrote: >> It would be good to extend the test coverage. In this case it was caught >> by JCK so not an OpenJDK test. > > Well, that's something of a philosophical issue: should we really > duplicate TCK tests in our regression test suite? Also, I must point > out that there is an OpenJDK TCK licence available. One point is that the regression tests are much more tractable to run. Brian From aph at redhat.com Mon May 11 16:49:18 2015 From: aph at redhat.com (Andrew Haley) Date: Mon, 11 May 2015 17:49:18 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> Message-ID: <5550DD8E.6060805@redhat.com> On 05/11/2015 05:46 PM, Brian Burkhalter wrote: > > On May 11, 2015, at 9:25 AM, Andrew Haley wrote: > >>> It would be good to extend the test coverage. In this case it was caught >>> by JCK so not an OpenJDK test. >> >> Well, that's something of a philosophical issue: should we really >> duplicate TCK tests in our regression test suite? Also, I must point >> out that there is an OpenJDK TCK licence available. > > One point is that the regression tests are much more tractable to run. Well, yeah. I have to confess that I did not run the TCK tests for this bug, so you may have a point... Andrew. From brian.burkhalter at oracle.com Mon May 11 16:50:52 2015 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 11 May 2015 09:50:52 -0700 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5550DD8E.6060805@redhat.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> <5550DD8E.6060805@redhat.com> Message-ID: <39803AC2-E845-4B7D-AE56-68EB012328C5@oracle.com> On May 11, 2015, at 9:49 AM, Andrew Haley wrote: >> One point is that the regression tests are much more tractable to run. > > Well, yeah. I have to confess that I did not run the TCK tests for > this bug, so you may have a point... Makes one wonder whether some portion of those tests ought to be moved into the regression test area. No reason SQE could not run them from there. I suppose there are historical reasons for the way things are however. Brian From mandy.chung at oracle.com Mon May 11 19:09:14 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 11 May 2015 12:09:14 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55479A4F.4060806@oracle.com> References: <55479A4F.4060806@oracle.com> Message-ID: <5550FE5A.4070607@oracle.com> Hi Brent, On 05/04/2015 09:11 AM, Brent Christian wrote: > Hi, > > Please review this fix, courtesy of Peter Levart (thanks!), that I > would like to get in. > > https://bugs.openjdk.java.net/browse/JDK-8029891 > http://cr.openjdk.java.net/~bchristi/8029891/webrev.0/ Thanks for taking this on. I haven't seen an updated webrev yet and I reviewed webrev.0 version. Peter is right that the CheckOverrides.java test doesn't need to match the checked exceptions in the method signature to determine if a new method is missing in Properties class to override. If any checked exception is changed in a public/protected Hashtable method, Properties.java should fail the compilation. W.r.t. whether Properties.load* methods should keep the synchronized, the existing behavior of Properties.load* methods update the Properties object with all entries before any other thread calls other write operation (e.g. setProperty or put). As David pointed out, this patch changes the current behavior that the resulting Properties after the load method call might be different if concurrent modification is done by a separate thread. I'm unsure if this incompatibility is a real concern in practice due to the nature concurrency. In order to have predictable result, an application should have their own lock to ensure the Properties entries are updated in the expected order as far as I can see. On the other hand, I'd like Daniel's suggestion to have the load* method to putAll entries in one go after the input reader/stream/xml file is loaded and parsed rather than adding one entry at a time. Taking another look at this deadlock issue and the compatibility concerns, I wonder if we should keep this change as a special implementation for system properties rather than having this change to java.util.Properties class. Properties is a Hashtable which specifies the fast-fail behavior (throwing ConcurrentModificationException for concurrent update). There are other issues specific to system properties we want to clean up (e.g. read-only system property, private system property to JDK but not visible to public etc). Any thought? Mandy From mandy.chung at oracle.com Mon May 11 19:20:09 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 11 May 2015 12:20:09 -0700 Subject: RFR: 8079773: java/util/logging/LogManager/TestLoggerNames.java In-Reply-To: <5550B42A.8010707@oracle.com> References: <5550B42A.8010707@oracle.com> Message-ID: <555100E9.2060805@oracle.com> On 05/11/2015 06:52 AM, Daniel Fuchs wrote: > Please find below a fix for: > > 8079773: java/util/logging/LogManager/TestLoggerNames.java > > The issue arises from a race condition in the test logic. > > The test calls LogManager.getLoggerNames(), reset, and adds > and remove loggers concurrently - mostly for the purpose of > validating that no CME will be thrown. > > It also attempts to partially validate the logger names enumeration > returned by LogManager - but the validation logic left a small > opportunity for a race condition to appear (and it did). > > http://cr.openjdk.java.net/~dfuchs/webrev_8079773/webrev.00/ > Looks okay to me. Mandy From Kristen.O'Leary at gs.com Mon May 11 15:33:18 2015 From: Kristen.O'Leary at gs.com (O'Leary, Kristen) Date: Mon, 11 May 2015 11:33:18 -0400 Subject: Patch to improve primitives Array.sort() In-Reply-To: <553A0832.7070702@oracle.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> Message-ID: <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> Hi Alan, For MAX_RUN_LENGTH, the constant was used to limit the size of a run when the numbers were equal. We treat equal numbers as part of the same run and do not require such a limitation. We have created a consolidated test based upon your feedback and Sunny will work on getting a new revision sent out. Thanks! Kristen -----Original Message----- From: Alan Bateman [mailto:Alan.Bateman at oracle.com] Sent: Friday, April 24, 2015 5:09 AM To: Paul Sandoz; Chan, Sunny [Tech] Cc: 'core-libs-dev at openjdk.java.net'; O'Leary, Kristen [Tech] Subject: Re: Patch to improve primitives Array.sort() On 24/04/2015 09:57, Paul Sandoz wrote: > See here: > > http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev/ > > Some very quick comments as i have not yet had time to review more closely: > > - IANAL so i dunno about the GS copyright in the files. > > - The constant MAX_RUN_LENGTH is no longer used so could be removed. But i would like to understand why it's no longer required. > > - There is quite a bit of duplication in the tests. AFAICT data sources are all derived from ints that are then converted. The sources could be data providers, so only one test method per data type is required, each data can come with a descriptive string so it shows up in the test reports. The goal here being if another source of data is added (which is derivable) it could be added just once. > Also overall with the existing Sorting test should be examined as it tests a lot of cases with varying data sizes (and consequentially runs for a long time). We should also go back through the archives for all the other benchmarks that were created in the move to the dual pivot implementation. -Alan From ivan.gerasimov at oracle.com Mon May 11 20:52:59 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 11 May 2015 23:52:59 +0300 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: <55156FB3.1080006@oracle.com> References: <55156FB3.1080006@oracle.com> Message-ID: <555116AB.3030603@oracle.com> I have to take over this fix. The latest webrev from the review thread above (with a few minor changes) is here: http://cr.openjdk.java.net/~igerasim/8071571/00/webrev/ Would you please review/approve the fix at your convenience? Sincerely yours, Ivan From ivan.gerasimov at oracle.com Mon May 11 21:38:10 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 12 May 2015 00:38:10 +0300 Subject: RFR: 8074657: Missing space on a boundary of concatenated strings Message-ID: <55512142.5050408@oracle.com> Hi all! grep found a few places, where a space is missing. Would you please help review this cleanup fix? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8074657 WEBREV: http://cr.openjdk.java.net/~igerasim/8074657/00/webrev/ Sincerely yours, Ivan From martinrb at google.com Mon May 11 21:55:49 2015 From: martinrb at google.com (Martin Buchholz) Date: Mon, 11 May 2015 14:55:49 -0700 Subject: RFR: 8074657: Missing space on a boundary of concatenated strings In-Reply-To: <55512142.5050408@oracle.com> References: <55512142.5050408@oracle.com> Message-ID: Looks good. (but I might go further and coalesce string constants for readability) On Mon, May 11, 2015 at 2:38 PM, Ivan Gerasimov wrote: > Hi all! > > grep found a few places, where a space is missing. > > Would you please help review this cleanup fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8074657 > WEBREV: http://cr.openjdk.java.net/~igerasim/8074657/00/webrev/ > > Sincerely yours, > Ivan > From joe.darcy at oracle.com Mon May 11 22:58:42 2015 From: joe.darcy at oracle.com (joe darcy) Date: Mon, 11 May 2015 15:58:42 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible Message-ID: <55513422.70902@oracle.com> Hello, Some are of the opinion that the specification for the Documented meta-annotation type could be clarified. JDK-8053918: make the spec for @Documented comprehensible http://cr.openjdk.java.net/~darcy/8053918.0/ Please review the patch below which aims to accomplish this. Thanks, -Joe --- old/src/java.base/share/classes/java/lang/annotation/Documented.java 2015-05-11 15:54:37.273033243 -0700 +++ new/src/java.base/share/classes/java/lang/annotation/Documented.java 2015-05-11 15:54:37.153033240 -0700 @@ -26,12 +26,20 @@ package java.lang.annotation; /** - * Indicates that annotations with a type are to be documented by javadoc - * and similar tools by default. This type should be used to annotate the - * declarations of types whose annotations affect the use of annotated - * elements by their clients. If a type declaration is annotated with - * Documented, its annotations become part of the public API - * of the annotated elements. + * When an annotation type A is annotated with {@code + * Documented}, the presence and value of annotations of type A + * are a part of the public contract of the elements A + * annotates. + * + * Conversely, if an annotation type B is not + * annotated with {@code Documented}, the presence and value of + * Bannotations are not part of the public contract of + * the elements B annotates. + * + * Concretely, if an annotation type is annotated with {@code + * Documented}, by default a tool like javadoc will display + * annotations of that type in its output while annotations of + * annotation types without {@code Documented} will not be displayed. * * @author Joshua Bloch * @since 1.5 From ivan.gerasimov at oracle.com Mon May 11 23:02:20 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 12 May 2015 02:02:20 +0300 Subject: RFR: 8074657: Missing space on a boundary of concatenated strings In-Reply-To: References: <55512142.5050408@oracle.com> Message-ID: <555134FC.1030508@oracle.com> Thanks Martin! Yes, did that. I also fixed indentation in some places and replaced StringBuffer with StringBuilder. Here's the updated webrev: http://cr.openjdk.java.net/~igerasim/8074657/01/webrev/ Sincerely yours, Ivan On 12.05.2015 0:55, Martin Buchholz wrote: > Looks good. > > (but I might go further and coalesce string constants for readability) > > On Mon, May 11, 2015 at 2:38 PM, Ivan Gerasimov > > wrote: > > Hi all! > > grep found a few places, where a space is missing. > > Would you please help review this cleanup fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8074657 > WEBREV: http://cr.openjdk.java.net/~igerasim/8074657/00/webrev/ > > > Sincerely yours, > Ivan > > From joe.darcy at oracle.com Mon May 11 23:16:25 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Mon, 11 May 2015 16:16:25 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible In-Reply-To: <5551362C.9040102@oracle.com> References: <55513422.70902@oracle.com> <5551362C.9040102@oracle.com> Message-ID: <55513849.5000505@oracle.com> How about as a first sentence "The Documented meta-annotation indicates whether or not annotations of the annotation types it annotates are considered part of the public contract of the elements they in turn annotate." (Admittedly still a bit convoluted.) -Joe On 5/11/2015 4:07 PM, Jonathan Gibbons wrote: > Although the original "first sentence" is somewhat hard to parse, at > least there is a single "first sentence" The rewrite doesn't seem to > have such a succint first sentence. > > If I were to change just one word in the original first sentence, I > would change "with" to "on": > > - * Indicates that annotations with a type are to be documented by > javadoc > - * and similar tools by default. > + * Indicates that annotations on a type are to be documented by javadoc > +* and similar tools by default. > > -- Jon > > On 05/11/2015 03:58 PM, joe darcy wrote: >> Hello, >> >> Some are of the opinion that the specification for the Documented >> meta-annotation type could be clarified. >> >> JDK-8053918: make the spec for @Documented comprehensible >> http://cr.openjdk.java.net/~darcy/8053918.0/ >> >> Please review the patch below which aims to accomplish this. >> >> Thanks, >> >> -Joe >> >> --- >> old/src/java.base/share/classes/java/lang/annotation/Documented.java >> 2015-05-11 15:54:37.273033243 -0700 >> +++ >> new/src/java.base/share/classes/java/lang/annotation/Documented.java >> 2015-05-11 15:54:37.153033240 -0700 >> @@ -26,12 +26,20 @@ >> package java.lang.annotation; >> >> /** >> - * Indicates that annotations with a type are to be documented by >> javadoc >> - * and similar tools by default. This type should be used to >> annotate the >> - * declarations of types whose annotations affect the use of annotated >> - * elements by their clients. If a type declaration is annotated with >> - * Documented, its annotations become part of the public API >> - * of the annotated elements. >> + * When an annotation type A is annotated with {@code >> + * Documented}, the presence and value of annotations of type A >> + * are a part of the public contract of the elements A >> + * annotates. >> + * >> + * Conversely, if an annotation type B is not >> + * annotated with {@code Documented}, the presence and value of >> + * Bannotations are not part of the public contract of >> + * the elements B annotates. >> + * >> + * Concretely, if an annotation type is annotated with {@code >> + * Documented}, by default a tool like javadoc will display >> + * annotations of that type in its output while annotations of >> + * annotation types without {@code Documented} will not be displayed. >> * >> * @author Joshua Bloch >> * @since 1.5 >> > From jonathan.gibbons at oracle.com Mon May 11 23:35:46 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 11 May 2015 16:35:46 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible In-Reply-To: <55513849.5000505@oracle.com> References: <55513422.70902@oracle.com> <5551362C.9040102@oracle.com> <55513849.5000505@oracle.com> Message-ID: <55513CD2.3050106@oracle.com> Still a bit convoluted, but the mean time to comprehension is significant less than that of the original. -- Jon On 05/11/2015 04:16 PM, Joseph D. Darcy wrote: > How about as a first sentence > > "The Documented meta-annotation indicates whether or not annotations > of the annotation types it annotates are considered part of the public > contract of the elements they in turn annotate." > > (Admittedly still a bit convoluted.) > > -Joe > > > On 5/11/2015 4:07 PM, Jonathan Gibbons wrote: >> Although the original "first sentence" is somewhat hard to parse, at >> least there is a single "first sentence" The rewrite doesn't seem to >> have such a succint first sentence. >> >> If I were to change just one word in the original first sentence, I >> would change "with" to "on": >> >> - * Indicates that annotations with a type are to be documented by >> javadoc >> - * and similar tools by default. >> + * Indicates that annotations on a type are to be documented by javadoc >> +* and similar tools by default. >> >> -- Jon >> >> On 05/11/2015 03:58 PM, joe darcy wrote: >>> Hello, >>> >>> Some are of the opinion that the specification for the Documented >>> meta-annotation type could be clarified. >>> >>> JDK-8053918: make the spec for @Documented comprehensible >>> http://cr.openjdk.java.net/~darcy/8053918.0/ >>> >>> Please review the patch below which aims to accomplish this. >>> >>> Thanks, >>> >>> -Joe >>> >>> --- >>> old/src/java.base/share/classes/java/lang/annotation/Documented.java >>> 2015-05-11 15:54:37.273033243 -0700 >>> +++ >>> new/src/java.base/share/classes/java/lang/annotation/Documented.java >>> 2015-05-11 15:54:37.153033240 -0700 >>> @@ -26,12 +26,20 @@ >>> package java.lang.annotation; >>> >>> /** >>> - * Indicates that annotations with a type are to be documented by >>> javadoc >>> - * and similar tools by default. This type should be used to >>> annotate the >>> - * declarations of types whose annotations affect the use of annotated >>> - * elements by their clients. If a type declaration is annotated with >>> - * Documented, its annotations become part of the public API >>> - * of the annotated elements. >>> + * When an annotation type A is annotated with {@code >>> + * Documented}, the presence and value of annotations of type A >>> + * are a part of the public contract of the elements A >>> + * annotates. >>> + * >>> + * Conversely, if an annotation type B is not >>> + * annotated with {@code Documented}, the presence and value of >>> + * Bannotations are not part of the public contract of >>> + * the elements B annotates. >>> + * >>> + * Concretely, if an annotation type is annotated with {@code >>> + * Documented}, by default a tool like javadoc will display >>> + * annotations of that type in its output while annotations of >>> + * annotation types without {@code Documented} will not be displayed. >>> * >>> * @author Joshua Bloch >>> * @since 1.5 >>> >> > From brent.christian at oracle.com Mon May 11 23:43:35 2015 From: brent.christian at oracle.com (Brent Christian) Date: Mon, 11 May 2015 16:43:35 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <5550FE5A.4070607@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> Message-ID: <55513EA7.1050700@oracle.com> Hi, Mandy. Thanks for having a look. On 5/11/15 12:09 PM, Mandy Chung wrote: > ~/WORK/8029891/plevartI'd like Daniel's suggestion to have the load* > method to putAll entries in one go after the input reader/stream/xml > file is loaded and parsed rather than adding one entry at a time. I also like the idea. > Taking another look at this deadlock issue and the compatibility > concerns, I wonder if we should keep this change as a special > implementation for system properties rather than having this change to > java.util.Properties class. Properties is a Hashtable which specifies > the fast-fail behavior (throwing ConcurrentModificationException for > concurrent update). There are other issues specific to system > properties we want to clean up (e.g. read-only system property, private > system property to JDK but not visible to public etc). > > Any thought? I like this idea, too. :) One thought: In the current fix, clone() and serialization make use of package-private methods. This could present some difficulties if system properties would use its own Properties subclass that would live outside java.util. -Brent From alex.buckley at oracle.com Mon May 11 23:44:49 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 11 May 2015 16:44:49 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible In-Reply-To: <55513849.5000505@oracle.com> References: <55513422.70902@oracle.com> <5551362C.9040102@oracle.com> <55513849.5000505@oracle.com> Message-ID: <55513EF1.3050602@oracle.com> Option A: If the annotation @Documented is present on the declaration of an annotation type T, then any @T annotation on an element is considered part of the element's public contract. Option B: The annotation type Documented is used to indicate that annotations of a given annotation type (namely, the type meta-annotated with @Documented) are considered part of the public contract of the elements they annotate. On 5/11/2015 4:16 PM, Joseph D. Darcy wrote: > How about as a first sentence > > "The Documented meta-annotation indicates whether or not annotations of > the annotation types it annotates are considered part of the public > contract of the elements they in turn annotate." > > (Admittedly still a bit convoluted.) > > -Joe > > > On 5/11/2015 4:07 PM, Jonathan Gibbons wrote: >> Although the original "first sentence" is somewhat hard to parse, at >> least there is a single "first sentence" The rewrite doesn't seem to >> have such a succint first sentence. >> >> If I were to change just one word in the original first sentence, I >> would change "with" to "on": >> >> - * Indicates that annotations with a type are to be documented by >> javadoc >> - * and similar tools by default. >> + * Indicates that annotations on a type are to be documented by javadoc >> +* and similar tools by default. >> >> -- Jon >> >> On 05/11/2015 03:58 PM, joe darcy wrote: >>> Hello, >>> >>> Some are of the opinion that the specification for the Documented >>> meta-annotation type could be clarified. >>> >>> JDK-8053918: make the spec for @Documented comprehensible >>> http://cr.openjdk.java.net/~darcy/8053918.0/ >>> >>> Please review the patch below which aims to accomplish this. >>> >>> Thanks, >>> >>> -Joe >>> >>> --- >>> old/src/java.base/share/classes/java/lang/annotation/Documented.java >>> 2015-05-11 15:54:37.273033243 -0700 >>> +++ >>> new/src/java.base/share/classes/java/lang/annotation/Documented.java >>> 2015-05-11 15:54:37.153033240 -0700 >>> @@ -26,12 +26,20 @@ >>> package java.lang.annotation; >>> >>> /** >>> - * Indicates that annotations with a type are to be documented by >>> javadoc >>> - * and similar tools by default. This type should be used to >>> annotate the >>> - * declarations of types whose annotations affect the use of annotated >>> - * elements by their clients. If a type declaration is annotated with >>> - * Documented, its annotations become part of the public API >>> - * of the annotated elements. >>> + * When an annotation type A is annotated with {@code >>> + * Documented}, the presence and value of annotations of type A >>> + * are a part of the public contract of the elements A >>> + * annotates. >>> + * >>> + * Conversely, if an annotation type B is not >>> + * annotated with {@code Documented}, the presence and value of >>> + * Bannotations are not part of the public contract of >>> + * the elements B annotates. >>> + * >>> + * Concretely, if an annotation type is annotated with {@code >>> + * Documented}, by default a tool like javadoc will display >>> + * annotations of that type in its output while annotations of >>> + * annotation types without {@code Documented} will not be displayed. >>> * >>> * @author Joshua Bloch >>> * @since 1.5 >>> >> > From mandy.chung at oracle.com Tue May 12 02:39:41 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 11 May 2015 19:39:41 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55513EA7.1050700@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> Message-ID: > On May 11, 2015, at 4:43 PM, Brent Christian wrote: > > Hi, Mandy. Thanks for having a look. > > On 5/11/15 12:09 PM, Mandy Chung wrote: >> ~/WORK/8029891/plevartI'd like Daniel's suggestion to have the load* >> method to putAll entries in one go after the input reader/stream/xml >> file is loaded and parsed rather than adding one entry at a time. > > I also like the idea. > >> Taking another look at this deadlock issue and the compatibility >> concerns, I wonder if we should keep this change as a special >> implementation for system properties rather than having this change to >> java.util.Properties class. Properties is a Hashtable which specifies >> the fast-fail behavior (throwing ConcurrentModificationException for >> concurrent update). There are other issues specific to system >> properties we want to clean up (e.g. read-only system property, private >> system property to JDK but not visible to public etc). >> >> Any thought? > > I like this idea, too. :) > > One thought: > In the current fix, clone() and serialization make use of package-private methods. This could present some difficulties if system properties would use its own Properties subclass that would live outside java.util. It could use the shared secret mechanism sun.misc.SharedSecrets. Mandy From peter.levart at gmail.com Tue May 12 05:41:56 2015 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 12 May 2015 07:41:56 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55513EA7.1050700@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> Message-ID: <555192A4.3080305@gmail.com> On 05/12/2015 01:43 AM, Brent Christian wrote: > Hi, Mandy. Thanks for having a look. > > On 5/11/15 12:09 PM, Mandy Chung wrote: >> ~/WORK/8029891/plevartI'd like Daniel's suggestion to have the load* >> method to putAll entries in one go after the input reader/stream/xml >> file is loaded and parsed rather than adding one entry at a time. > > I also like the idea. > >> Taking another look at this deadlock issue and the compatibility >> concerns, I wonder if we should keep this change as a special >> implementation for system properties rather than having this change to >> java.util.Properties class. Properties is a Hashtable which specifies >> the fast-fail behavior (throwing ConcurrentModificationException for >> concurrent update). There are other issues specific to system >> properties we want to clean up (e.g. read-only system property, private >> system property to JDK but not visible to public etc). >> >> Any thought? > > I like this idea, too. :) > > One thought: > In the current fix, clone() and serialization make use of > package-private methods. This could present some difficulties if > system properties would use its own Properties subclass that would > live outside java.util. > > -Brent Do you have an example where you would like to access/override one of those methods? They are designed to be a private contract between Properties and Hashtable. Regards, Peter From peter.levart at gmail.com Tue May 12 06:41:46 2015 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 12 May 2015 08:41:46 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <555192A4.3080305@gmail.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> Message-ID: <5551A0AA.6050800@gmail.com> On 05/12/2015 07:41 AM, Peter Levart wrote: >>> Taking another look at this deadlock issue and the compatibility >>> concerns, I wonder if we should keep this change as a special >>> implementation for system properties rather than having this change to >>> java.util.Properties class. Properties is a Hashtable which specifies >>> the fast-fail behavior (throwing ConcurrentModificationException for >>> concurrent update). There are other issues specific to system >>> properties we want to clean up (e.g. read-only system property, private >>> system property to JDK but not visible to public etc). >>> >>> Any thought? >> >> I like this idea, too. :) >> >> One thought: >> In the current fix, clone() and serialization make use of >> package-private methods. This could present some difficulties if >> system properties would use its own Properties subclass that would >> live outside java.util. >> >> -Brent > > Do you have an example where you would like to access/override one of > those methods? They are designed to be a private contract between > Properties and Hashtable. > > Regards, Peter Ah, I understand Mandy now. You are talking about using special Properties implementation just for system properties. Unfortunately, this is currently valid code: Properties props = new Properties(); ... System.setProperties(props); ... props.setProperty(key, value); assert System.getProperty(key).equals(value); By current semantics, the props object must be installed as new system properties by reference, so later changes to it must be visible. Here, the class of system properties is chosen by user. But I think it should be pretty safe to make the java.util.Properties object override all Hashtable methods and delegate to internal CMH so that: - all modification methods + all bulk read methods such as (keySet().toArray, values.toArray) are made synchronized again - individual entry read methods (get, containsKey, ...) are not synchronized. This way we get the benefits of non-synchronized read access but the change is hardly observable. In particular since external synchronization on the Properties object makes guarded code atomic like it is now and individual entry read accesses are almost equivalent whether they are synchronized or not and I would be surprised if any code using Properties for the purpose they were designed for worked any differently. Regards, Peter From vladimir.x.ivanov at oracle.com Tue May 12 10:56:04 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 12 May 2015 13:56:04 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <554DD477.7000703@gmail.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> Message-ID: <5551DC44.9060902@oracle.com> Peter, >> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.01 >> https://bugs.openjdk.java.net/browse/JDK-8079205 > > Your Finalizator touches are good. Supplier interface is not needed as > there is a public Reference superclass that can be used for return type > of JavaLangRefAccess.createFinalizator(). You can remove the import for > Supplier in Reference now. Thanks for spotting that. Will do. >> Recent change in sun.misc.Cleaner behavior broke CallSite context >> cleanup. >> >> CallSite references context class through a Cleaner to avoid its >> unnecessary retention. >> >> The problem is the following: to do a cleanup (invalidate all affected >> nmethods) VM needs a pointer to a context class. Until Cleaner is >> cleared (and it was a manual action, since Cleaner extends >> PhantomReference isn't automatically cleared according to the docs), >> VM can extract it from CallSite.context.referent field. > > If PhantomReference.referent wasn't cleared by VM when PhantomReference > was equeued, could it happen that the referent pointer was still != null > and the referent object's heap memory was already reclaimed by GC? Is > that what JDK-8071931 is about? (I cant't see the bug - it's internal). > In that respect the Cleaner based solution was broken from the start, as > you did dereference the referent after Cleaner was enqueued. You could > get a != null pointer which was pointing to reclaimed heap. In Java this > dereference is prevented by PhantomReference.get() always returning null > (well, nothing prevents one to read the referent field with reflection > though). No, the object isn't reclaimed until corresponding reference is != null. When Cleaner wasn't automatically cleared, it was guaranteed that the referent is alive when cleanup action happens. That is the assumption CallSite dependency tracking is based on. It's not the case anymore when Cleaner is automatically cleared. Cleanup action can happen when context Class is already GCed. So, I can access neither the context mirror class nor VM-internal InstanceKlass. > FinalReference(s) are different in that their referent is not reclaimed > while it is still reachable through FinalReference, which means that > finalizable objects must undergo at least two GC cycles, with processing > in the reference handler and finalizer threads inbetween the cycles, to > be reclaimed. PhantomReference(s), on the other hand, can be enqueued > and their referents reclaimed in the same GC cycle, can't they? Since PhantomReference isn't automatically cleared, GC can't reclaim its referent until the reference is manually cleared or PhantomReference becomes unreachable as a result of cleanup action. So, it's impossible to reclaim it in the same GC cycle (unless it is a concurrent GC cycle?). >> I experimented with moving cleanup logic into VM [1], > > What's the downside of that approach? I mean, why is GC-assisted > approach better? Simpler? IMO the more code on JDK side the better. More safety guarantees are provided in Java code comparing to native/VM code. Also, JVM-based approach suffers from the fact it doesn't get prompt notification when context Class can be GCed. Since it should work with autocleared references, there's no need in a cleanup action anymore. By the time cleanup happens, referent can be already GCed. That's why I switched from Cleaner to WeakReference. When CallSite.context is cleared ("stale" context), VM has to scan all nmethods in the code cache to find all affected nmethods. BTW I had a private discussion with Kim Barrett who suggested an alternative approach which doesn't require full code cache scan. I plan to do some prototyping to understand its feasibility, since it requires non-InstanceKlass-based nmethod dependency tracking machinery. Best regards, Vladimir Ivanov >> but Peter Levart came up with a clever idea and implemented >> FinalReference-based cleaner-like Finalizator. Classes don't have >> finalizers, but Finalizator allows to attach a finalization action to >> them. And it is guaranteed that the referent is alive when >> finalization happens. >> >> Also, Peter spotted another problem with Cleaner-based implementation. >> Cleaner cleanup action is strongly referenced, since it is registered >> in Cleaner class. CallSite context cleanup action keeps a reference to >> CallSite class (it is passed to MHN.invalidateDependentNMethods). >> Users are free to extend CallSite and many do so. If a context class >> and a call site class are loaded by a custom class loader, such loader >> will never be unloaded, causing a memory leak. >> >> Finalizator doesn't suffer from that, since the action is referenced >> only from Finalizator instance. The downside is that cleanup action >> can be missed if Finalizator becomes unreachable. It's not a problem >> for CallSite context, because a context is always referenced from some >> CallSite and if a CallSite becomes unreachable, there's no need to >> perform a cleanup. >> >> Testing: jdk/test/java/lang/invoke, hotspot/test/compiler/jsr292 >> >> Contributed-by: plevart, vlivanov >> >> Best regards, >> Vladimir Ivanov >> >> PS: frankly speaking, I would move Finalizator from java.lang.ref to >> java.lang.invoke and call it Context, if there were a way to extend >> package-private FinalReference from another package :-) > > Modules may have an answer for that. FinalReference could be moved to a > package (java.lang.ref.internal or jdk.lang.ref) that is not exported to > the world and made public. > > On the other hand, I don't see a reason why FinalReference couldn't be > part of JDK public API. I know it's currently just a private mechanism > to implement finalization which has issues and many would like to see it > gone, but Java has learned to live with it, and, as you see, it can be a > solution to some problems too ;-) > > Regards, Peter > >> >> [1] http://cr.openjdk.java.net/~vlivanov/8079205/webrev.00 > From doanduyhai at gmail.com Tue May 12 13:18:47 2015 From: doanduyhai at gmail.com (DuyHai Doan) Date: Tue, 12 May 2015 15:18:47 +0200 Subject: [Annotation Processor] Accessing type annotations on VariableElement at compile time Message-ID: Hello I've tried to play with the new JSR 308 feature (type annotations) and I'm facing a rather annoying limitation: Suppose a class: public static class SimpleEntityCodecFactoryTest { private Map<@JSON Integer,Map<@Frozen Integer, at Enumerated(value = Enumerated.Encoding.NAME, test = "123") String>> map; } What I need is to access all annotations set on type parameters as well as their attribute values. Right now the only way I find so far is to cast the VariableElement to "Symbol.VarSymbol" and then access the internal api getMetadata(). It works but it is far from being developer-friendly. More details here: https://gist.github.com/doanduyhai/b11f9cd843f9be557382 I've tried with declareType.getTypeArguments().get(0).getAnnotationMirrors() but the returned list is empty. Note: I'm using JDK 1.8.0_45. I also tried 1.8.0_u60 but same result ... Am I missing something or is it really a bug in the javax.lang.model package ? Thanks From dmitry.samersoff at oracle.com Tue May 12 17:10:48 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Tue, 12 May 2015 20:10:48 +0300 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <554A8CEE.2090009@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> Message-ID: <55523418.5010708@oracle.com> Everybody, Updated version: http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ Now it iterates over queue and output result sorted by number of instances. -Dmitry On 2015-05-07 00:51, Derek White wrote: > Hi Dmitry, Staffan, > > Lots of good comments here. > > On the topic of what list should be printed out, I think we should focus > on objects waiting to be finalized - e.g. the contents of the > ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you > could add a summerizeQueue(TreeMap) method, or a > general iterator and lambda. > > A histogram of objects with finalize methods might also be interesting, > but you can get most of the same information from a heap histogram > (ClassHistogramDCmd, and search for count of Finalizer instances). > > BTW, by only locking the ReferenceQueue, we should only be blocking the > FinalizerThread from making progress (and I think there's a GC thread > that runs after GC that sorts found References objects that need > processing into their respective ReferenceQueues). But locking the > "unfinalized" list blocks initializing any object with a finalize() method. > > The sorting suggestion is a nice touch. > > - Derek White, GC team > > On 5/5/15 10:40 AM, Peter Levart wrote: >> Hi Dmitry, Staffan, >> >> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>> Dmitry, >>> >>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>> well considering the changes to Finalizer. >>> >>> I?m a little worried about the potentially very large String that is >>> returned from printFinalizationQueue(). A possible different approach >>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>> That would allow for outputting one line at a time. The output would >>> still be saved in memory (since the stream is buffered), but at least >>> the data is only saved once in memory, then. It would make the code a >>> bit harder to write, so its a question of how scared we are of >>> running out of memory. >> >> If the output is just a histogram of # of instances per class name, >> then it should not be too large, as there are not many different >> classes overriding finalize() method (I counted 72 overriddings of >> finalize() method in the whole jdk/src tree). >> >> I'm more concerned about the fact that while traversing the list, a >> lock is held, which might impact prompt finalization(). Is it >> acceptable for diagnostic output to impact performance and/or >> interfere with synchronization? >> >> It might be possible to scan the list without holding a lock for >> diagnostic purposes if Finalizer.remove() didn't set the removed >> Finalizer.next pointer to point back to itself: >> >> private void remove() { >> synchronized (lock) { >> if (unfinalized == this) { >> if (this.next != null) { >> unfinalized = this.next; >> } else { >> unfinalized = this.prev; >> } >> } >> if (this.next != null) { >> this.next.prev = this.prev; >> } >> if (this.prev != null) { >> this.prev.next = this.next; >> } >> // this.next = this; must not be set so that we can >> traverse the list unsynchronized >> this.prev = this; /* Indicates that this has been >> finalized */ >> } >> } >> >> For detecting whether a Finalizer is already processed, the 'prev' >> pointer could be used instead: >> >> private boolean hasBeenFinalized() { >> return (prev == this); >> } >> >> Also, to make sure a data race dereferencing 'unfinalized' in >> unsynchronized printFinalizationQueue() would get you a fully >> initialized Finalizer instance (in particular the next pointer), you >> would have to make the 'unfinalized' field volatile or insert an >> Unsafe.storeFence() before assigning to 'unfinalized': >> >> private void add() { >> synchronized (lock) { >> if (unfinalized != null) { >> this.next = unfinalized; >> unfinalized.prev = this; >> } >> // make sure a data race dereferencing 'unfinalized' >> // in printFinalizationQueue() does see the Finalizer >> // instance fully initialized >> // (in particular the 'next' pointer) >> U.storeFence(); >> unfinalized = this; >> } >> } >> >> >> By doing these modifications, I think you can remove >> synchronized(lock) {} from printFinalizationQueue(). >> >>> >>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>> not sure of the difference, perhaps someone from the GC team can help >>> out? >> >> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >> instances pending processing by finalizer thread because their >> referents are eligible for finalization (they are not reachable any >> more). The 'unfinalized' is a doubly-linked list of all Finalizer >> instances for which their referents have not been finalized yet >> (including those that are still reachable and alive). The later serves >> two purposes: >> - it keeps Finalizer instances reachable until they are processed >> - it is a source of unfinalized instances for >> running-finalizers-on-exit if requested by >> System.runFinalizersOnExit(true); >> >> So it really depends on what one would like to see. Showing the queue >> may be interesting if one wants to see how the finalizer thread is >> coping with processing the finalize() invocations. Showing unfinalized >> list may be interesting if one wants to know how many live + >> finalization pending instances are there on the heap that override >> finalize() method. >> >> Regards, Peter >> >>> >>> For the output, it would be a nice touch to sort it on the number of >>> references for each type. Perhaps outputting it more like a table >>> (see the old code again) would also make it easier to digest. >>> >>> In diagnosticCommand.hpp, the new commands should override >>> permission() and limit access: >>> >>> static const JavaPermission permission() { >>> JavaPermission p = {"java.lang.management.ManagementPermission", >>> "monitor", NULL}; >>> return p; >>> } >>> >>> The two tests don?t validate the output in any way. Would it be >>> possible to add validation? Perhaps hard to make sure an object is on >>> the finalizer queue? Hmm. >>> >>> Thanks, >>> /Staffan >>> >>> >>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>> wrote: >>>> >>>> Everyone, >>>> >>>> Please review the fix: >>>> >>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>> >>>> heap dcmd outputs the same information as SIGBREAK >>>> >>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>> with count >>>> >>>> -Dmitry >>>> >>>> -- >>>> Dmitry Samersoff >>>> Oracle Java development team, Saint Petersburg, Russia >>>> * I would love to change the world, but they won't give me the sources. >> > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From martinrb at google.com Tue May 12 17:34:08 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 12 May 2015 10:34:08 -0700 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: <555116AB.3030603@oracle.com> References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> Message-ID: Hi Ivan, The code below looks wrong to me - sb.length() resolves to sb.count, not v2.length. If I'm correct, then there's a missing test to be added, since this error should be caught by some test. private boolean nonSyncContentEquals(AbstractStringBuilder sb) { - char v1[] = value; - char v2[] = sb.getValue(); + char[] v1 = value; + char[] v2 = sb.getValue(); int n = v1.length; - if (n != sb.length()) { + if (n != v2.length) { return false; } On Mon, May 11, 2015 at 1:52 PM, Ivan Gerasimov wrote: > I have to take over this fix. > > The latest webrev from the review thread above (with a few minor changes) > is here: > http://cr.openjdk.java.net/~igerasim/8071571/00/webrev/ > > Would you please review/approve the fix at your convenience? > > Sincerely yours, > Ivan > > From martinrb at google.com Tue May 12 18:12:58 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 12 May 2015 11:12:58 -0700 Subject: RFR: 8074657: Missing space on a boundary of concatenated strings In-Reply-To: <555134FC.1030508@oracle.com> References: <55512142.5050408@oracle.com> <555134FC.1030508@oracle.com> Message-ID: Your updated webrev http://cr.openjdk.java.net/~igerasim/8074657/02/webrev/jdk.changeset Looks Good To Me! On Mon, May 11, 2015 at 4:02 PM, Ivan Gerasimov wrote: > Thanks Martin! > > Yes, did that. > I also fixed indentation in some places and replaced StringBuffer with > StringBuilder. > > Here's the updated webrev: > http://cr.openjdk.java.net/~igerasim/8074657/01/webrev/ > > Sincerely yours, > Ivan > > > On 12.05.2015 0:55, Martin Buchholz wrote: > > Looks good. > > (but I might go further and coalesce string constants for readability) > > On Mon, May 11, 2015 at 2:38 PM, Ivan Gerasimov > wrote: > >> Hi all! >> >> grep found a few places, where a space is missing. >> >> Would you please help review this cleanup fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8074657 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8074657/00/webrev/ >> >> Sincerely yours, >> Ivan >> > > > From Roger.Riggs at Oracle.com Tue May 12 18:32:28 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 12 May 2015 14:32:28 -0400 Subject: RFR: 8074657: Missing space on a boundary of concatenated strings In-Reply-To: <555134FC.1030508@oracle.com> References: <55512142.5050408@oracle.com> <555134FC.1030508@oracle.com> Message-ID: <5552473C.10305@Oracle.com> Hi Ivan, Perhaps the bug description should be updated. The original changes the bug identifies are lost in the collateral updates. Roger On 5/11/2015 7:02 PM, Ivan Gerasimov wrote: > Thanks Martin! > > Yes, did that. > I also fixed indentation in some places and replaced StringBuffer with > StringBuilder. > > Here's the updated webrev: > http://cr.openjdk.java.net/~igerasim/8074657/01/webrev/ > > Sincerely yours, > Ivan > > On 12.05.2015 0:55, Martin Buchholz wrote: >> Looks good. >> >> (but I might go further and coalesce string constants for readability) >> >> On Mon, May 11, 2015 at 2:38 PM, Ivan Gerasimov >> > wrote: >> >> Hi all! >> >> grep found a few places, where a space is missing. >> >> Would you please help review this cleanup fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8074657 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8074657/00/webrev/ >> >> >> Sincerely yours, >> Ivan >> >> > From martinrb at google.com Tue May 12 18:47:16 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 12 May 2015 11:47:16 -0700 Subject: RFR: 8074657: Missing space on a boundary of concatenated strings In-Reply-To: <5552473C.10305@Oracle.com> References: <55512142.5050408@oracle.com> <555134FC.1030508@oracle.com> <5552473C.10305@Oracle.com> Message-ID: On Tue, May 12, 2015 at 11:32 AM, Roger Riggs wrote: > The original changes the bug identifies are lost in the collateral updates. > Roger is correct that user-invisible changes are mixed with user-visible ones. In a perfect world with low-friction commits, we would have whitespace-only cleanups separated into their own hg changesets. But every openjdk changeset requires a bug id, so we have no such thing as a truly low-friction commit. From ivan.gerasimov at oracle.com Tue May 12 18:58:44 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 12 May 2015 21:58:44 +0300 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> Message-ID: <55524D64.5080808@oracle.com> On 12.05.2015 20:34, Martin Buchholz wrote: > Hi Ivan, > > The code below looks wrong to me - sb.length() resolves to sb.count, > not v2.length. > If I'm correct, then there's a missing test to be added, since this > error should be caught by some test. > private boolean nonSyncContentEquals(AbstractStringBuilder sb) { > - char v1[] = value; > - char v2[] = sb.getValue(); > + char[] v1 = value; > + char[] v2 = sb.getValue(); > int n = v1.length; > - if (n != sb.length()) { > + if (n != v2.length) { > return false; > } > Yes, of course you're right. This change looked so "obviously correct" to me, that I didn't care to run the tests before posting the webrev :-( I've reverted this change back: http://cr.openjdk.java.net/~igerasim/8071571/01/webrev/ Sincerely yours, Ivan > > On Mon, May 11, 2015 at 1:52 PM, Ivan Gerasimov > > wrote: > > I have to take over this fix. > > The latest webrev from the review thread above (with a few minor > changes) is here: > http://cr.openjdk.java.net/~igerasim/8071571/00/webrev/ > > > Would you please review/approve the fix at your convenience? > > Sincerely yours, > Ivan > > From ivan.gerasimov at oracle.com Tue May 12 19:18:10 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 12 May 2015 22:18:10 +0300 Subject: RFR: 8074657: Missing space on a boundary of concatenated strings In-Reply-To: <5552473C.10305@Oracle.com> References: <55512142.5050408@oracle.com> <555134FC.1030508@oracle.com> <5552473C.10305@Oracle.com> Message-ID: <555251F2.9050307@oracle.com> Hi Roger. On 12.05.2015 21:32, Roger Riggs wrote: > Hi Ivan, > > Perhaps the bug description should be updated. > The original changes the bug identifies are lost in the collateral > updates. > Adding the spaces to the strings are the only changes here noticeable from outside. What if we keep the synopsis, but also add the summary mentioning other cleanup work? 8074657: Missing space on a boundary of concatenated strings Summary: Added missing spaces, fixed indentation, replaced StringBuffer with StringBuilder Sincerely yours, Ivan > Roger > > > On 5/11/2015 7:02 PM, Ivan Gerasimov wrote: >> Thanks Martin! >> >> Yes, did that. >> I also fixed indentation in some places and replaced StringBuffer >> with StringBuilder. >> >> Here's the updated webrev: >> http://cr.openjdk.java.net/~igerasim/8074657/01/webrev/ >> >> Sincerely yours, >> Ivan >> >> On 12.05.2015 0:55, Martin Buchholz wrote: >>> Looks good. >>> >>> (but I might go further and coalesce string constants for readability) >>> >>> On Mon, May 11, 2015 at 2:38 PM, Ivan Gerasimov >>> > wrote: >>> >>> Hi all! >>> >>> grep found a few places, where a space is missing. >>> >>> Would you please help review this cleanup fix? >>> >>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8074657 >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8074657/00/webrev/ >>> >>> >>> Sincerely yours, >>> Ivan >>> >>> >> > > > From Roger.Riggs at Oracle.com Tue May 12 19:42:29 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 12 May 2015 15:42:29 -0400 Subject: RFR: 8074657: Missing space on a boundary of concatenated strings In-Reply-To: <555251F2.9050307@oracle.com> References: <55512142.5050408@oracle.com> <555134FC.1030508@oracle.com> <5552473C.10305@Oracle.com> <555251F2.9050307@oracle.com> Message-ID: <555257A5.9060001@Oracle.com> Sounds good, to make note of the style cleanup. I suppose if this were backported to JDK 8 the source cleanup would not be an issue. Thanks, Roger On 5/12/2015 3:18 PM, Ivan Gerasimov wrote: > Hi Roger. > > On 12.05.2015 21:32, Roger Riggs wrote: >> Hi Ivan, >> >> Perhaps the bug description should be updated. >> The original changes the bug identifies are lost in the collateral >> updates. >> > Adding the spaces to the strings are the only changes here noticeable > from outside. > What if we keep the synopsis, but also add the summary mentioning > other cleanup work? > > 8074657: Missing space on a boundary of concatenated strings > Summary: Added missing spaces, fixed indentation, replaced > StringBuffer with StringBuilder > > Sincerely yours, > Ivan > >> Roger >> >> >> On 5/11/2015 7:02 PM, Ivan Gerasimov wrote: >>> Thanks Martin! >>> >>> Yes, did that. >>> I also fixed indentation in some places and replaced StringBuffer >>> with StringBuilder. >>> >>> Here's the updated webrev: >>> http://cr.openjdk.java.net/~igerasim/8074657/01/webrev/ >>> >>> Sincerely yours, >>> Ivan >>> >>> On 12.05.2015 0:55, Martin Buchholz wrote: >>>> Looks good. >>>> >>>> (but I might go further and coalesce string constants for readability) >>>> >>>> On Mon, May 11, 2015 at 2:38 PM, Ivan Gerasimov >>>> > wrote: >>>> >>>> Hi all! >>>> >>>> grep found a few places, where a space is missing. >>>> >>>> Would you please help review this cleanup fix? >>>> >>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8074657 >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8074657/00/webrev/ >>>> >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>> >>> >> >> >> > From mandy.chung at oracle.com Tue May 12 20:49:18 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 12 May 2015 13:49:18 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <5551A0AA.6050800@gmail.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> Message-ID: <5552674E.4030009@oracle.com> On 05/11/2015 11:41 PM, Peter Levart wrote: > > > On 05/12/2015 07:41 AM, Peter Levart wrote: >>>> Taking another look at this deadlock issue and the compatibility >>>> concerns, I wonder if we should keep this change as a special >>>> implementation for system properties rather than having this change to >>>> java.util.Properties class. Properties is a Hashtable which specifies >>>> the fast-fail behavior (throwing ConcurrentModificationException for >>>> concurrent update). There are other issues specific to system >>>> properties we want to clean up (e.g. read-only system property, >>>> private >>>> system property to JDK but not visible to public etc). >>>> >>>> Any thought? >>> >>> I like this idea, too. :) >>> >>> One thought: >>> In the current fix, clone() and serialization make use of >>> package-private methods. This could present some difficulties if >>> system properties would use its own Properties subclass that would >>> live outside java.util. >>> >>> -Brent >> >> Do you have an example where you would like to access/override one of >> those methods? They are designed to be a private contract between >> Properties and Hashtable. >> >> Regards, Peter > > Ah, I understand Mandy now. You are talking about using special > Properties implementation just for system properties. Unfortunately, > this is currently valid code: > > Properties props = new Properties(); > ... > System.setProperties(props); > ... > props.setProperty(key, value); > assert System.getProperty(key).equals(value); > How likely does existing code do this? A proper way is to call System.setProperty. One pattern I found on System.setProperties is like this to add a system property of key/value pair: Properties props = System.getProperties(); props.put(key, value); System.setProperties(props); More investigation needs to be done (e.g. look at System.setProperties and other system property related APIs and any spec change is needed to be made and the compatibility implication) if we agree that it worths keeping this change local to system properties. > By current semantics, the props object must be installed as new system > properties by reference, so later changes to it must be visible. Here, > the class of system properties is chosen by user. > Perhaps the spec of System.setProperties should be changed (I don't have cycle to think through this). > But I think it should be pretty safe to make the java.util.Properties > object override all Hashtable methods and delegate to internal CMH so > that: > - all modification methods + all bulk read methods such as > (keySet().toArray, values.toArray) are made synchronized again > - individual entry read methods (get, containsKey, ...) are not > synchronized. > > This way we get the benefits of non-synchronized read access but the > change is hardly observable. In particular since external > synchronization on the Properties object makes guarded code atomic > like it is now and individual entry read accesses are almost > equivalent whether they are synchronized or not and I would be > surprised if any code using Properties for the purpose they were > designed for worked any differently. I agree that making read-only methods not synchronized while keeping any method with write-access with synchronized is pretty safe change and low compatibility risk. On the other hand, would most of the overrridden methods be synchronized then? Mandy From martinrb at google.com Tue May 12 21:22:00 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 12 May 2015 14:22:00 -0700 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: <55524D64.5080808@oracle.com> References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> Message-ID: All your changes look good. But: --- Not your bug, but it looks like the below should instead be: throw new StringIndexOutOfBoundsException(beginIndex); Perhaps fix in a follow-on change. 1935 if (subLen < 0) { 1936 throw new StringIndexOutOfBoundsException(subLen); --- We seem to have clean progress, but for substring fast-path we can do a little better, I think, thus: public String substring(int beginIndex, int endIndex) { int subLen; return ((beginIndex | (value.length - endIndex)) > 0 && (subLen = endIndex - beginIndex) > 0) ? new String(value, beginIndex, subLen) : substringSlowPath(beginIndex, endIndex); } private String substringSlowPath(int beginIndex, int endIndex) { if (beginIndex <= 0) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex == value.length) { return this; } } if (endIndex > value.length) { throw new StringIndexOutOfBoundsException(endIndex); } if (endIndex == beginIndex) { return ""; } throw new StringIndexOutOfBoundsException(endIndex - beginIndex); } additional white-box tests would be required if we adopt that. On Tue, May 12, 2015 at 11:58 AM, Ivan Gerasimov wrote: > > > On 12.05.2015 20:34, Martin Buchholz wrote: > > Hi Ivan, > > The code below looks wrong to me - sb.length() resolves to sb.count, not > v2.length. > If I'm correct, then there's a missing test to be added, since this error > should be caught by some test. > > private boolean nonSyncContentEquals(AbstractStringBuilder sb) { > - char v1[] = value; > - char v2[] = sb.getValue(); > + char[] v1 = value; > + char[] v2 = sb.getValue(); > int n = v1.length; > - if (n != sb.length()) { > + if (n != v2.length) { > return false; > } > > > Yes, of course you're right. This change looked so "obviously correct" > to me, that I didn't care to run the tests before posting the webrev :-( > > I've reverted this change back: > http://cr.openjdk.java.net/~igerasim/8071571/01/webrev/ > > Sincerely yours, > Ivan > > > On Mon, May 11, 2015 at 1:52 PM, Ivan Gerasimov > wrote: > >> I have to take over this fix. >> >> The latest webrev from the review thread above (with a few minor changes) >> is here: >> http://cr.openjdk.java.net/~igerasim/8071571/00/webrev/ >> >> Would you please review/approve the fix at your convenience? >> >> Sincerely yours, >> Ivan >> >> > > From peter.levart at gmail.com Tue May 12 21:26:13 2015 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 12 May 2015 23:26:13 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <5552674E.4030009@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> Message-ID: <55526FF5.9000509@gmail.com> On 05/12/2015 10:49 PM, Mandy Chung wrote: >> But I think it should be pretty safe to make the java.util.Properties >> object override all Hashtable methods and delegate to internal CMH so >> that: >> - all modification methods + all bulk read methods such as >> (keySet().toArray, values.toArray) are made synchronized again >> - individual entry read methods (get, containsKey, ...) are not >> synchronized. >> >> This way we get the benefits of non-synchronized read access but the >> change is hardly observable. In particular since external >> synchronization on the Properties object makes guarded code atomic >> like it is now and individual entry read accesses are almost >> equivalent whether they are synchronized or not and I would be >> surprised if any code using Properties for the purpose they were >> designed for worked any differently. > > I agree that making read-only methods not synchronized while keeping > any method with write-access with synchronized is pretty safe change > and low compatibility risk. On the other hand, would most of the > overrridden methods be synchronized then? Yes, and that doesn't seem to be a problem. Setting properties is not very frequent operation and is usually quite localized. Reading properties is, on the other hand, a very frequent operation dispersed throughout the code (almost like logging) and therefore very prone to deadlocks like the one in this issue. I think that by having an unsynchronized get(Property), most problems with Properties will be solved - deadlock and performance (scalability) related. Regards, Peter > > Mandy From martinrb at google.com Tue May 12 21:58:47 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 12 May 2015 14:58:47 -0700 Subject: RFR: 8079841: Buffer underflow with empty zip entry names In-Reply-To: <554D018E.7020203@oracle.com> References: <554D018E.7020203@oracle.com> Message-ID: Committed! On Fri, May 8, 2015 at 11:33 AM, Xueming Shen wrote: > looks good! > > > On 5/8/15 10:58 AM, Jeremy Manson wrote: > >> There's a fairly harmless buffer underflow with empty zip names in libzip. >> Martin has offered to sponsor this (right, Martin?). >> >> We detected this with ASan, an automatic memory error and leak checking >> tool built into Clang/LLVM. This is one of the reasons that Alexander >> Smundak asked if we could backport clang support to JDK8. >> >> Bug: >> https://bugs.openjdk.java.net/browse/JDK-8079841 >> >> Webrev: >> http://cr.openjdk.java.net/~jmanson/8079841/webrev.00/ >> > > From peter.levart at gmail.com Tue May 12 22:05:41 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 13 May 2015 00:05:41 +0200 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55523418.5010708@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> Message-ID: <55527935.5010408@gmail.com> Hi Dmitry, You iterate the queue then, not the unfinalized list. That's more logical. Holding the queue's lock may pause reference handler and finalizer threads for the entire time of iteration. This can blow up the application. Suppose one wants to diagnose the application because he suspects that finalizer thread hardly keeps up with production of finalizable instances. This can happen if the allocation rate of finalizable objects is very high and/or finalize() methods are not coded to be fast enough. Suppose the queue of Finalizer(s) builds up gradually and is already holding several million objects. Now you initiate the diagnostic command to print the queue. The iteration over and grouping/counting of several millions of Finalizer(s) takes some time. This blocks finalizer thread and reference handler thread. But does not block the threads that allocate finalizable objects. By the time the iteration is over, the JVM blows up and application slows down to a halt doing GCs most of the time, getting OOMEs, etc... It is possible to iterate the elements of the queue for diagnostic purposes without holding a lock. The modification required to do that is the following (havent tested this, but I think it should work): http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ I also suggest the addition to the ReferenceQueue to be contained (package-private) and as generic as possible. That's why I suggest forEach iteration method with no concrete logic. It would be possible to encapsulate the entire logic into a special package-private class (say java.lang.ref.DiagnosticCommands) with static method(s) (printFinalizationQueue)... You could just expose a package-private forEach static method from Finalizer and code the rest in DiagnosticCommands. Regards, Peter On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: > Everybody, > > Updated version: > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ > > Now it iterates over queue and output result sorted by number of instances. > > -Dmitry > > On 2015-05-07 00:51, Derek White wrote: >> Hi Dmitry, Staffan, >> >> Lots of good comments here. >> >> On the topic of what list should be printed out, I think we should focus >> on objects waiting to be finalized - e.g. the contents of the >> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >> could add a summerizeQueue(TreeMap) method, or a >> general iterator and lambda. >> >> A histogram of objects with finalize methods might also be interesting, >> but you can get most of the same information from a heap histogram >> (ClassHistogramDCmd, and search for count of Finalizer instances). >> >> BTW, by only locking the ReferenceQueue, we should only be blocking the >> FinalizerThread from making progress (and I think there's a GC thread >> that runs after GC that sorts found References objects that need >> processing into their respective ReferenceQueues). But locking the >> "unfinalized" list blocks initializing any object with a finalize() method. >> >> The sorting suggestion is a nice touch. >> >> - Derek White, GC team >> >> On 5/5/15 10:40 AM, Peter Levart wrote: >>> Hi Dmitry, Staffan, >>> >>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>> Dmitry, >>>> >>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>> well considering the changes to Finalizer. >>>> >>>> I?m a little worried about the potentially very large String that is >>>> returned from printFinalizationQueue(). A possible different approach >>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>> That would allow for outputting one line at a time. The output would >>>> still be saved in memory (since the stream is buffered), but at least >>>> the data is only saved once in memory, then. It would make the code a >>>> bit harder to write, so its a question of how scared we are of >>>> running out of memory. >>> If the output is just a histogram of # of instances per class name, >>> then it should not be too large, as there are not many different >>> classes overriding finalize() method (I counted 72 overriddings of >>> finalize() method in the whole jdk/src tree). >>> >>> I'm more concerned about the fact that while traversing the list, a >>> lock is held, which might impact prompt finalization(). Is it >>> acceptable for diagnostic output to impact performance and/or >>> interfere with synchronization? >>> >>> It might be possible to scan the list without holding a lock for >>> diagnostic purposes if Finalizer.remove() didn't set the removed >>> Finalizer.next pointer to point back to itself: >>> >>> private void remove() { >>> synchronized (lock) { >>> if (unfinalized == this) { >>> if (this.next != null) { >>> unfinalized = this.next; >>> } else { >>> unfinalized = this.prev; >>> } >>> } >>> if (this.next != null) { >>> this.next.prev = this.prev; >>> } >>> if (this.prev != null) { >>> this.prev.next = this.next; >>> } >>> // this.next = this; must not be set so that we can >>> traverse the list unsynchronized >>> this.prev = this; /* Indicates that this has been >>> finalized */ >>> } >>> } >>> >>> For detecting whether a Finalizer is already processed, the 'prev' >>> pointer could be used instead: >>> >>> private boolean hasBeenFinalized() { >>> return (prev == this); >>> } >>> >>> Also, to make sure a data race dereferencing 'unfinalized' in >>> unsynchronized printFinalizationQueue() would get you a fully >>> initialized Finalizer instance (in particular the next pointer), you >>> would have to make the 'unfinalized' field volatile or insert an >>> Unsafe.storeFence() before assigning to 'unfinalized': >>> >>> private void add() { >>> synchronized (lock) { >>> if (unfinalized != null) { >>> this.next = unfinalized; >>> unfinalized.prev = this; >>> } >>> // make sure a data race dereferencing 'unfinalized' >>> // in printFinalizationQueue() does see the Finalizer >>> // instance fully initialized >>> // (in particular the 'next' pointer) >>> U.storeFence(); >>> unfinalized = this; >>> } >>> } >>> >>> >>> By doing these modifications, I think you can remove >>> synchronized(lock) {} from printFinalizationQueue(). >>> >>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>> not sure of the difference, perhaps someone from the GC team can help >>>> out? >>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>> instances pending processing by finalizer thread because their >>> referents are eligible for finalization (they are not reachable any >>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>> instances for which their referents have not been finalized yet >>> (including those that are still reachable and alive). The later serves >>> two purposes: >>> - it keeps Finalizer instances reachable until they are processed >>> - it is a source of unfinalized instances for >>> running-finalizers-on-exit if requested by >>> System.runFinalizersOnExit(true); >>> >>> So it really depends on what one would like to see. Showing the queue >>> may be interesting if one wants to see how the finalizer thread is >>> coping with processing the finalize() invocations. Showing unfinalized >>> list may be interesting if one wants to know how many live + >>> finalization pending instances are there on the heap that override >>> finalize() method. >>> >>> Regards, Peter >>> >>>> For the output, it would be a nice touch to sort it on the number of >>>> references for each type. Perhaps outputting it more like a table >>>> (see the old code again) would also make it easier to digest. >>>> >>>> In diagnosticCommand.hpp, the new commands should override >>>> permission() and limit access: >>>> >>>> static const JavaPermission permission() { >>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>> "monitor", NULL}; >>>> return p; >>>> } >>>> >>>> The two tests don?t validate the output in any way. Would it be >>>> possible to add validation? Perhaps hard to make sure an object is on >>>> the finalizer queue? Hmm. >>>> >>>> Thanks, >>>> /Staffan >>>> >>>> >>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>> wrote: >>>>> >>>>> Everyone, >>>>> >>>>> Please review the fix: >>>>> >>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>> >>>>> heap dcmd outputs the same information as SIGBREAK >>>>> >>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>> with count >>>>> >>>>> -Dmitry >>>>> >>>>> -- >>>>> Dmitry Samersoff >>>>> Oracle Java development team, Saint Petersburg, Russia >>>>> * I would love to change the world, but they won't give me the sources. From patrick at reini.net Tue May 12 22:10:51 2015 From: patrick at reini.net (Patrick Reinhart) Date: Wed, 13 May 2015 00:10:51 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> Message-ID: <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> Hi Pavel, Is there anything I can do in the meantime? Unfortunately I do not have no account on cr.openjdk.java.net , so I need to paste the patch to the mailing list directly. Cheers Patrick > Am 10.05.2015 um 21:16 schrieb Chris Hegarty : > > I have not looked at the changes in detail yet, but I think it is going in the right direction. Just a few comments: > From paul.sandoz at oracle.com Wed May 13 08:45:21 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 13 May 2015 10:45:21 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <5552674E.4030009@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> Message-ID: <1290B915-DA74-4D41-96D9-5E1E7DB3428D@oracle.com> On May 12, 2015, at 10:49 PM, Mandy Chung wrote: >> >> Ah, I understand Mandy now. You are talking about using special Properties implementation just for system properties. Unfortunately, this is currently valid code: >> >> Properties props = new Properties(); >> ... >> System.setProperties(props); >> ... >> props.setProperty(key, value); >> assert System.getProperty(key).equals(value); >> > > > How likely does existing code do this? A proper way is to call System.setProperty. One pattern I found on System.setProperties is like this to add a system property of key/value pair: > > Properties props = System.getProperties(); > props.put(key, value); > System.setProperties(props); > > More investigation needs to be done (e.g. look at System.setProperties and other system property related APIs and any spec change is needed to be made and the compatibility implication) if we agree that it worths keeping this change local to system properties. > FWIW you can see some usages here: http://grepcode.com/search/usages?type=method&id=repository.grepcode.com%24java%24root at jdk%24openjdk at 7u40-b43@java%24lang at System@setProperties%28java.util.Properties%29&k=u Paul. From vladimir.x.ivanov at oracle.com Wed May 13 09:27:59 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 13 May 2015 12:27:59 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <5551DC44.9060902@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> Message-ID: <5553191F.6080800@oracle.com> I finished experimenting with the idea inspired by private discussion with Kim Barrett: http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02/ The idea is to use CallSite instance as a context for dependency tracking, instead of the Class CallSite is bound to. It requires extension of nmethod dependencies to be used separately from InstanceKlass. Though it slightly complicates nmethod dependency management (special cases for call_site_target_value are added), it completely eliminates the need for context state transitions. Every CallSite instance has its dedicated context, represented as CallSite.Context which stores an address of the dependency list head (nmethodBucket*). Cleanup action (Cleaner) is attached to CallSite instance and frees all allocated nmethodBucket entries when CallSite becomes unreachable. Though CallSite instance can freely go away, the Cleaner keeps corresponding CallSite.Context from reclamation (all Cleaners are registered in static list in Cleaner class). I like how it finally shaped out. It became much easier to reason about CallSite context. Dependency tracking extension to non-InstanceKlass contextes looks quite natural and can be reused. Testing: extended regression test, jprt, nashorn Thanks! Best regards, Vladimir Ivanov On 5/12/15 1:56 PM, Vladimir Ivanov wrote: > Peter, > >>> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.01 >>> https://bugs.openjdk.java.net/browse/JDK-8079205 >> >> Your Finalizator touches are good. Supplier interface is not needed as >> there is a public Reference superclass that can be used for return type >> of JavaLangRefAccess.createFinalizator(). You can remove the import for >> Supplier in Reference now. > Thanks for spotting that. Will do. > >>> Recent change in sun.misc.Cleaner behavior broke CallSite context >>> cleanup. >>> >>> CallSite references context class through a Cleaner to avoid its >>> unnecessary retention. >>> >>> The problem is the following: to do a cleanup (invalidate all affected >>> nmethods) VM needs a pointer to a context class. Until Cleaner is >>> cleared (and it was a manual action, since Cleaner extends >>> PhantomReference isn't automatically cleared according to the docs), >>> VM can extract it from CallSite.context.referent field. >> >> If PhantomReference.referent wasn't cleared by VM when PhantomReference >> was equeued, could it happen that the referent pointer was still != null >> and the referent object's heap memory was already reclaimed by GC? Is >> that what JDK-8071931 is about? (I cant't see the bug - it's internal). >> In that respect the Cleaner based solution was broken from the start, as >> you did dereference the referent after Cleaner was enqueued. You could >> get a != null pointer which was pointing to reclaimed heap. In Java this >> dereference is prevented by PhantomReference.get() always returning null >> (well, nothing prevents one to read the referent field with reflection >> though). > No, the object isn't reclaimed until corresponding reference is != null. > When Cleaner wasn't automatically cleared, it was guaranteed that the > referent is alive when cleanup action happens. That is the assumption > CallSite dependency tracking is based on. > > It's not the case anymore when Cleaner is automatically cleared. Cleanup > action can happen when context Class is already GCed. So, I can access > neither the context mirror class nor VM-internal InstanceKlass. > >> FinalReference(s) are different in that their referent is not reclaimed >> while it is still reachable through FinalReference, which means that >> finalizable objects must undergo at least two GC cycles, with processing >> in the reference handler and finalizer threads inbetween the cycles, to >> be reclaimed. PhantomReference(s), on the other hand, can be enqueued >> and their referents reclaimed in the same GC cycle, can't they? > Since PhantomReference isn't automatically cleared, GC can't reclaim its > referent until the reference is manually cleared or PhantomReference > becomes unreachable as a result of cleanup action. > So, it's impossible to reclaim it in the same GC cycle (unless it is a > concurrent GC cycle?). > >>> I experimented with moving cleanup logic into VM [1], >> >> What's the downside of that approach? I mean, why is GC-assisted >> approach better? Simpler? > IMO the more code on JDK side the better. More safety guarantees are > provided in Java code comparing to native/VM code. > > Also, JVM-based approach suffers from the fact it doesn't get prompt > notification when context Class can be GCed. Since it should work with > autocleared references, there's no need in a cleanup action anymore. > By the time cleanup happens, referent can be already GCed. > > That's why I switched from Cleaner to WeakReference. When > CallSite.context is cleared ("stale" context), VM has to scan all > nmethods in the code cache to find all affected nmethods. > > BTW I had a private discussion with Kim Barrett who suggested an > alternative approach which doesn't require full code cache scan. I plan > to do some prototyping to understand its feasibility, since it requires > non-InstanceKlass-based nmethod dependency tracking machinery. > > Best regards, > Vladimir Ivanov > >>> but Peter Levart came up with a clever idea and implemented >>> FinalReference-based cleaner-like Finalizator. Classes don't have >>> finalizers, but Finalizator allows to attach a finalization action to >>> them. And it is guaranteed that the referent is alive when >>> finalization happens. >>> >>> Also, Peter spotted another problem with Cleaner-based implementation. >>> Cleaner cleanup action is strongly referenced, since it is registered >>> in Cleaner class. CallSite context cleanup action keeps a reference to >>> CallSite class (it is passed to MHN.invalidateDependentNMethods). >>> Users are free to extend CallSite and many do so. If a context class >>> and a call site class are loaded by a custom class loader, such loader >>> will never be unloaded, causing a memory leak. >>> >>> Finalizator doesn't suffer from that, since the action is referenced >>> only from Finalizator instance. The downside is that cleanup action >>> can be missed if Finalizator becomes unreachable. It's not a problem >>> for CallSite context, because a context is always referenced from some >>> CallSite and if a CallSite becomes unreachable, there's no need to >>> perform a cleanup. >>> >>> Testing: jdk/test/java/lang/invoke, hotspot/test/compiler/jsr292 >>> >>> Contributed-by: plevart, vlivanov >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> PS: frankly speaking, I would move Finalizator from java.lang.ref to >>> java.lang.invoke and call it Context, if there were a way to extend >>> package-private FinalReference from another package :-) >> >> Modules may have an answer for that. FinalReference could be moved to a >> package (java.lang.ref.internal or jdk.lang.ref) that is not exported to >> the world and made public. >> >> On the other hand, I don't see a reason why FinalReference couldn't be >> part of JDK public API. I know it's currently just a private mechanism >> to implement finalization which has issues and many would like to see it >> gone, but Java has learned to live with it, and, as you see, it can be a >> solution to some problems too ;-) >> >> Regards, Peter >> >>> >>> [1] http://cr.openjdk.java.net/~vlivanov/8079205/webrev.00 >> From chris.hegarty at oracle.com Wed May 13 10:12:52 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 13 May 2015 11:12:52 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> Message-ID: <555323A4.4060801@oracle.com> On 12/05/15 23:10, Patrick Reinhart wrote: > ... > Unfortunately I do not have no account on cr.openjdk.java.net , so I need to paste the patch to the mailing list directly. Given your previous contributions [1] and ongoing involvement in OpenJDK, it would be reasonable for you to request an author role [2] for the JDK 9 project. An author has an account on cr.openjdk.java.net. But of course, this is your choice. -Chris. [1] http://hg.openjdk.java.net/jdk9/dev/jdk/log?rev=patrick%40reini.net [2] http://openjdk.java.net/bylaws#author > > Cheers Patrick > >> Am 10.05.2015 um 21:16 schrieb Chris Hegarty : >> >> I have not looked at the changes in detail yet, but I think it is going in the right direction. Just a few comments: >> > From peter.levart at gmail.com Wed May 13 10:45:17 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 13 May 2015 12:45:17 +0200 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <5553191F.6080800@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> Message-ID: <55532B3D.5090202@gmail.com> Hi Vladimir, This is nice. I don't know how space-savvy CallSite should be, but you can save one additional object - the Cleaner's thunk: static class Context implements Runnable { private final long dependencies = 0; // Used by JVM to store JVM_nmethodBucket* static Context make(CallSite cs) { Context newContext = new Context(); // Cleaner is attached to CallSite instance and it clears native structures allocated for CallSite context. // Though the CallSite can become unreachable, its Context is retained by the Cleaner instance (which is // referenced from Cleaner class) until cleanup is performed. Cleaner.create(cs, newContext); return newContext; } @Override public void run() { MethodHandleNatives.clearCallSiteContext(this); } } Since Context instance does not escape to client code, I think this is safe. Regards, Peter On 05/13/2015 11:27 AM, Vladimir Ivanov wrote: > I finished experimenting with the idea inspired by private discussion > with Kim Barrett: > > http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02/ > > The idea is to use CallSite instance as a context for dependency > tracking, instead of the Class CallSite is bound to. It requires > extension of nmethod dependencies to be used separately from > InstanceKlass. Though it slightly complicates nmethod dependency > management (special cases for call_site_target_value are added), it > completely eliminates the need for context state transitions. > > Every CallSite instance has its dedicated context, represented as > CallSite.Context which stores an address of the dependency list head > (nmethodBucket*). Cleanup action (Cleaner) is attached to CallSite > instance and frees all allocated nmethodBucket entries when CallSite > becomes unreachable. Though CallSite instance can freely go away, the > Cleaner keeps corresponding CallSite.Context from reclamation (all > Cleaners are registered in static list in Cleaner class). > > I like how it finally shaped out. It became much easier to reason > about CallSite context. Dependency tracking extension to > non-InstanceKlass contextes looks quite natural and can be reused. > > Testing: extended regression test, jprt, nashorn > > Thanks! > > Best regards, > Vladimir Ivanov > > On 5/12/15 1:56 PM, Vladimir Ivanov wrote: >> Peter, >> >>>> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.01 >>>> https://bugs.openjdk.java.net/browse/JDK-8079205 >>> >>> Your Finalizator touches are good. Supplier interface is not needed as >>> there is a public Reference superclass that can be used for return type >>> of JavaLangRefAccess.createFinalizator(). You can remove the import for >>> Supplier in Reference now. >> Thanks for spotting that. Will do. >> >>>> Recent change in sun.misc.Cleaner behavior broke CallSite context >>>> cleanup. >>>> >>>> CallSite references context class through a Cleaner to avoid its >>>> unnecessary retention. >>>> >>>> The problem is the following: to do a cleanup (invalidate all affected >>>> nmethods) VM needs a pointer to a context class. Until Cleaner is >>>> cleared (and it was a manual action, since Cleaner extends >>>> PhantomReference isn't automatically cleared according to the docs), >>>> VM can extract it from CallSite.context.referent field. >>> >>> If PhantomReference.referent wasn't cleared by VM when PhantomReference >>> was equeued, could it happen that the referent pointer was still != >>> null >>> and the referent object's heap memory was already reclaimed by GC? Is >>> that what JDK-8071931 is about? (I cant't see the bug - it's internal). >>> In that respect the Cleaner based solution was broken from the >>> start, as >>> you did dereference the referent after Cleaner was enqueued. You could >>> get a != null pointer which was pointing to reclaimed heap. In Java >>> this >>> dereference is prevented by PhantomReference.get() always returning >>> null >>> (well, nothing prevents one to read the referent field with reflection >>> though). >> No, the object isn't reclaimed until corresponding reference is != null. >> When Cleaner wasn't automatically cleared, it was guaranteed that the >> referent is alive when cleanup action happens. That is the assumption >> CallSite dependency tracking is based on. >> >> It's not the case anymore when Cleaner is automatically cleared. Cleanup >> action can happen when context Class is already GCed. So, I can access >> neither the context mirror class nor VM-internal InstanceKlass. >> >>> FinalReference(s) are different in that their referent is not reclaimed >>> while it is still reachable through FinalReference, which means that >>> finalizable objects must undergo at least two GC cycles, with >>> processing >>> in the reference handler and finalizer threads inbetween the cycles, to >>> be reclaimed. PhantomReference(s), on the other hand, can be enqueued >>> and their referents reclaimed in the same GC cycle, can't they? >> Since PhantomReference isn't automatically cleared, GC can't reclaim its >> referent until the reference is manually cleared or PhantomReference >> becomes unreachable as a result of cleanup action. >> So, it's impossible to reclaim it in the same GC cycle (unless it is a >> concurrent GC cycle?). >> >>>> I experimented with moving cleanup logic into VM [1], >>> >>> What's the downside of that approach? I mean, why is GC-assisted >>> approach better? Simpler? >> IMO the more code on JDK side the better. More safety guarantees are >> provided in Java code comparing to native/VM code. >> >> Also, JVM-based approach suffers from the fact it doesn't get prompt >> notification when context Class can be GCed. Since it should work with >> autocleared references, there's no need in a cleanup action anymore. >> By the time cleanup happens, referent can be already GCed. >> >> That's why I switched from Cleaner to WeakReference. When >> CallSite.context is cleared ("stale" context), VM has to scan all >> nmethods in the code cache to find all affected nmethods. >> >> BTW I had a private discussion with Kim Barrett who suggested an >> alternative approach which doesn't require full code cache scan. I plan >> to do some prototyping to understand its feasibility, since it requires >> non-InstanceKlass-based nmethod dependency tracking machinery. >> >> Best regards, >> Vladimir Ivanov >> >>>> but Peter Levart came up with a clever idea and implemented >>>> FinalReference-based cleaner-like Finalizator. Classes don't have >>>> finalizers, but Finalizator allows to attach a finalization action to >>>> them. And it is guaranteed that the referent is alive when >>>> finalization happens. >>>> >>>> Also, Peter spotted another problem with Cleaner-based implementation. >>>> Cleaner cleanup action is strongly referenced, since it is registered >>>> in Cleaner class. CallSite context cleanup action keeps a reference to >>>> CallSite class (it is passed to MHN.invalidateDependentNMethods). >>>> Users are free to extend CallSite and many do so. If a context class >>>> and a call site class are loaded by a custom class loader, such loader >>>> will never be unloaded, causing a memory leak. >>>> >>>> Finalizator doesn't suffer from that, since the action is referenced >>>> only from Finalizator instance. The downside is that cleanup action >>>> can be missed if Finalizator becomes unreachable. It's not a problem >>>> for CallSite context, because a context is always referenced from some >>>> CallSite and if a CallSite becomes unreachable, there's no need to >>>> perform a cleanup. >>>> >>>> Testing: jdk/test/java/lang/invoke, hotspot/test/compiler/jsr292 >>>> >>>> Contributed-by: plevart, vlivanov >>>> >>>> Best regards, >>>> Vladimir Ivanov >>>> >>>> PS: frankly speaking, I would move Finalizator from java.lang.ref to >>>> java.lang.invoke and call it Context, if there were a way to extend >>>> package-private FinalReference from another package :-) >>> >>> Modules may have an answer for that. FinalReference could be moved to a >>> package (java.lang.ref.internal or jdk.lang.ref) that is not >>> exported to >>> the world and made public. >>> >>> On the other hand, I don't see a reason why FinalReference couldn't be >>> part of JDK public API. I know it's currently just a private mechanism >>> to implement finalization which has issues and many would like to >>> see it >>> gone, but Java has learned to live with it, and, as you see, it can >>> be a >>> solution to some problems too ;-) >>> >>> Regards, Peter >>> >>>> >>>> [1] http://cr.openjdk.java.net/~vlivanov/8079205/webrev.00 >>> From pavel.rappo at oracle.com Wed May 13 11:03:32 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 13 May 2015 12:03:32 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Message-ID: It now can be reviewed as usual at: http://cr.openjdk.java.net/~prappo/8080272/webrev.00/ Feel free to review. Thanks. -Pavel > On 10 May 2015, at 12:45, Martijn Verburg wrote: > > Hi Patrick, > > Have you posted the webrev somewhere for review? > > Cheers, > Martijn > > On 8 May 2015 at 23:53, Patrick Reinhart wrote: > Hi Pavel, > > I have changed the most obvious files and made a patch of each repo. I hope the patches will not be removed? > > Cheers > > Patrick > > > > > > Am 07.05.2015 um 20:44 schrieb Pavel Rappo : > > > > Hi Patrick, > > > > That's a good idea! I can sponsor them no problem. > > > > -Pavel > > > >> On 7 May 2015, at 19:13, Patrick Reinhart wrote: > >> > >> Hi there, > >> > >> A couple months ago the transferTo() method was added to the JDK. I?m regularly joining the local hacker garten and wanted to ask if it maybe would be a good task to clean up the JDK code to use this method in such a session. Would someone sponsor such changes to be checked in? I would suggest that I would post a diff for each changed class to the core-libs-dev list. > >> > >> Cheers > >> > >> Patrick > > > > > From patrick at reini.net Wed May 13 11:24:03 2015 From: patrick at reini.net (patrick at reini.net) Date: Wed, 13 May 2015 13:24:03 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: <555323A4.4060801@oracle.com> References: "<908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> " <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> <555323A4.4060801@oracle.com> Message-ID: <85cee66716a066c7dfd31975dddc1e3f@reini.net> Hi Chris, That would simplify the process greatly. What I exactly need to do for getting the JDK 9 project author role? Cheers, Patrick On 2015-05-13 12:12, Chris Hegarty wrote: > Given your previous contributions [1] and ongoing involvement in > OpenJDK, it would be reasonable for you to request an author role [2] > for the JDK 9 project. An author has an account on > cr.openjdk.java.net. But of course, this is your choice. > > -Chris. > > [1] > http://hg.openjdk.java.net/jdk9/dev/jdk/log?rev=patrick%40reini.net > [2] http://openjdk.java.net/bylaws#author From paul.sandoz at oracle.com Wed May 13 11:24:07 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 13 May 2015 13:24:07 +0200 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <5553191F.6080800@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> Message-ID: <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> Hi Vladimir, I am not an export in the HS area but the code mostly made sense to me. I also like Peter's suggestion of Context implementing Runnable. Some minor comments. CallSite.java: 145 private final long dependencies = 0; // Used by JVM to store JVM_nmethodBucket* It's a little odd to see this field be final, but i think i understand the motivation as it's essentially acting as a memory address pointing to the head of the nbucket list, so in Java code you don't want to assign it to anything other than 0. Is VM access, via java_lang_invoke_CallSite_Context, affected by treating final fields as really final in the j.l.i package? javaClasses.hpp: 1182 static oop context(oop site); 1183 static void set_context(oop site, oop context); Is set_context required? instanceKlass.cpp: 1876 // recording of dependecies. Returns true if the bucket is ready for reclamation. typo "dependecies" Paul. On May 13, 2015, at 11:27 AM, Vladimir Ivanov wrote: > I finished experimenting with the idea inspired by private discussion with Kim Barrett: > > http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02/ > > The idea is to use CallSite instance as a context for dependency tracking, instead of the Class CallSite is bound to. It requires extension of nmethod dependencies to be used separately from InstanceKlass. Though it slightly complicates nmethod dependency management (special cases for call_site_target_value are added), it completely eliminates the need for context state transitions. > > Every CallSite instance has its dedicated context, represented as CallSite.Context which stores an address of the dependency list head (nmethodBucket*). Cleanup action (Cleaner) is attached to CallSite instance and frees all allocated nmethodBucket entries when CallSite becomes unreachable. Though CallSite instance can freely go away, the Cleaner keeps corresponding CallSite.Context from reclamation (all Cleaners are registered in static list in Cleaner class). > > I like how it finally shaped out. It became much easier to reason about CallSite context. Dependency tracking extension to non-InstanceKlass contextes looks quite natural and can be reused. > > Testing: extended regression test, jprt, nashorn > > Thanks! > > Best regards, > Vladimir Ivanov > > On 5/12/15 1:56 PM, Vladimir Ivanov wrote: >> Peter, >> >>>> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.01 >>>> https://bugs.openjdk.java.net/browse/JDK-8079205 >>> >>> Your Finalizator touches are good. Supplier interface is not needed as >>> there is a public Reference superclass that can be used for return type >>> of JavaLangRefAccess.createFinalizator(). You can remove the import for >>> Supplier in Reference now. >> Thanks for spotting that. Will do. >> >>>> Recent change in sun.misc.Cleaner behavior broke CallSite context >>>> cleanup. >>>> >>>> CallSite references context class through a Cleaner to avoid its >>>> unnecessary retention. >>>> >>>> The problem is the following: to do a cleanup (invalidate all affected >>>> nmethods) VM needs a pointer to a context class. Until Cleaner is >>>> cleared (and it was a manual action, since Cleaner extends >>>> PhantomReference isn't automatically cleared according to the docs), >>>> VM can extract it from CallSite.context.referent field. >>> >>> If PhantomReference.referent wasn't cleared by VM when PhantomReference >>> was equeued, could it happen that the referent pointer was still != null >>> and the referent object's heap memory was already reclaimed by GC? Is >>> that what JDK-8071931 is about? (I cant't see the bug - it's internal). >>> In that respect the Cleaner based solution was broken from the start, as >>> you did dereference the referent after Cleaner was enqueued. You could >>> get a != null pointer which was pointing to reclaimed heap. In Java this >>> dereference is prevented by PhantomReference.get() always returning null >>> (well, nothing prevents one to read the referent field with reflection >>> though). >> No, the object isn't reclaimed until corresponding reference is != null. >> When Cleaner wasn't automatically cleared, it was guaranteed that the >> referent is alive when cleanup action happens. That is the assumption >> CallSite dependency tracking is based on. >> >> It's not the case anymore when Cleaner is automatically cleared. Cleanup >> action can happen when context Class is already GCed. So, I can access >> neither the context mirror class nor VM-internal InstanceKlass. >> >>> FinalReference(s) are different in that their referent is not reclaimed >>> while it is still reachable through FinalReference, which means that >>> finalizable objects must undergo at least two GC cycles, with processing >>> in the reference handler and finalizer threads inbetween the cycles, to >>> be reclaimed. PhantomReference(s), on the other hand, can be enqueued >>> and their referents reclaimed in the same GC cycle, can't they? >> Since PhantomReference isn't automatically cleared, GC can't reclaim its >> referent until the reference is manually cleared or PhantomReference >> becomes unreachable as a result of cleanup action. >> So, it's impossible to reclaim it in the same GC cycle (unless it is a >> concurrent GC cycle?). >> >>>> I experimented with moving cleanup logic into VM [1], >>> >>> What's the downside of that approach? I mean, why is GC-assisted >>> approach better? Simpler? >> IMO the more code on JDK side the better. More safety guarantees are >> provided in Java code comparing to native/VM code. >> >> Also, JVM-based approach suffers from the fact it doesn't get prompt >> notification when context Class can be GCed. Since it should work with >> autocleared references, there's no need in a cleanup action anymore. >> By the time cleanup happens, referent can be already GCed. >> >> That's why I switched from Cleaner to WeakReference. When >> CallSite.context is cleared ("stale" context), VM has to scan all >> nmethods in the code cache to find all affected nmethods. >> >> BTW I had a private discussion with Kim Barrett who suggested an >> alternative approach which doesn't require full code cache scan. I plan >> to do some prototyping to understand its feasibility, since it requires >> non-InstanceKlass-based nmethod dependency tracking machinery. >> >> Best regards, >> Vladimir Ivanov >> >>>> but Peter Levart came up with a clever idea and implemented >>>> FinalReference-based cleaner-like Finalizator. Classes don't have >>>> finalizers, but Finalizator allows to attach a finalization action to >>>> them. And it is guaranteed that the referent is alive when >>>> finalization happens. >>>> >>>> Also, Peter spotted another problem with Cleaner-based implementation. >>>> Cleaner cleanup action is strongly referenced, since it is registered >>>> in Cleaner class. CallSite context cleanup action keeps a reference to >>>> CallSite class (it is passed to MHN.invalidateDependentNMethods). >>>> Users are free to extend CallSite and many do so. If a context class >>>> and a call site class are loaded by a custom class loader, such loader >>>> will never be unloaded, causing a memory leak. >>>> >>>> Finalizator doesn't suffer from that, since the action is referenced >>>> only from Finalizator instance. The downside is that cleanup action >>>> can be missed if Finalizator becomes unreachable. It's not a problem >>>> for CallSite context, because a context is always referenced from some >>>> CallSite and if a CallSite becomes unreachable, there's no need to >>>> perform a cleanup. >>>> >>>> Testing: jdk/test/java/lang/invoke, hotspot/test/compiler/jsr292 >>>> >>>> Contributed-by: plevart, vlivanov >>>> >>>> Best regards, >>>> Vladimir Ivanov >>>> >>>> PS: frankly speaking, I would move Finalizator from java.lang.ref to >>>> java.lang.invoke and call it Context, if there were a way to extend >>>> package-private FinalReference from another package :-) >>> >>> Modules may have an answer for that. FinalReference could be moved to a >>> package (java.lang.ref.internal or jdk.lang.ref) that is not exported to >>> the world and made public. >>> >>> On the other hand, I don't see a reason why FinalReference couldn't be >>> part of JDK public API. I know it's currently just a private mechanism >>> to implement finalization which has issues and many would like to see it >>> gone, but Java has learned to live with it, and, as you see, it can be a >>> solution to some problems too ;-) >>> >>> Regards, Peter >>> >>>> >>>> [1] http://cr.openjdk.java.net/~vlivanov/8079205/webrev.00 >>> From chris.hegarty at oracle.com Wed May 13 11:29:14 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 13 May 2015 12:29:14 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: <85cee66716a066c7dfd31975dddc1e3f@reini.net> References: "<908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> " <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> <555323A4.4060801@oracle.com> <85cee66716a066c7dfd31975dddc1e3f@reini.net> Message-ID: <5553358A.5050507@oracle.com> On 13/05/15 12:24, patrick at reini.net wrote: > Hi Chris, > > That would simplify the process greatly. What I exactly need to do for > getting the JDK 9 project author role? See the section named "Becoming an Author" on the Projects page [1]. -Chris. [1] http://openjdk.java.net/projects/ > > Cheers, > > Patrick > > On 2015-05-13 12:12, Chris Hegarty wrote: > >> Given your previous contributions [1] and ongoing involvement in >> OpenJDK, it would be reasonable for you to request an author role [2] >> for the JDK 9 project. An author has an account on >> cr.openjdk.java.net. But of course, this is your choice. >> >> -Chris. >> >> [1] http://hg.openjdk.java.net/jdk9/dev/jdk/log?rev=patrick%40reini.net >> [2] http://openjdk.java.net/bylaws#author > > From claes.redestad at oracle.com Wed May 13 11:51:05 2015 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 13 May 2015 13:51:05 +0200 Subject: RFR: 8061254: SPECjvm2008-XML performance regressions in 9-b33 Message-ID: <55533AA9.7010304@oracle.com> Hi, 9-b33 introduced a sustained regression in SPECjvm2008 xml.transform on a number of our test setups. JDK-8058643 removed the check on value.length > 0, which means repeated calls to "".hashCode() now do a store of the calculated value (0) to the hash field. This has potential to cause excessive cache coherence traffic in xml.transform[1] Extracting the code that showed up in profiles to a micro[2] and running this in multiple threads is up to 100x slower in 9-b33 on a dual-socket machine. Adding back the check that value.length > 0 before entering the calculation loop recuperates the loss in both micro and xml.transform, but we're seeing as good or better number by simply guarding the store: Webrev: http://cr.openjdk.java.net/~redestad/8061254/webrev.00/ Bug: https://bugs.openjdk.java.net/browse/JDK-8061254 (confidential due to links to internal systems, sorry!) This additionally avoids the field store (and potential for pointless cache traffic) also on non-empty strings whose hash value happen to equals 0. Thanks! /Claes [1] See com.sun.org.apache.xml.internal.dtm.ref.ExpandedNameTable#getExpandedTypeID. [2] http://cr.openjdk.java.net/~redestad/8061254/expandedtypeid-micro.zip From vladimir.x.ivanov at oracle.com Wed May 13 11:59:42 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 13 May 2015 14:59:42 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> Message-ID: <55533CAE.3050201@oracle.com> Peter, Paul, thanks for the feedback! Updated the webrev in place: http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 > I am not an export in the HS area but the code mostly made sense to me. I also like Peter's suggestion of Context implementing Runnable. I agree. Integrated. > Some minor comments. > > CallSite.java: > > 145 private final long dependencies = 0; // Used by JVM to store JVM_nmethodBucket* > > It's a little odd to see this field be final, but i think i understand the motivation as it's essentially acting as a memory address pointing to the head of the nbucket list, so in Java code you don't want to assign it to anything other than 0. Yes, my motivation was to forbid reads & writes of the field from Java code. I was experimenting with injecting the field by VM, but it's less attractive. > Is VM access, via java_lang_invoke_CallSite_Context, affected by treating final fields as really final in the j.l.i package? No, field modifiers aren't respected. oopDesc::*_field_[get|put] does a raw read/write using field offset. > javaClasses.hpp: > > 1182 static oop context(oop site); > 1183 static void set_context(oop site, oop context); > > Is set_context required? Good point. Removed. > instanceKlass.cpp: > > 1876 // recording of dependecies. Returns true if the bucket is ready for reclamation. > > typo "dependecies" Fixed. Best regards, Vladimir Ivanov From aleksey.shipilev at oracle.com Wed May 13 12:03:03 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Wed, 13 May 2015 15:03:03 +0300 Subject: RFR: 8061254: SPECjvm2008-XML performance regressions in 9-b33 In-Reply-To: <55533AA9.7010304@oracle.com> References: <55533AA9.7010304@oracle.com> Message-ID: <55533D77.2020904@oracle.com> On 13.05.2015 14:51, Claes Redestad wrote: > 9-b33 introduced a sustained regression in SPECjvm2008 > xml.transform on a number of our test setups. > > JDK-8058643 removed the check on value.length > 0, which > means repeated calls to "".hashCode() now do a store of the > calculated value (0) to the hash field. This has potential to > cause excessive cache coherence traffic in xml.transform[1] More details: it seems like xml.transform ends up using JDK APIs (com.sun.org.apache.xml.internal.dtm.ref.ExpandedNameTable.getExpandedTypeID) that "compute" the hashcode for "null" argument by calling "".hashCode(), which is silly in itself. Anyhow, dropping value.length > 0 check was my bad, and it is a yet another manifestation of the empirical law in performance engineering: https://twitter.com/shipilev/status/539119320081907713 > Adding back the check that value.length > 0 before entering the > calculation loop recuperates the loss in both micro and > xml.transform, but we're seeing as good or better number by > simply guarding the store: > > Webrev: http://cr.openjdk.java.net/~redestad/8061254/webrev.00/ Good. Thanks, -Aleksey From Sergey.Bylokhov at oracle.com Wed May 13 12:36:11 2015 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Wed, 13 May 2015 15:36:11 +0300 Subject: RFR: 8061254: SPECjvm2008-XML performance regressions in 9-b33 In-Reply-To: <55533AA9.7010304@oracle.com> References: <55533AA9.7010304@oracle.com> Message-ID: <5553453B.7000800@oracle.com> Just curious, what is the difference between this fix and an old version of the code: http://cr.openjdk.java.net/~shade/8058643/webrev.01/src/java.base/share/classes/java/lang/String.java.sdiff.html I meant: "if (h == 0 && value.length > 0) {}" vs "if (h != 0) {hash = h;}" On 13.05.15 14:51, Claes Redestad wrote: > Hi, > > 9-b33 introduced a sustained regression in SPECjvm2008 > xml.transform on a number of our test setups. > > JDK-8058643 removed the check on value.length > 0, which > means repeated calls to "".hashCode() now do a store of the > calculated value (0) to the hash field. This has potential to > cause excessive cache coherence traffic in xml.transform[1] > > Extracting the code that showed up in profiles to a micro[2] and > running this in multiple threads is up to 100x slower in 9-b33 on > a dual-socket machine. > > Adding back the check that value.length > 0 before entering the > calculation loop recuperates the loss in both micro and > xml.transform, but we're seeing as good or better number by > simply guarding the store: > > Webrev: http://cr.openjdk.java.net/~redestad/8061254/webrev.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8061254 (confidential > due to links to internal systems, sorry!) > > This additionally avoids the field store (and potential for pointless > cache traffic) also on non-empty strings whose hash value happen > to equals 0. > > Thanks! > > /Claes > > [1] See > com.sun.org.apache.xml.internal.dtm.ref.ExpandedNameTable#getExpandedTypeID. > [2] http://cr.openjdk.java.net/~redestad/8061254/expandedtypeid-micro.zip -- Best regards, Sergey. From vitalyd at gmail.com Wed May 13 12:53:02 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Wed, 13 May 2015 08:53:02 -0400 Subject: RFR: 8061254: SPECjvm2008-XML performance regressions in 9-b33 In-Reply-To: <5553453B.7000800@oracle.com> References: <55533AA9.7010304@oracle.com> <5553453B.7000800@oracle.com> Message-ID: It's interesting that this version performs as good or *better* than value.length > 0 check. Intuitively, value.length is going to be used anyway (if h == 0) in the loop and so there should be no penalty of loading and branching on it (given the change here has a branch anyway) and compiler can keep that value in a register for the actual loop. Looking at the generated asm for current String.hashCode(), it doesn't look like compiler is actually using the user-written check to skip its own check (see the two tests at the bottom of this snippet): 0x00007f7e312a0d8c: mov %rsi,%rbx 0x00007f7e312a0d8f: mov 0x10(%rsi),%eax ;*getfield hash ; - java.lang.String::hashCode at 1 (line 1454) 0x00007f7e312a0d92: test %eax,%eax 0x00007f7e312a0d94: jne 0x00007f7e312a0e85 ;*ifne ; - java.lang.String::hashCode at 6 (line 1455) 0x00007f7e312a0d9a: mov 0xc(%rsi),%ebp ;*getfield value ; - java.lang.String::hashCode at 10 (line 1455) 0x00007f7e312a0d9d: mov 0xc(%r12,%rbp,8),%r10d ;*arraylength ; - java.lang.String::hashCode at 13 (line 1455) ; implicit exception: dispatches to 0x00007f7e312a0ea9 0x00007f7e312a0da2: test %r10d,%r10d 0x00007f7e312a0da5: jle 0x00007f7e312a0e91 ;*ifle ; - java.lang.String::hashCode at 14 (line 1455) 0x00007f7e312a0dab: test %r10d,%r10d 0x00007f7e312a0dae: jbe 0x00007f7e312a0e95 It does however continue using r10. On Wed, May 13, 2015 at 8:36 AM, Sergey Bylokhov wrote: > Just curious, what is the difference between this fix and an old version > of the code: > > http://cr.openjdk.java.net/~shade/8058643/webrev.01/src/java.base/share/classes/java/lang/String.java.sdiff.html > > I meant: > "if (h == 0 && value.length > 0) {}" > vs > "if (h != 0) {hash = h;}" > > > On 13.05.15 14:51, Claes Redestad wrote: > >> Hi, >> >> 9-b33 introduced a sustained regression in SPECjvm2008 >> xml.transform on a number of our test setups. >> >> JDK-8058643 removed the check on value.length > 0, which >> means repeated calls to "".hashCode() now do a store of the >> calculated value (0) to the hash field. This has potential to >> cause excessive cache coherence traffic in xml.transform[1] >> >> Extracting the code that showed up in profiles to a micro[2] and >> running this in multiple threads is up to 100x slower in 9-b33 on >> a dual-socket machine. >> >> Adding back the check that value.length > 0 before entering the >> calculation loop recuperates the loss in both micro and >> xml.transform, but we're seeing as good or better number by >> simply guarding the store: >> >> Webrev: http://cr.openjdk.java.net/~redestad/8061254/webrev.00/ >> Bug: https://bugs.openjdk.java.net/browse/JDK-8061254 (confidential >> due to links to internal systems, sorry!) >> >> This additionally avoids the field store (and potential for pointless >> cache traffic) also on non-empty strings whose hash value happen >> to equals 0. >> >> Thanks! >> >> /Claes >> >> [1] See >> com.sun.org.apache.xml.internal.dtm.ref.ExpandedNameTable#getExpandedTypeID. >> [2] http://cr.openjdk.java.net/~redestad/8061254/expandedtypeid-micro.zip >> > > > -- > Best regards, Sergey. > > From claes.redestad at oracle.com Wed May 13 13:06:07 2015 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 13 May 2015 15:06:07 +0200 Subject: RFR: 8061254: SPECjvm2008-XML performance regressions in 9-b33 In-Reply-To: References: <55533AA9.7010304@oracle.com> <5553453B.7000800@oracle.com> Message-ID: <55534C3F.3090203@oracle.com> I shouldn't have said better. :-) Running against versions of hashCode using value.length > 0 and h != 0 respectively show results that are within the error range of each other. It's hard to quantify the cost of one extra branch in the slow path, I guess. Checking value.length will only avoid the store for the empty string, but not for other strings with hash==0. For the empty string, we might do one extra compare compare/branch every time we call hashCode, The value.length > 0 check does issue an additional getfield op code for the slow path, avoiding this can be slightly beneficial in some scenarios (even though it shouldn't matter much in the final asm). For reference, this patch (doing if (h != 0) { hash = h; }) nets about a 60x speedup on the micro with -t 32 -p valueString="pollinating sandboxes" on our multi-socket machines over both the 8058643 implementation and the one before it. /Claes On 2015-05-13 14:53, Vitaly Davidovich wrote: > It's interesting that this version performs as good or *better* than > value.length > 0 check. Intuitively, value.length is going to be used > anyway (if h == 0) in the loop and so there should be no penalty of > loading and branching on it (given the change here has a branch > anyway) and compiler can keep that value in a register for the actual > loop. > > Looking at the generated asm for current String.hashCode(), it doesn't > look like compiler is actually using the user-written check to skip > its own check (see the two tests at the bottom of this snippet): > > 0x00007f7e312a0d8c: mov %rsi,%rbx > 0x00007f7e312a0d8f: mov 0x10(%rsi),%eax ;*getfield hash > ; - > java.lang.String::hashCode at 1 (line 1454) > > 0x00007f7e312a0d92: test %eax,%eax > 0x00007f7e312a0d94: jne 0x00007f7e312a0e85 ;*ifne > ; - > java.lang.String::hashCode at 6 (line 1455) > > 0x00007f7e312a0d9a: mov 0xc(%rsi),%ebp ;*getfield value > ; - > java.lang.String::hashCode at 10 (line 1455) > > 0x00007f7e312a0d9d: mov 0xc(%r12,%rbp,8),%r10d ;*arraylength > ; - > java.lang.String::hashCode at 13 (line 1455) > ; implicit exception: > dispatches to 0x00007f7e312a0ea9 > 0x00007f7e312a0da2: test %r10d,%r10d > 0x00007f7e312a0da5: jle 0x00007f7e312a0e91 ;*ifle > ; - > java.lang.String::hashCode at 14 (line 1455) > > 0x00007f7e312a0dab: test %r10d,%r10d > 0x00007f7e312a0dae: jbe 0x00007f7e312a0e95 > > > It does however continue using r10. > > On Wed, May 13, 2015 at 8:36 AM, Sergey Bylokhov > > wrote: > > Just curious, what is the difference between this fix and an old > version of the code: > http://cr.openjdk.java.net/~shade/8058643/webrev.01/src/java.base/share/classes/java/lang/String.java.sdiff.html > > > I meant: > "if (h == 0 && value.length > 0) {}" > vs > "if (h != 0) {hash = h;}" > > > On 13.05.15 14:51, Claes Redestad wrote: > > Hi, > > 9-b33 introduced a sustained regression in SPECjvm2008 > xml.transform on a number of our test setups. > > JDK-8058643 removed the check on value.length > 0, which > means repeated calls to "".hashCode() now do a store of the > calculated value (0) to the hash field. This has potential to > cause excessive cache coherence traffic in xml.transform[1] > > Extracting the code that showed up in profiles to a micro[2] and > running this in multiple threads is up to 100x slower in 9-b33 on > a dual-socket machine. > > Adding back the check that value.length > 0 before entering the > calculation loop recuperates the loss in both micro and > xml.transform, but we're seeing as good or better number by > simply guarding the store: > > Webrev: > http://cr.openjdk.java.net/~redestad/8061254/webrev.00/ > > Bug: https://bugs.openjdk.java.net/browse/JDK-8061254 > (confidential > due to links to internal systems, sorry!) > > This additionally avoids the field store (and potential for > pointless > cache traffic) also on non-empty strings whose hash value happen > to equals 0. > > Thanks! > > /Claes > > [1] See > com.sun.org.apache.xml.internal.dtm.ref.ExpandedNameTable#getExpandedTypeID. > [2] > http://cr.openjdk.java.net/~redestad/8061254/expandedtypeid-micro.zip > > > > > -- > Best regards, Sergey. > > From vitalyd at gmail.com Wed May 13 13:11:45 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Wed, 13 May 2015 09:11:45 -0400 Subject: RFR: 8061254: SPECjvm2008-XML performance regressions in 9-b33 In-Reply-To: <55534C3F.3090203@oracle.com> References: <55533AA9.7010304@oracle.com> <5553453B.7000800@oracle.com> <55534C3F.3090203@oracle.com> Message-ID: Thanks Claes. I think there's some room for improvement in the JIT to piggyback on the user check, but that's a side topic. Out of curiosity, have you tried moving the slow path (computation of the hash) into an out-of-line method? What's the bytecode size if you do that? This shouldn't matter for C2, but I wonder if it may somehow tickle the JIT/register allocator into better codegen. On Wed, May 13, 2015 at 9:06 AM, Claes Redestad wrote: > I shouldn't have said better. :-) > > Running against versions of hashCode using value.length > 0 and h != 0 > respectively show results that are within the error range of each other. > It's > hard to quantify the cost of one extra branch in the slow path, I guess. > > Checking value.length will only avoid the store for the empty string, > but not for other strings with hash==0. For the empty string, we might > do one extra compare compare/branch every time we call hashCode, > > The value.length > 0 check does issue an additional getfield op code for > the slow path, avoiding this can be slightly beneficial in some scenarios > (even though it shouldn't matter much in the final asm). > > For reference, this patch (doing if (h != 0) { hash = h; }) nets about a > 60x speedup on the micro with -t 32 -p valueString="pollinating sandboxes" > on our multi-socket machines over both the 8058643 implementation > and the one before it. > > /Claes > > > On 2015-05-13 14:53, Vitaly Davidovich wrote: > > It's interesting that this version performs as good or *better* than > value.length > 0 check. Intuitively, value.length is going to be used > anyway (if h == 0) in the loop and so there should be no penalty of loading > and branching on it (given the change here has a branch anyway) and > compiler can keep that value in a register for the actual loop. > > Looking at the generated asm for current String.hashCode(), it doesn't > look like compiler is actually using the user-written check to skip its own > check (see the two tests at the bottom of this snippet): > > 0x00007f7e312a0d8c: mov %rsi,%rbx > 0x00007f7e312a0d8f: mov 0x10(%rsi),%eax ;*getfield hash > ; - > java.lang.String::hashCode at 1 (line 1454) > > 0x00007f7e312a0d92: test %eax,%eax > 0x00007f7e312a0d94: jne 0x00007f7e312a0e85 ;*ifne > ; - > java.lang.String::hashCode at 6 (line 1455) > > 0x00007f7e312a0d9a: mov 0xc(%rsi),%ebp ;*getfield value > ; - > java.lang.String::hashCode at 10 (line 1455) > > 0x00007f7e312a0d9d: mov 0xc(%r12,%rbp,8),%r10d ;*arraylength > ; - > java.lang.String::hashCode at 13 (line 1455) > ; implicit exception: > dispatches to 0x00007f7e312a0ea9 > 0x00007f7e312a0da2: test %r10d,%r10d > 0x00007f7e312a0da5: jle 0x00007f7e312a0e91 ;*ifle > ; - > java.lang.String::hashCode at 14 (line 1455) > > 0x00007f7e312a0dab: test %r10d,%r10d > 0x00007f7e312a0dae: jbe 0x00007f7e312a0e95 > > > It does however continue using r10. > > On Wed, May 13, 2015 at 8:36 AM, Sergey Bylokhov < > Sergey.Bylokhov at oracle.com> wrote: > >> Just curious, what is the difference between this fix and an old version >> of the code: >> >> http://cr.openjdk.java.net/~shade/8058643/webrev.01/src/java.base/share/classes/java/lang/String.java.sdiff.html >> >> I meant: >> "if (h == 0 && value.length > 0) {}" >> vs >> "if (h != 0) {hash = h;}" >> >> >> On 13.05.15 14:51, Claes Redestad wrote: >> >>> Hi, >>> >>> 9-b33 introduced a sustained regression in SPECjvm2008 >>> xml.transform on a number of our test setups. >>> >>> JDK-8058643 removed the check on value.length > 0, which >>> means repeated calls to "".hashCode() now do a store of the >>> calculated value (0) to the hash field. This has potential to >>> cause excessive cache coherence traffic in xml.transform[1] >>> >>> Extracting the code that showed up in profiles to a micro[2] and >>> running this in multiple threads is up to 100x slower in 9-b33 on >>> a dual-socket machine. >>> >>> Adding back the check that value.length > 0 before entering the >>> calculation loop recuperates the loss in both micro and >>> xml.transform, but we're seeing as good or better number by >>> simply guarding the store: >>> >>> Webrev: http://cr.openjdk.java.net/~redestad/8061254/webrev.00/ >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8061254 (confidential >>> due to links to internal systems, sorry!) >>> >>> This additionally avoids the field store (and potential for pointless >>> cache traffic) also on non-empty strings whose hash value happen >>> to equals 0. >>> >>> Thanks! >>> >>> /Claes >>> >>> [1] See >>> com.sun.org.apache.xml.internal.dtm.ref.ExpandedNameTable#getExpandedTypeID. >>> [2] >>> http://cr.openjdk.java.net/~redestad/8061254/expandedtypeid-micro.zip >>> >> >> >> -- >> Best regards, Sergey. >> >> > > From roland.westrelin at oracle.com Wed May 13 13:47:45 2015 From: roland.westrelin at oracle.com (Roland Westrelin) Date: Wed, 13 May 2015 15:47:45 +0200 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <5553191F.6080800@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> Message-ID: <882B8D85-62B4-4734-8CA7-0BFD45DB73B3@oracle.com> > http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02/ The hotspot code looks good to me. Roland. From Roger.Riggs at Oracle.com Wed May 13 14:16:39 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 13 May 2015 10:16:39 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <5550CFA1.9010606@Oracle.com> References: <5550CFA1.9010606@Oracle.com> Message-ID: <55535CC7.3000503@Oracle.com> Hi, Are there any comments about the use of java.util.Optional in the ProcessHandle API? Or a review of the changes? Thanks, Roger On 5/11/2015 11:49 AM, Roger Riggs wrote: > Please review clarifications and updates to the proposed Precess API. > > A few loose ends in the ProcessHandle API were identified. > > 1) The ProcessHandle.parent() method currently returns null if the > parent cannot > be determined and the ProcessHandle.of(PID) method returns null if the > PID does not exist. > It has been suggested to return an Optional to make > these methods more flexible and allow a fluent style and work better > with streams. > > 2) The behavior of Processhandle.destroy and destroyForcibly are > different > than Process.destroy and destroyForcibly. Those functions always > succeed because > they are children of the spawning process. > > In contrast, ProcessHandle.destroy and destroyForcible are requests to > destroy the process and may not succeed due to operating system > restrictions such > as the process not being a child or not having enough privilege. > The description of the methods needs to be clarified that it is a > request to destroy > and it may not succeed, In that case the destroy and destroyForcibly > methods > should indicate that the request was not successful. In particular, > the caller > may not want to wait for the process to terminate (its not going to). > > The proposed update is to return an Optional . > It can be streamed and can take advantage of the conditional > operations on the Optional. > > 3) Using Optional is also attractive for the return values of the > information > about a ProcessHandles, since not all values are available from every OS. > The returns values of Info.command, arguments, startInstant, > totalDuration, and user > are proposed to be updated to return Optional. > It allows for more compact code and fewer explicit checks for null. > > Please review and comment: > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-ph/ > > javadoc: > http://cr.openjdk.java.net/~rriggs/ph-apidraft/ > > Diffs of the spec/javadoc from previous draft: > http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-11/overview-summary.html > > > Thanks, Roger > > > From Alan.Bateman at oracle.com Wed May 13 14:55:31 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 13 May 2015 15:55:31 +0100 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <55535CC7.3000503@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> Message-ID: <555365E3.2020700@oracle.com> On 13/05/2015 15:16, Roger Riggs wrote: > Hi, > > Are there any comments about the use of java.util.Optional in the > ProcessHandle API? > Or a review of the changes? Having parent return Optional looks good. Having all methods in ProcessHandle.Info return Optional is probably right, it gives us a bit more flexibility compared to info() returning Optional. I'm not sure abut the destory* methods, the result of a destroy is essentially a boolean so this feels a little odd. -Alan. From paul.sandoz at oracle.com Wed May 13 14:56:37 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 13 May 2015 16:56:37 +0200 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <55533CAE.3050201@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> <55533CAE.3050201@oracle.com> Message-ID: On May 13, 2015, at 1:59 PM, Vladimir Ivanov wrote: > Peter, Paul, thanks for the feedback! > > Updated the webrev in place: > http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 > +1 >> I am not an export in the HS area but the code mostly made sense to me. I also like Peter's suggestion of Context implementing Runnable. > I agree. Integrated. > >> Some minor comments. >> >> CallSite.java: >> >> 145 private final long dependencies = 0; // Used by JVM to store JVM_nmethodBucket* >> >> It's a little odd to see this field be final, but i think i understand the motivation as it's essentially acting as a memory address pointing to the head of the nbucket list, so in Java code you don't want to assign it to anything other than 0. > Yes, my motivation was to forbid reads & writes of the field from Java code. I was experimenting with injecting the field by VM, but it's less attractive. > I was wondering if that were possible. >> Is VM access, via java_lang_invoke_CallSite_Context, affected by treating final fields as really final in the j.l.i package? > No, field modifiers aren't respected. oopDesc::*_field_[get|put] does a raw read/write using field offset. > Ok. Paul. From Roger.Riggs at Oracle.com Wed May 13 15:10:57 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 13 May 2015 11:10:57 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555365E3.2020700@oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555365E3.2020700@oracle.com> Message-ID: <55536981.80505@Oracle.com> Hi Alan, Yes, the destroy use looks a bit odd. In Process, destroyForcibly returns this so that the application can fluently wait for the termination to complete. Returning Optional enables the case to fluently perform an action on the process when it does exit. ProcessHandle ph = ...; ph.destroy().ifPresent(p -> p.onExit( ...)); Optional.isPresent() provides a boolean if that's needed. Thanks, Roger On 5/13/2015 10:55 AM, Alan Bateman wrote: > On 13/05/2015 15:16, Roger Riggs wrote: >> Hi, >> >> Are there any comments about the use of java.util.Optional in the >> ProcessHandle API? >> Or a review of the changes? > Having parent return Optional looks good. > > Having all methods in ProcessHandle.Info return Optional is probably > right, it gives us a bit more flexibility compared to info() returning > Optional. > > I'm not sure abut the destroy* methods, the result of a destroy is > essentially a boolean so this feels a little odd. > > -Alan. From chris.hegarty at oracle.com Wed May 13 15:17:32 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 13 May 2015 16:17:32 +0100 Subject: Changes fro JDK-8075327: moving jdk testlibraty files duplicated in hotspot to the common test repository In-Reply-To: <1b2aa136-3d8b-4c3c-ab80-405346898578@default> References: <1b2aa136-3d8b-4c3c-ab80-405346898578@default> Message-ID: <55536B0C.1070604@oracle.com> Hi Alexander, On 13/05/15 15:52, Alexander Kulyakhtin wrote: > Hi, > > Could you please, review the following tests-only changes to the hs-rt/jdk and hs-rt/test repositories. These changes are a part of the changes for "JDK-8075327: Merge jdk and hotspot test libraries" I suspect that these changes are best going directly into jdk9/dev, as opposed to a a downstream forest. > The changes are as follows: > > http://cr.openjdk.java.net/~akulyakh/8075327/jdk_patch/webrev/ In may places '@library /lib/testlibrary ...' remains. Is this redundant, in many tests? If so, it be removed. > http://cr.openjdk.java.net/~akulyakh/8075327/test_patch/webrev/ > > 1) Renaming jdk.testlibrary package to jdk.test.lib in the hs-rt/jdk repo, so it has the same name as the jdk.test.lib package in the hotspot repo. > > 2) Several files from the jdk/testlibrary have duplicates in the hotspot/testlibrary. We are moving those files from jdk/testlibrary to the upper-level hs-rt/test The changes are to the 'test' directory in the "top" repo? You are not proposing to add a new repo, right? test/lib/testlibrary/jdk/testlibrary/RandomFactory.java was updated recently in jdk9/dev. The version in your webrev is a little out of date. Is there any special update needed to jtreg to support this? > so they can be shared by jdk and hotspot (also updating @library directives to reflect that). > > If these proposed changes are acceptable then we'll merge the duplicates between the hs-rt/hotspot and hs-rt/test/lib files into hs-rt/test/lib and prepare a full review. > > Thank you very much for the review. > > Best regards, > Alexander -Chris. From pavel.rappo at oracle.com Wed May 13 15:29:04 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 13 May 2015 16:29:04 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Message-ID: > It now can be reviewed as usual at: > > http://cr.openjdk.java.net/~prappo/8080272/webrev.00/ > > Feel free to review. Thanks. Let me start then. 1. I've seen several cases where current behaviour while ((n = in.read(buffer)) > 0) ~~~ has been changed to while ((read = this.read(buffer, 0, TRANSFER_BUFFER_SIZE)) >= 0) ~~~ Those things jump out at you, but don't seem to be harmful, since the only case where: java.io.InputStream.read(byte[], int off, int len) java.io.InputStream#read(byte[]) may return 0, is when len == 0. And it's never the case here. Unless, of course, some misbehaving implementation of InputStream is used. 2. jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java Some of the refactored methods there seem to be unused: getBytesFromFile(String) writeBytesToFilename(String, byte[]) Should we remove them instead? 3. Thanks to Patrick I've learned AutoCloseable s = ... try (s) { ~~~ } is not a bug, but new javac 9 feature [1]. Learned it the hard way. 4. I wonder if javax.management.loading.MLet.loadLibraryAsResource and sun.net.www.MimeLauncher.run could be refactored with more appropriate Files.copy(is, file.toPath()) as it seems to fit there perfectly. 5. Now we don't need the com.sun.media.sound.StandardMidiFileWriter.bufferSize after we removed its sole client. 6. I've run into several cases where code use explicit `flush()` for ByteArrayOutputStream, BufferedOutputStream. For the former one it's never needed. The latter one does it automatically on `close()`. Should we still call them? 7. org.jcp.xml.dsig.internal.dom.Utils.readBytesFromStream is a little bit awkward since it used 1024 as some sort of a cut-off. It might've had something to do with EOF detection, but I'm not sure. 8. jdk/src/java.desktop/windows/classes/sun/print/Win32PrintJob.java } catch (FileNotFoundException fnfe) { notifyEvent(PrintJobEvent.JOB_FAILED); throw new PrintException(fnfe.toString()); } catch (IOException ioe) { notifyEvent(PrintJobEvent.JOB_FAILED); throw new PrintException(ioe.toString()); } It seems ok to remove the FileNotFoundException branch. Or I'm missing something. 9. I don't think I would agree with some changes in sun.net.www.MimeLauncher.run as they obviously make the new version not equivalent to the old one. Non swallowed IOException, additional null check. Way too much for the cleanup change. Summary ------- The change seems ok to me, given that (7, 9) are justified or fixed. Patrick needs a _R_eviewer for his changes to be accepted. Please help him with this. ------------------------------------------------------------------------------- [1] https://blogs.oracle.com/darcy/entry/concise_twr_jdk9 From mandy.chung at oracle.com Wed May 13 15:53:41 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 13 May 2015 08:53:41 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55526FF5.9000509@gmail.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> <55526FF5.9000509@gmail.com> Message-ID: > On May 12, 2015, at 2:26 PM, Peter Levart wrote: > > > > On 05/12/2015 10:49 PM, Mandy Chung wrote: >>> But I think it should be pretty safe to make the java.util.Properties object override all Hashtable methods and delegate to internal CMH so that: >>> - all modification methods + all bulk read methods such as (keySet().toArray, values.toArray) are made synchronized again >>> - individual entry read methods (get, containsKey, ...) are not synchronized. >>> >>> This way we get the benefits of non-synchronized read access but the change is hardly observable. In particular since external synchronization on the Properties object makes guarded code atomic like it is now and individual entry read accesses are almost equivalent whether they are synchronized or not and I would be surprised if any code using Properties for the purpose they were designed for worked any differently. >> >> I agree that making read-only methods not synchronized while keeping any method with write-access with synchronized is pretty safe change and low compatibility risk. On the other hand, would most of the overrridden methods be synchronized then? > > Yes, and that doesn't seem to be a problem. Setting properties is not very frequent operation and is usually quite localized. Reading properties is, on the other hand, a very frequent operation dispersed throughout the code (almost like logging) and therefore very prone to deadlocks like the one in this issue. I think that by having an unsynchronized get(Property), most problems with Properties will be solved - deadlock and performance (scalability) related. I?m keen on cleaning up the system properties but it is a bigger scope as it should take other related enhancement requests into account that should be something for future. I think what you propose seems a good solution to fix JDK-8029891 while it doesn?t completely get us off the deadlock due to user code locking the Properties object. Thanks. Mandy From alexander.kulyakhtin at oracle.com Wed May 13 14:52:20 2015 From: alexander.kulyakhtin at oracle.com (Alexander Kulyakhtin) Date: Wed, 13 May 2015 07:52:20 -0700 (PDT) Subject: Changes fro JDK-8075327: moving jdk testlibraty files duplicated in hotspot to the common test repository Message-ID: <1b2aa136-3d8b-4c3c-ab80-405346898578@default> Hi, Could you please, review the following tests-only changes to the hs-rt/jdk and hs-rt/test repositories. These changes are a part of the changes for "JDK-8075327: Merge jdk and hotspot test libraries" The changes are as follows: http://cr.openjdk.java.net/~akulyakh/8075327/jdk_patch/webrev/ http://cr.openjdk.java.net/~akulyakh/8075327/test_patch/webrev/ 1) Renaming jdk.testlibrary package to jdk.test.lib in the hs-rt/jdk repo, so it has the same name as the jdk.test.lib package in the hotspot repo. 2) Several files from the jdk/testlibrary have duplicates in the hotspot/testlibrary. We are moving those files from jdk/testlibrary to the upper-level hs-rt/test so they can be shared by jdk and hotspot (also updating @library directives to reflect that). If these proposed changes are acceptable then we'll merge the duplicates between the hs-rt/hotspot and hs-rt/test/lib files into hs-rt/test/lib and prepare a full review. Thank you very much for the review. Best regards, Alexander From alexander.kulyakhtin at oracle.com Wed May 13 15:46:04 2015 From: alexander.kulyakhtin at oracle.com (Alexander Kulyakhtin) Date: Wed, 13 May 2015 08:46:04 -0700 (PDT) Subject: Changes fro JDK-8075327: moving jdk testlibraty files duplicated in hotspot to the common test repository Message-ID: <5e28a49a-4ff3-43b4-8e02-7bfe73f0bfd6@default> Hi Chris, > I suspect that these changes are best going directly into jdk9/dev, as > opposed to a a downstream forest. Yes, they are going directly to jdk9/dev, I forgot to add the group, adding now. > In may places '@library /lib/testlibrary ...' remains. Is this > redundant, in many tests? If so, it be removed. No, this is mostly not redundant, as the jdk/testlibrary comntains many files specific for jdk only. Only a relatively small number of files are duplicated between hotspot and jdk. >The changes are to the 'test' directory in the "top" repo? You are not >proposing to add a new repo, right? No, we are not proposing a new repo. The changes are in the 'top' repo. >test/lib/testlibrary/jdk/testlibrary/RandomFactory.java was updated >recently in jdk9/dev. The version in your webrev is a little out of date. We are going to upmerge the changes then >Is there any special update needed to jtreg to support this? For thse changes no jtreg update is required. However, there are plans for the jtreg to prohibit referencing any @libraries above the repo root unless such libraries are directly specified in TEST.properties If jtreg thus prohibits our using /../../test/lib (because it's above the root) we will have to additionally make a change to jdk and hotspot TEST.properties Best regards, Alexander From alexander.kulyakhtin at oracle.com Wed May 13 15:48:48 2015 From: alexander.kulyakhtin at oracle.com (Alexander Kulyakhtin) Date: Wed, 13 May 2015 08:48:48 -0700 (PDT) Subject: Changes fro JDK-8075327: moving jdk testlibraty files duplicated in hotspot to the common test repository Message-ID: <15629659-f6ca-4ad4-8458-9174f8ce473f@default> Adding jdk9-dev mailing list ----- Original Message ----- From: alexander.kulyakhtin at oracle.com To: core-libs-dev at openjdk.java.net, awt-dev at openjdk.java.net, hotspot-dev at openjdk.java.net Cc: stefan.sarne at oracle.com, yekaterina.kantserova at oracle.com, alan.bateman at oracle.com Sent: Wednesday, May 13, 2015 5:52:20 PM GMT +03:00 Iraq Subject: Changes fro JDK-8075327: moving jdk testlibraty files duplicated in hotspot to the common test repository Hi, Could you please, review the following tests-only changes to the hs-rt/jdk and hs-rt/test repositories. These changes are a part of the changes for "JDK-8075327: Merge jdk and hotspot test libraries" The changes are as follows: http://cr.openjdk.java.net/~akulyakh/8075327/jdk_patch/webrev/ http://cr.openjdk.java.net/~akulyakh/8075327/test_patch/webrev/ 1) Renaming jdk.testlibrary package to jdk.test.lib in the hs-rt/jdk repo, so it has the same name as the jdk.test.lib package in the hotspot repo. 2) Several files from the jdk/testlibrary have duplicates in the hotspot/testlibrary. We are moving those files from jdk/testlibrary to the upper-level hs-rt/test so they can be shared by jdk and hotspot (also updating @library directives to reflect that). If these proposed changes are acceptable then we'll merge the duplicates between the hs-rt/hotspot and hs-rt/test/lib files into hs-rt/test/lib and prepare a full review. Thank you very much for the review. Best regards, Alexander From aph at redhat.com Wed May 13 16:14:02 2015 From: aph at redhat.com (Andrew Haley) Date: Wed, 13 May 2015 17:14:02 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5550D7FE.4030903@redhat.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> Message-ID: <5553784A.4030607@redhat.com> On 05/11/2015 05:25 PM, Andrew Haley wrote: > On 05/11/2015 04:39 PM, Alan Bateman wrote: >> On 11/05/2015 15:14, Andrew Haley wrote: >>> I mixed up my nextPutIndex and nextGetIndex. Sorry. >>> >>> http://cr.openjdk.java.net/~aph/8079459/ >>> >>> This is also the cause of Bug https://bugs.openjdk.java.net/browse/JDK-8079860 >>> >> This looks good, easy to miss when looking at a big patch. >> >> It would be good to extend the test coverage. In this case it was caught >> by JCK so not an OpenJDK test. Test coverage is here extended to include boundary conditions for all primitive types: Fix: http://cr.openjdk.java.net/~aph/8079459-2-jdk/ Testcase: http://cr.openjdk.java.net/~aph/8079459-2-hs/ Andrew. From pavel.rappo at oracle.com Wed May 13 16:19:11 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 13 May 2015 17:19:11 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> Message-ID: <015B4FE1-CFEE-4090-8EE2-F15F21E2B3BD@oracle.com> If you have time it might be useful to have a look for places to retrofit with java.nio.file.Files This class provides lots of useful tools which cover many usecases. Especially take a look at `copy` methods. Thanks! -Pavel > On 12 May 2015, at 23:10, Patrick Reinhart wrote: > > Hi Pavel, > > Is there anything I can do in the meantime? > > Unfortunately I do not have no account on cr.openjdk.java.net, so I need to paste the patch to the mailing list directly. > > Cheers Patrick From chris.hegarty at oracle.com Wed May 13 16:48:02 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 13 May 2015 17:48:02 +0100 Subject: Changes fro JDK-8075327: moving jdk testlibraty files duplicated in hotspot to the common test repository In-Reply-To: <5e28a49a-4ff3-43b4-8e02-7bfe73f0bfd6@default> References: <5e28a49a-4ff3-43b4-8e02-7bfe73f0bfd6@default> Message-ID: <34348D14-9BBC-40E6-A1DB-923D88AFCD90@oracle.com> Alexander, > On 13 May 2015, at 16:46, Alexander Kulyakhtin wrote: > > Hi Chris, > > >> I suspect that these changes are best going directly into jdk9/dev, as >> opposed to a a downstream forest. > Yes, they are going directly to jdk9/dev, I forgot to add the group, adding now. > >> In may places '@library /lib/testlibrary ...' remains. Is this >> redundant, in many tests? If so, it be removed. > No, this is mostly not redundant, as the jdk/testlibrary comntains many files specific for jdk only. Only a relatively small number of files are duplicated between hotspot and jdk. Right, but mostly is not all. For example test/com/sun/net/httpserver/Test1.java should no longer include @library /lib/testlibrary. It depends only on SimpleSSLContext which is being moved. It is easy to see this by looking at the imports. Whatever script you have for updating these tests should also remove redundant values in the @library tag. I suspect there are a significant number of these ( a lot of tests just use one library class ). Just on that, is it for a library class to indicate that it depends on a class from another library? I believe this is the case for some library utilities. How can a test know this. It needs to be a library class that indicates this dependency.I see nothing in the webrev for this ( or maybe I missed it ). -Chris. > >> The changes are to the 'test' directory in the "top" repo? You are not >> proposing to add a new repo, right? > No, we are not proposing a new repo. The changes are in the 'top' repo. > >> test/lib/testlibrary/jdk/testlibrary/RandomFactory.java was updated >> recently in jdk9/dev. The version in your webrev is a little out of date. > We are going to upmerge the changes then > >> Is there any special update needed to jtreg to support this? > For thse changes no jtreg update is required. > However, there are plans for the jtreg to prohibit referencing any @libraries above the repo root unless such libraries are directly specified in TEST.properties > If jtreg thus prohibits our using /../../test/lib (because it's above the root) we will have to additionally make a change to jdk and hotspot TEST.properties > > Best regards, > Alexander From alexander.kulyakhtin at oracle.com Wed May 13 17:08:29 2015 From: alexander.kulyakhtin at oracle.com (Alexander Kulyakhtin) Date: Wed, 13 May 2015 10:08:29 -0700 (PDT) Subject: Changes for JDK-8075327: moving jdk testlibraty files duplicated in hotspot to the common test repository Message-ID: Chris, Following the feedback from Jon Gibbons, we have changed our current plan to the following: 1) We are waiting till the new jtreg is promoted. The new jtreg allows for specifying in the repository's TEST.properties file one or more paths to search for libraries 2) After the jtreg is out we are adding both path to jdk/testlibrary and path to toplevel/test/lib/share library to the jdk and hotspot TEST.properties files Under those testlibrary roots we are rearranging the directories to have the same jdk/test/lib structure (to provide for the jdk.test.lib package) 3) Same as with the current changes we are changing import package jdk.testlib.* to import package jdk.test.lib.* in the jdk and hotspot tests. This way, if the jtreg does not find a required class from the jdk.test.lib in the jdk/testlibrary it will look for it in the toplevel/test/lib/share test library. The same will be done for the hotspot tests. Best regards, Alexander ----- Original Message ----- From: chris.hegarty at oracle.com To: alexander.kulyakhtin at oracle.com Cc: core-libs-dev at openjdk.java.net, awt-dev at openjdk.java.net, stefan.sarne at oracle.com, yekaterina.kantserova at oracle.com, hotspot-dev at openjdk.java.net, jdk9-dev at openjdk.java.net Sent: Wednesday, May 13, 2015 7:48:06 PM GMT +03:00 Iraq Subject: Re: Changes fro JDK-8075327: moving jdk testlibraty files duplicated in hotspot to the common test repository Alexander, > On 13 May 2015, at 16:46, Alexander Kulyakhtin wrote: > > Hi Chris, > > >> I suspect that these changes are best going directly into jdk9/dev, as >> opposed to a a downstream forest. > Yes, they are going directly to jdk9/dev, I forgot to add the group, adding now. > >> In may places '@library /lib/testlibrary ...' remains. Is this >> redundant, in many tests? If so, it be removed. > No, this is mostly not redundant, as the jdk/testlibrary comntains many files specific for jdk only. Only a relatively small number of files are duplicated between hotspot and jdk. Right, but mostly is not all. For example test/com/sun/net/httpserver/Test1.java should no longer include @library /lib/testlibrary. It depends only on SimpleSSLContext which is being moved. It is easy to see this by looking at the imports. Whatever script you have for updating these tests should also remove redundant values in the @library tag. I suspect there are a significant number of these ( a lot of tests just use one library class ). Just on that, is it for a library class to indicate that it depends on a class from another library? I believe this is the case for some library utilities. How can a test know this. It needs to be a library class that indicates this dependency.I see nothing in the webrev for this ( or maybe I missed it ). -Chris. > >> The changes are to the 'test' directory in the "top" repo? You are not >> proposing to add a new repo, right? > No, we are not proposing a new repo. The changes are in the 'top' repo. > >> test/lib/testlibrary/jdk/testlibrary/RandomFactory.java was updated >> recently in jdk9/dev. The version in your webrev is a little out of date. > We are going to upmerge the changes then > >> Is there any special update needed to jtreg to support this? > For thse changes no jtreg update is required. > However, there are plans for the jtreg to prohibit referencing any @libraries above the repo root unless such libraries are directly specified in TEST.properties > If jtreg thus prohibits our using /../../test/lib (because it's above the root) we will have to additionally make a change to jdk and hotspot TEST.properties > > Best regards, > Alexander From Alan.Bateman at oracle.com Wed May 13 18:35:38 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 13 May 2015 19:35:38 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5553784A.4030607@redhat.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> <5553784A.4030607@redhat.com> Message-ID: <5553997A.7030401@oracle.com> On 13/05/2015 17:14, Andrew Haley wrote: > : > Test coverage is here extended to include boundary conditions for all primitive > types: > > Fix: > > http://cr.openjdk.java.net/~aph/8079459-2-jdk/ > > Testcase: > > http://cr.openjdk.java.net/~aph/8079459-2-hs/ > Thanks for expanding the test coverage, just awkward to have the tests split between the hotspot/compiler tree and jdk/test/java/nio/Buffer. A few passing comments on the test - Is errors incremented anywhere? - You could reduce the code a bit by catching Throwable once. Also would be good to have it be the cause for the RuntimeException so that the original exception/error isn't lost. - Personally I would reduce the line length but this area might be okay with very long lines. -Alan. From derek.white at oracle.com Wed May 13 20:34:26 2015 From: derek.white at oracle.com (Derek White) Date: Wed, 13 May 2015 16:34:26 -0400 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55527935.5010408@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> Message-ID: <5553B552.9060900@oracle.com> Hi Peter, I don't have smoking gun evidence that your change introduces a bug, but I have some concerns... On 5/12/15 6:05 PM, Peter Levart wrote: > Hi Dmitry, > > You iterate the queue then, not the unfinalized list. That's more logical. > > Holding the queue's lock may pause reference handler and finalizer > threads for the entire time of iteration. This can blow up the > application. Suppose one wants to diagnose the application because he > suspects that finalizer thread hardly keeps up with production of > finalizable instances. This can happen if the allocation rate of > finalizable objects is very high and/or finalize() methods are not > coded to be fast enough. Suppose the queue of Finalizer(s) builds up > gradually and is already holding several million objects. Now you > initiate the diagnostic command to print the queue. The iteration over > and grouping/counting of several millions of Finalizer(s) takes some > time. This blocks finalizer thread and reference handler thread. But > does not block the threads that allocate finalizable objects. By the > time the iteration is over, the JVM blows up and application slows > down to a halt doing GCs most of the time, getting OOMEs, etc... > > It is possible to iterate the elements of the queue for diagnostic > purposes without holding a lock. The modification required to do that > is the following (havent tested this, but I think it should work): > > http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ > One issue to watch out for is the garbage collectors inspect the Reference.next field from C code directly (to distinguish active vs. pending, iterate over oops, etc.). You can search hotspot for java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. Your change makes "inactive" References superficially look like "enqueued" References. The GC code is rather subtle and I haven't yet seen a case where it would get confused by this change, but there could easily be something like that lurking in the GC code. > I also suggest the addition to the ReferenceQueue to be contained > (package-private) and as generic as possible. That's why I suggest > forEach iteration method with no concrete logic. > > It would be possible to encapsulate the entire logic into a special > package-private class (say java.lang.ref.DiagnosticCommands) with > static method(s) (printFinalizationQueue)... You could just expose a > package-private forEach static method from Finalizer and code the rest > in DiagnosticCommands. That's good for encapsulation. But I'm concerned that if "forEach" got exposed beyond careful use in DiagnosticCommands, and the Referents were leaked back into the heap, then we could get unexpected object resurrection after finalization. This isn't a bug on it's own - any finalizer might resurrect its object if not careful, but ordinarily /only/ the finalizer could resurrect the object. This could invalidate application invariants? I agree that using a lock over the ReferenceQueue iteration opens up /another/ case of diagnostics affecting application behavior. And there are pathological scenarios where this gets severe. This is unfortunate but not uncommon. There is enough complication here that you should be sure that the fix for diagnostics performance doesn't introduce subtle bugs to the system in general. A change in this area should get a thorough review from both the runtime and GC sides. Better yet, the reference handling code in GC and runtime should probably be thrown out and re-written, but that's another issue :-) - Derek > Regards, Peter > > > On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >> Everybody, >> >> Updated version: >> >> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >> >> Now it iterates over queue and output result sorted by number of instances. >> >> -Dmitry >> >> On 2015-05-07 00:51, Derek White wrote: >>> Hi Dmitry, Staffan, >>> >>> Lots of good comments here. >>> >>> On the topic of what list should be printed out, I think we should focus >>> on objects waiting to be finalized - e.g. the contents of the >>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>> could add a summerizeQueue(TreeMap) method, or a >>> general iterator and lambda. >>> >>> A histogram of objects with finalize methods might also be interesting, >>> but you can get most of the same information from a heap histogram >>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>> >>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>> FinalizerThread from making progress (and I think there's a GC thread >>> that runs after GC that sorts found References objects that need >>> processing into their respective ReferenceQueues). But locking the >>> "unfinalized" list blocks initializing any object with a finalize() method. >>> >>> The sorting suggestion is a nice touch. >>> >>> - Derek White, GC team >>> >>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>> Hi Dmitry, Staffan, >>>> >>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>> Dmitry, >>>>> >>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>> well considering the changes to Finalizer. >>>>> >>>>> I?m a little worried about the potentially very large String that is >>>>> returned from printFinalizationQueue(). A possible different approach >>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>> That would allow for outputting one line at a time. The output would >>>>> still be saved in memory (since the stream is buffered), but at least >>>>> the data is only saved once in memory, then. It would make the code a >>>>> bit harder to write, so its a question of how scared we are of >>>>> running out of memory. >>>> If the output is just a histogram of # of instances per class name, >>>> then it should not be too large, as there are not many different >>>> classes overriding finalize() method (I counted 72 overriddings of >>>> finalize() method in the whole jdk/src tree). >>>> >>>> I'm more concerned about the fact that while traversing the list, a >>>> lock is held, which might impact prompt finalization(). Is it >>>> acceptable for diagnostic output to impact performance and/or >>>> interfere with synchronization? >>>> >>>> It might be possible to scan the list without holding a lock for >>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>> Finalizer.next pointer to point back to itself: >>>> >>>> private void remove() { >>>> synchronized (lock) { >>>> if (unfinalized == this) { >>>> if (this.next != null) { >>>> unfinalized = this.next; >>>> } else { >>>> unfinalized = this.prev; >>>> } >>>> } >>>> if (this.next != null) { >>>> this.next.prev = this.prev; >>>> } >>>> if (this.prev != null) { >>>> this.prev.next = this.next; >>>> } >>>> // this.next = this; must not be set so that we can >>>> traverse the list unsynchronized >>>> this.prev = this; /* Indicates that this has been >>>> finalized */ >>>> } >>>> } >>>> >>>> For detecting whether a Finalizer is already processed, the 'prev' >>>> pointer could be used instead: >>>> >>>> private boolean hasBeenFinalized() { >>>> return (prev == this); >>>> } >>>> >>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>> unsynchronized printFinalizationQueue() would get you a fully >>>> initialized Finalizer instance (in particular the next pointer), you >>>> would have to make the 'unfinalized' field volatile or insert an >>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>> >>>> private void add() { >>>> synchronized (lock) { >>>> if (unfinalized != null) { >>>> this.next = unfinalized; >>>> unfinalized.prev = this; >>>> } >>>> // make sure a data race dereferencing 'unfinalized' >>>> // in printFinalizationQueue() does see the Finalizer >>>> // instance fully initialized >>>> // (in particular the 'next' pointer) >>>> U.storeFence(); >>>> unfinalized = this; >>>> } >>>> } >>>> >>>> >>>> By doing these modifications, I think you can remove >>>> synchronized(lock) {} from printFinalizationQueue(). >>>> >>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>> not sure of the difference, perhaps someone from the GC team can help >>>>> out? >>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>> instances pending processing by finalizer thread because their >>>> referents are eligible for finalization (they are not reachable any >>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>> instances for which their referents have not been finalized yet >>>> (including those that are still reachable and alive). The later serves >>>> two purposes: >>>> - it keeps Finalizer instances reachable until they are processed >>>> - it is a source of unfinalized instances for >>>> running-finalizers-on-exit if requested by >>>> System.runFinalizersOnExit(true); >>>> >>>> So it really depends on what one would like to see. Showing the queue >>>> may be interesting if one wants to see how the finalizer thread is >>>> coping with processing the finalize() invocations. Showing unfinalized >>>> list may be interesting if one wants to know how many live + >>>> finalization pending instances are there on the heap that override >>>> finalize() method. >>>> >>>> Regards, Peter >>>> >>>>> For the output, it would be a nice touch to sort it on the number of >>>>> references for each type. Perhaps outputting it more like a table >>>>> (see the old code again) would also make it easier to digest. >>>>> >>>>> In diagnosticCommand.hpp, the new commands should override >>>>> permission() and limit access: >>>>> >>>>> static const JavaPermission permission() { >>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>> "monitor", NULL}; >>>>> return p; >>>>> } >>>>> >>>>> The two tests don?t validate the output in any way. Would it be >>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>> the finalizer queue? Hmm. >>>>> >>>>> Thanks, >>>>> /Staffan >>>>> >>>>> >>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>> wrote: >>>>>> >>>>>> Everyone, >>>>>> >>>>>> Please review the fix: >>>>>> >>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>> >>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>> >>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>> with count >>>>>> >>>>>> -Dmitry >>>>>> >>>>>> -- >>>>>> Dmitry Samersoff >>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>> * I would love to change the world, but they won't give me the sources. > From ivan.gerasimov at oracle.com Wed May 13 21:25:19 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 14 May 2015 00:25:19 +0300 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> Message-ID: <5553C13F.5080900@oracle.com> Hi Martin! On 13.05.2015 0:22, Martin Buchholz wrote: > All your changes look good. But: > > --- > Not your bug, but it looks like the below should instead be: > throw new StringIndexOutOfBoundsException(beginIndex); > Perhaps fix in a follow-on change. > > 1935 if (subLen < 0) { > 1936 throw new StringIndexOutOfBoundsException(subLen); > I guess, it was done so in order to make the error messages consistent for str.substring(tooBigIndex) and str.substring(tooBigIndex, str.length). There are also other places, where StringIndexOutOfBoundsException() is passed a (wrong) distance, not an index. It might be a good mini-project to make all the IndexOutOfBounds error messages uniform and fully informative, I'll file a RFE for this. > --- > We seem to have clean progress, but for substring fast-path we can do > a little better, I think, thus: > > public String substring(int beginIndex, int endIndex) { > int subLen; > return ((beginIndex | (value.length - endIndex)) > 0 > && (subLen = endIndex - beginIndex) > 0) > ? new String(value, beginIndex, subLen) > : substringSlowPath(beginIndex, endIndex); > } > > private String substringSlowPath(int beginIndex, int endIndex) { > if (beginIndex <= 0) { > if (beginIndex < 0) { > throw new StringIndexOutOfBoundsException(beginIndex); > } > if (endIndex == value.length) { > return this; > } > } > if (endIndex > value.length) { > throw new StringIndexOutOfBoundsException(endIndex); > } > if (endIndex == beginIndex) { > return ""; > } > throw new StringIndexOutOfBoundsException(endIndex - beginIndex); > } > > additional white-box tests would be required if we adopt that. > I think this is great, and it's lot of fun to rewrite the checks this way, but I have concerns. First, I think this style would reduce readability of the code. Second, it's not obvious to me that such combined check will always be faster. I did some experimenting with jmh, and the results are unclear. For example, please take a look at the following three tests: @State(Scope.Benchmark) public class MyBenchmark { static char[] buff = new char[12]; @Benchmark public void testMethod_1() { substring_1(1, 10, buff); } void substring_1(int from, int to, char[] buff) { if ((from < 0) || (to > buff.length) || (from > to)) throw new Error(); } @Benchmark public void testMethod_2() { substring_2(1, 10, buff); } void substring_2(int from, int to, char[] buff) { if ((from | (buff.length - to) | (to - from)) < 0) throw new Error(); } @Benchmark public void testMethod_3() { substring_3(1, 10, buff); } void substring_3(int from, int to, char[] buff) { int len; if ((from | (buff.length - to)) < 0 || (len = (to - from)) < 0) throw new Error(); } } Benchmark Mode Cnt Score Error Units MyBenchmark.testMethod_1 thrpt 60 1132911599.680 ? 42375177.640 ops/s MyBenchmark.testMethod_2 thrpt 60 813737659.576 ? 14226427.823 ops/s MyBenchmark.testMethod_3 thrpt 60 810406621.145 ? 12316864.045 ops/s The plain old ||-combined check was faster in this round. Some other tests showed different results. The speed seems to depend on the scope of the checked variables and complexity of the expressions to calculate. However, I still don't have a clear understanding of all the aspects we need to pay attention to when doing such optimizations. My third concern is this: Wouldn't it be possible to implement this type of optimization at jvm level? At least some conditions can automatically be combined into one. Given the information about which execution path is expected to be fast, hotspot should be able to quickly perform that one combined condition check and move to the fast path in most situations. Sincerely yours, Ivan From forax at univ-mlv.fr Wed May 13 21:45:10 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 13 May 2015 23:45:10 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> Message-ID: <5553C5E6.3020902@univ-mlv.fr> On 05/13/2015 05:29 PM, Pavel Rappo wrote: >> It now can be reviewed as usual at: >> >> http://cr.openjdk.java.net/~prappo/8080272/webrev.00/ >> >> Feel free to review. Thanks. > Let me start then. > > 1. I've seen several cases where current behaviour > > while ((n = in.read(buffer)) > 0) > ~~~ > has been changed to > > while ((read = this.read(buffer, 0, TRANSFER_BUFFER_SIZE)) >= 0) > ~~~ > > Those things jump out at you, but don't seem to be harmful, since the only case > where: > > java.io.InputStream.read(byte[], int off, int len) > java.io.InputStream#read(byte[]) > > may return 0, is when len == 0. And it's never the case here. Unless, of course, > some misbehaving implementation of InputStream is used. The other reason to have read that returns 0 is if the underlying channel is in non-blocking mode. A read on an InputStream created by Channels.newInputStream on a SelectableChannel may return 0 and the code will go in a loop until the SelectableChannel can read something. while(read() > 0) avoid that issue. The other things that may be a problem with this patch is that a lot of codes replaced by transferTo use either a bigger or a smaller size of buffer than transferTo. Given that we don't know if the buffer size is something important for a code or if the buffer size can be changed, i think it's better to split this patch in several parts and to send each parts to the right mailing list. regards, R?mi From derek.white at oracle.com Wed May 13 21:52:33 2015 From: derek.white at oracle.com (Derek White) Date: Wed, 13 May 2015 17:52:33 -0400 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55523418.5010708@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> Message-ID: <5553C7A1.8060004@oracle.com> Hi Dmitry, Some review comments below... On 5/12/15 1:10 PM, Dmitry Samersoff wrote: > Everybody, > > Updated version: > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ > > Now it iterates over queue and output result sorted by number of instances. FinalReference.java - Update copyright to 2015. ReferenceQueue.java - Update copyright to 2015. class "mutableInt": - Should be "MutableInt" - Not a collections lawyer, but should MutableInt implement Comparable? countInstances(): - Javadoc should mention may return null. - Can countInstances() be package-private? - After you get the lock in line 138, you should recheck for "head == null", and return null if so. Otherwise it might sometimes return null and sometimes return an empty map. - BIG: Is loop missing? Should "if" at line 140 be "while"? - Merge lines 147, 148: "} else {" - Check for consistent line spacing. - Derek > > -Dmitry > > On 2015-05-07 00:51, Derek White wrote: >> Hi Dmitry, Staffan, >> >> Lots of good comments here. >> >> On the topic of what list should be printed out, I think we should focus >> on objects waiting to be finalized - e.g. the contents of the >> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >> could add a summerizeQueue(TreeMap) method, or a >> general iterator and lambda. >> >> A histogram of objects with finalize methods might also be interesting, >> but you can get most of the same information from a heap histogram >> (ClassHistogramDCmd, and search for count of Finalizer instances). >> >> BTW, by only locking the ReferenceQueue, we should only be blocking the >> FinalizerThread from making progress (and I think there's a GC thread >> that runs after GC that sorts found References objects that need >> processing into their respective ReferenceQueues). But locking the >> "unfinalized" list blocks initializing any object with a finalize() method. >> >> The sorting suggestion is a nice touch. >> >> - Derek White, GC team >> >> On 5/5/15 10:40 AM, Peter Levart wrote: >>> Hi Dmitry, Staffan, >>> >>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>> Dmitry, >>>> >>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>> well considering the changes to Finalizer. >>>> >>>> I?m a little worried about the potentially very large String that is >>>> returned from printFinalizationQueue(). A possible different approach >>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>> That would allow for outputting one line at a time. The output would >>>> still be saved in memory (since the stream is buffered), but at least >>>> the data is only saved once in memory, then. It would make the code a >>>> bit harder to write, so its a question of how scared we are of >>>> running out of memory. >>> If the output is just a histogram of # of instances per class name, >>> then it should not be too large, as there are not many different >>> classes overriding finalize() method (I counted 72 overriddings of >>> finalize() method in the whole jdk/src tree). >>> >>> I'm more concerned about the fact that while traversing the list, a >>> lock is held, which might impact prompt finalization(). Is it >>> acceptable for diagnostic output to impact performance and/or >>> interfere with synchronization? >>> >>> It might be possible to scan the list without holding a lock for >>> diagnostic purposes if Finalizer.remove() didn't set the removed >>> Finalizer.next pointer to point back to itself: >>> >>> private void remove() { >>> synchronized (lock) { >>> if (unfinalized == this) { >>> if (this.next != null) { >>> unfinalized = this.next; >>> } else { >>> unfinalized = this.prev; >>> } >>> } >>> if (this.next != null) { >>> this.next.prev = this.prev; >>> } >>> if (this.prev != null) { >>> this.prev.next = this.next; >>> } >>> // this.next = this; must not be set so that we can >>> traverse the list unsynchronized >>> this.prev = this; /* Indicates that this has been >>> finalized */ >>> } >>> } >>> >>> For detecting whether a Finalizer is already processed, the 'prev' >>> pointer could be used instead: >>> >>> private boolean hasBeenFinalized() { >>> return (prev == this); >>> } >>> >>> Also, to make sure a data race dereferencing 'unfinalized' in >>> unsynchronized printFinalizationQueue() would get you a fully >>> initialized Finalizer instance (in particular the next pointer), you >>> would have to make the 'unfinalized' field volatile or insert an >>> Unsafe.storeFence() before assigning to 'unfinalized': >>> >>> private void add() { >>> synchronized (lock) { >>> if (unfinalized != null) { >>> this.next = unfinalized; >>> unfinalized.prev = this; >>> } >>> // make sure a data race dereferencing 'unfinalized' >>> // in printFinalizationQueue() does see the Finalizer >>> // instance fully initialized >>> // (in particular the 'next' pointer) >>> U.storeFence(); >>> unfinalized = this; >>> } >>> } >>> >>> >>> By doing these modifications, I think you can remove >>> synchronized(lock) {} from printFinalizationQueue(). >>> >>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>> not sure of the difference, perhaps someone from the GC team can help >>>> out? >>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>> instances pending processing by finalizer thread because their >>> referents are eligible for finalization (they are not reachable any >>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>> instances for which their referents have not been finalized yet >>> (including those that are still reachable and alive). The later serves >>> two purposes: >>> - it keeps Finalizer instances reachable until they are processed >>> - it is a source of unfinalized instances for >>> running-finalizers-on-exit if requested by >>> System.runFinalizersOnExit(true); >>> >>> So it really depends on what one would like to see. Showing the queue >>> may be interesting if one wants to see how the finalizer thread is >>> coping with processing the finalize() invocations. Showing unfinalized >>> list may be interesting if one wants to know how many live + >>> finalization pending instances are there on the heap that override >>> finalize() method. >>> >>> Regards, Peter >>> >>>> For the output, it would be a nice touch to sort it on the number of >>>> references for each type. Perhaps outputting it more like a table >>>> (see the old code again) would also make it easier to digest. >>>> >>>> In diagnosticCommand.hpp, the new commands should override >>>> permission() and limit access: >>>> >>>> static const JavaPermission permission() { >>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>> "monitor", NULL}; >>>> return p; >>>> } >>>> >>>> The two tests don?t validate the output in any way. Would it be >>>> possible to add validation? Perhaps hard to make sure an object is on >>>> the finalizer queue? Hmm. >>>> >>>> Thanks, >>>> /Staffan >>>> >>>> >>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>> wrote: >>>>> >>>>> Everyone, >>>>> >>>>> Please review the fix: >>>>> >>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>> >>>>> heap dcmd outputs the same information as SIGBREAK >>>>> >>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>> with count >>>>> >>>>> -Dmitry >>>>> >>>>> -- >>>>> Dmitry Samersoff >>>>> Oracle Java development team, Saint Petersburg, Russia >>>>> * I would love to change the world, but they won't give me the sources. > From pavel.rappo at oracle.com Wed May 13 21:58:42 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 13 May 2015 22:58:42 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <5553C5E6.3020902@univ-mlv.fr> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <5553C5E6.3020902@univ-mlv.fr> Message-ID: Remi, > The other reason to have read that returns 0 is if the underlying channel is in non-blocking mode. > A read on an InputStream created by Channels.newInputStream on a SelectableChannel may return 0 > and the code will go in a loop until the SelectableChannel can read something. > while(read() > 0) avoid that issue. It doesn't seem possible as far as I can see. We have 2 methods in java.nio.channels.Channels: newInputStream(java.nio.channels.ReadableByteChannel) newInputStream(java.nio.channels.AsynchronousByteChannel) Neither ReadableByteChannel nor AsynchronousByteChannel is SelectableChannel. Sorry, I might be missing something. Anyway, it would be a misbehaving InputStream as it doesn't conform to the spec. From forax at univ-mlv.fr Wed May 13 22:05:23 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 14 May 2015 00:05:23 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <5553C5E6.3020902@univ-mlv.fr> Message-ID: <5553CAA3.8030502@univ-mlv.fr> On 05/13/2015 11:58 PM, Pavel Rappo wrote: > Remi, > >> The other reason to have read that returns 0 is if the underlying channel is in non-blocking mode. >> A read on an InputStream created by Channels.newInputStream on a SelectableChannel may return 0 >> and the code will go in a loop until the SelectableChannel can read something. >> while(read() > 0) avoid that issue. > It doesn't seem possible as far as I can see. We have 2 methods in > java.nio.channels.Channels: > > newInputStream(java.nio.channels.ReadableByteChannel) > newInputStream(java.nio.channels.AsynchronousByteChannel) > > Neither ReadableByteChannel nor AsynchronousByteChannel is SelectableChannel. SocketChannel is a subtype of both ReadableByteChannel and SelectableChannel. > > Sorry, I might be missing something. Anyway, it would be a misbehaving > InputStream as it doesn't conform to the spec. if the read is non-blocking, it can read 0 byte which is conform to the InputStream.read spec, or am i missing something ? R?mi From pavel.rappo at oracle.com Wed May 13 22:14:32 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 13 May 2015 23:14:32 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <5553CAA3.8030502@univ-mlv.fr> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <5553C5E6.3020902@univ-mlv.fr> <5553CAA3.8030502@univ-mlv.fr> Message-ID: <32759BE6-5A84-4E6F-99D6-CC808EAFB0E4@oracle.com> >>> The other reason to have read that returns 0 is if the underlying channel is in non-blocking mode. >>> A read on an InputStream created by Channels.newInputStream on a SelectableChannel may return 0 >>> and the code will go in a loop until the SelectableChannel can read something. >>> while(read() > 0) avoid that issue. >> It doesn't seem possible as far as I can see. We have 2 methods in >> java.nio.channels.Channels: >> >> newInputStream(java.nio.channels.ReadableByteChannel) >> newInputStream(java.nio.channels.AsynchronousByteChannel) >> >> Neither ReadableByteChannel nor AsynchronousByteChannel is SelectableChannel. > > SocketChannel is a subtype of both ReadableByteChannel and SelectableChannel. Yes, you're right. >> Sorry, I might be missing something. Anyway, it would be a misbehaving >> InputStream as it doesn't conform to the spec. > > if the read is non-blocking, it can read 0 byte which is conform to the InputStream.read spec, > or am i missing something ? *

If len is zero, then no bytes are read and * 0 is returned; otherwise, there is an attempt to read at * least one byte. If no byte is available because the stream is at end of * file, the value -1 is returned; otherwise, at least one * byte is read and stored into b. So as far as I can see, returning 0 as a number of bytes read is not an option, unless len == 0 From patrick at reini.net Wed May 13 22:25:34 2015 From: patrick at reini.net (Patrick Reinhart) Date: Thu, 14 May 2015 00:25:34 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <32759BE6-5A84-4E6F-99D6-CC808EAFB0E4@oracle.com> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <5553C5E6.3020902@univ-mlv.fr> <5553CAA3.8030502@univ-mlv.fr> <32759BE6-5A84-4E6F-99D6-CC808EAFB0E4@oracle.com> Message-ID: <7BED05E3-1F97-4BA4-A7F1-F9909757967C@reini.net> Hi Pavel, So then our transferTo() implementation should be like this? while ((read = this.read(buffer, 0, TRANSFER_BUFFER_SIZE)) > -1) { That would then look like the code I used to write? -Patrick > Am 14.05.2015 um 00:14 schrieb Pavel Rappo : > > >>>> The other reason to have read that returns 0 is if the underlying channel is in non-blocking mode. >>>> A read on an InputStream created by Channels.newInputStream on a SelectableChannel may return 0 >>>> and the code will go in a loop until the SelectableChannel can read something. >>>> while(read() > 0) avoid that issue. >>> It doesn't seem possible as far as I can see. We have 2 methods in >>> java.nio.channels.Channels: >>> >>> newInputStream(java.nio.channels.ReadableByteChannel) >>> newInputStream(java.nio.channels.AsynchronousByteChannel) >>> >>> Neither ReadableByteChannel nor AsynchronousByteChannel is SelectableChannel. >> >> SocketChannel is a subtype of both ReadableByteChannel and SelectableChannel. > > Yes, you're right. > >>> Sorry, I might be missing something. Anyway, it would be a misbehaving >>> InputStream as it doesn't conform to the spec. >> >> if the read is non-blocking, it can read 0 byte which is conform to the InputStream.read spec, >> or am i missing something ? > > *

If len is zero, then no bytes are read and > * 0 is returned; otherwise, there is an attempt to read at > * least one byte. If no byte is available because the stream is at end of > * file, the value -1 is returned; otherwise, at least one > * byte is read and stored into b. > > So as far as I can see, returning 0 as a number of bytes read is not an option, > unless len == 0 > From pavel.rappo at oracle.com Wed May 13 22:30:28 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 13 May 2015 23:30:28 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <7BED05E3-1F97-4BA4-A7F1-F9909757967C@reini.net> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <5553C5E6.3020902@univ-mlv.fr> <5553CAA3.8030502@univ-mlv.fr> <32759BE6-5A84-4E6F-99D6-CC808EAFB0E4@oracle.com> <7BED05E3-1F97-4BA4-A7F1-F9909757967C@reini.net> Message-ID: <75B4D88C-24FD-4D34-BFFE-79D2072A59C0@oracle.com> > So then our transferTo() implementation should be like this? > > while ((read = this.read(buffer, 0, TRANSFER_BUFFER_SIZE)) > -1) { Isn't it the same as we have now? :) If you mean "> 0", then we should probably wait for someone with both IO and NIO expertise to have a look at this. From chris.hegarty at oracle.com Wed May 13 22:40:31 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 13 May 2015 23:40:31 +0100 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <5553C5E6.3020902@univ-mlv.fr> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <5553C5E6.3020902@univ-mlv.fr> Message-ID: <4A82FD86-E217-45FA-88F7-5CC255AEA3C9@oracle.com> > On 13 May 2015, at 22:45, Remi Forax wrote: > >> >> may return 0, is when len == 0. And it's never the case here. Unless, of course, >> some misbehaving implementation of InputStream is used. > > The other reason to have read that returns 0 is if the underlying channel is in non-blocking mode. > A read on an InputStream created by Channels.newInputStream on a SelectableChannel may return 0 > and the code will go in a loop until the SelectableChannel can read something. > while(read() > 0) avoid that issue. Remi, is this right? I?d have to write a simple test to fully satisfy myself, but ChannelInputStream appears to put a SelectableChannel into blocking mode before reading, if it is non-blocking. > The other things that may be a problem with this patch is that a lot of codes replaced by transferTo use > either a bigger or a smaller size of buffer than transferTo. > Given that we don't know if the buffer size is something important for a code or if the buffer size can be changed, i think it's better to split this patch in several parts and to send each parts to the right mailing list. You are probably right, anything that is not a like for like replacement with the transferTo implementation should have a thorough review from the appropriate component team. -Chris. > regards, > R?mi From martinrb at google.com Wed May 13 22:50:48 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 13 May 2015 15:50:48 -0700 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: <5553C13F.5080900@oracle.com> References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> Message-ID: On Wed, May 13, 2015 at 2:25 PM, Ivan Gerasimov wrote: > > Benchmark Mode Cnt Score Error Units > MyBenchmark.testMethod_1 thrpt 60 1132911599.680 ? 42375177.640 ops/s > MyBenchmark.testMethod_2 thrpt 60 813737659.576 ? 14226427.823 ops/s > MyBenchmark.testMethod_3 thrpt 60 810406621.145 ? 12316864.045 ops/s > > The plain old ||-combined check was faster in this round. > Some other tests showed different results. > The speed seems to depend on the scope of the checked variables and > complexity of the expressions to calculate. > However, I still don't have a clear understanding of all the aspects we > need to pay attention to when doing such optimizations. > I'm not sure, but the only thing that could explain such a huge performance gap is that hotspot was able to determine at jit time that some of the comparisons did not need to be performed at all. If true, is this cheating or not? (you could retry with -Xint) One of the ideas is to separate hot and cold code (hotspot does not yet split code inside a single method) so that hotspot is more likely to inline, so that hotspot is more likely to optimize, and optimizing beginIndex < 0 away entirely is much easier than my more complex expression. So yeah, I could be persuaded that keeping beginIndex < 0 as an independent expression likely to be eliminated. Micro-optimizing is hard, but for the very core of the platform, important (more than readability). One of these days I have to learn how to write a jmh benchmark. From vitalyd at gmail.com Wed May 13 23:06:33 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Wed, 13 May 2015 19:06:33 -0400 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> Message-ID: Why not look at the generated asm and not guess? :) The branch avoiding versions may cause data dependence hazards whereas the branchy one just has branches but assuming perfectly predicted (and microbenchmarks typically are) can pipeline through. Ivan, could you please post the asm here? Assuming you guys are interested in investigating this further. sent from my phone On May 13, 2015 6:51 PM, "Martin Buchholz" wrote: > On Wed, May 13, 2015 at 2:25 PM, Ivan Gerasimov > > wrote: > > > > > Benchmark Mode Cnt Score Error Units > > MyBenchmark.testMethod_1 thrpt 60 1132911599.680 ? 42375177.640 ops/s > > MyBenchmark.testMethod_2 thrpt 60 813737659.576 ? 14226427.823 ops/s > > MyBenchmark.testMethod_3 thrpt 60 810406621.145 ? 12316864.045 ops/s > > > > The plain old ||-combined check was faster in this round. > > Some other tests showed different results. > > The speed seems to depend on the scope of the checked variables and > > complexity of the expressions to calculate. > > However, I still don't have a clear understanding of all the aspects we > > need to pay attention to when doing such optimizations. > > > > I'm not sure, but the only thing that could explain such a huge performance > gap is that hotspot was able to determine at jit time that some of the > comparisons did not need to be performed at all. If true, is this cheating > or not? (you could retry with -Xint) One of the ideas is to separate hot > and cold code (hotspot does not yet split code inside a single method) so > that hotspot is more likely to inline, so that hotspot is more likely to > optimize, and optimizing beginIndex < 0 away entirely is much easier than > my more complex expression. So yeah, I could be persuaded that keeping > beginIndex < 0 as an independent expression likely to be eliminated. > Micro-optimizing is hard, but for the very core of the platform, important > (more than readability). > > One of these days I have to learn how to write a jmh benchmark. > From forax at univ-mlv.fr Wed May 13 23:06:41 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 14 May 2015 01:06:41 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <4A82FD86-E217-45FA-88F7-5CC255AEA3C9@oracle.com> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <5553C5E6.3020902@univ-mlv.fr> <4A82FD86-E217-45FA-88F7-5CC255AEA3C9@oracle.com> Message-ID: <5553D901.3030408@univ-mlv.fr> Hi Chris, On 05/14/2015 12:40 AM, Chris Hegarty wrote: > >> On 13 May 2015, at 22:45, Remi Forax > > wrote: >> >>> >>> may return 0, is when len == 0. And it's never the case here. >>> Unless, of course, >>> some misbehaving implementation of InputStream is used. >> >> The other reason to have read that returns 0 is if the underlying >> channel is in non-blocking mode. >> A read on an InputStream created by Channels.newInputStream on a >> SelectableChannel may return 0 >> and the code will go in a loop until the SelectableChannel can read >> something. >> while(read() > 0) avoid that issue. > > Remi, is this right? I?d have to write a simple test to fully satisfy > myself, but ChannelInputStream appears to put a SelectableChannel into > blocking mode before reading, if it is non-blocking. No, it seems, i'm wrong on that. I have taken a look to ChannelInputStream and SocketAdapter.SocketInputStream and both don't accept non-blocking SelectableChannel. Sorry for the noise. > > >> The other things that may be a problem with this patch is that a lot >> of codes replaced by transferTo use >> either a bigger or a smaller size of buffer than transferTo. >> Given that we don't know if the buffer size is something important >> for a code or if the buffer size can be changed, i think it's better >> to split this patch in several parts and to send each parts to the >> right mailing list. > > You are probably right, anything that is not a like for like > replacement with the transferTo implementation should have a thorough > review from the appropriate component team. > > -Chris. regards, R?mi From forax at univ-mlv.fr Wed May 13 23:07:31 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 14 May 2015 01:07:31 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: <32759BE6-5A84-4E6F-99D6-CC808EAFB0E4@oracle.com> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <5553C5E6.3020902@univ-mlv.fr> <5553CAA3.8030502@univ-mlv.fr> <32759BE6-5A84-4E6F-99D6-CC808EAFB0E4@oracle.com> Message-ID: <5553D933.9070301@univ-mlv.fr> Hi Pavel, On 05/14/2015 12:14 AM, Pavel Rappo wrote: >>>> The other reason to have read that returns 0 is if the underlying channel is in non-blocking mode. >>>> A read on an InputStream created by Channels.newInputStream on a SelectableChannel may return 0 >>>> and the code will go in a loop until the SelectableChannel can read something. >>>> while(read() > 0) avoid that issue. >>> It doesn't seem possible as far as I can see. We have 2 methods in >>> java.nio.channels.Channels: >>> >>> newInputStream(java.nio.channels.ReadableByteChannel) >>> newInputStream(java.nio.channels.AsynchronousByteChannel) >>> >>> Neither ReadableByteChannel nor AsynchronousByteChannel is SelectableChannel. >> SocketChannel is a subtype of both ReadableByteChannel and SelectableChannel. > Yes, you're right. > >>> Sorry, I might be missing something. Anyway, it would be a misbehaving >>> InputStream as it doesn't conform to the spec. >> if the read is non-blocking, it can read 0 byte which is conform to the InputStream.read spec, >> or am i missing something ? > *

If len is zero, then no bytes are read and > * 0 is returned; otherwise, there is an attempt to read at > * least one byte. If no byte is available because the stream is at end of > * file, the value -1 is returned; otherwise, at least one > * byte is read and stored into b. > > So as far as I can see, returning 0 as a number of bytes read is not an option, > unless len == 0 > Yes, you're right, my bad on that. R?mi From martinrb at google.com Wed May 13 23:12:47 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 13 May 2015 16:12:47 -0700 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> Message-ID: On Wed, May 13, 2015 at 4:06 PM, Vitaly Davidovich wrote: > :) The branch avoiding versions may cause data dependence hazards whereas > the branchy one just has branches but assuming perfectly predicted (and > microbenchmarks typically are) can pipeline through. Ivan, could you > please post the asm here? Assuming you guys are interested in investigating > this further. > there might be a new rule of thumb there: only eliminate branches if they are unlikely to be predicted. From vitalyd at gmail.com Wed May 13 23:19:37 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Wed, 13 May 2015 19:19:37 -0400 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> Message-ID: Yes, that should be the general rule of thumb for code targeting out of order chips. The caveat is that microbenchmarks have the advantage of being the only (typically very small) code running on the cpu, and will get full use of execution resources; specifically in this case, it's very likely that the branch history of this code will stay in the buffer and not be evicted by other code, as you'd find in a more complex (non-microbench) scenario. Microbenching is hard :). sent from my phone On May 13, 2015 7:12 PM, "Martin Buchholz" wrote: > > > On Wed, May 13, 2015 at 4:06 PM, Vitaly Davidovich > wrote: > >> :) The branch avoiding versions may cause data dependence hazards whereas >> the branchy one just has branches but assuming perfectly predicted (and >> microbenchmarks typically are) can pipeline through. Ivan, could you >> please post the asm here? Assuming you guys are interested in investigating >> this further. >> > there might be a new rule of thumb there: only eliminate branches if they > are unlikely to be predicted. > From ivan.gerasimov at oracle.com Wed May 13 23:23:30 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 14 May 2015 02:23:30 +0300 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> Message-ID: <5553DCF2.7050004@oracle.com> On 14.05.2015 2:06, Vitaly Davidovich wrote: > > Why not look at the generated asm and not guess? :) The branch > avoiding versions may cause data dependence hazards whereas the > branchy one just has branches but assuming perfectly predicted (and > microbenchmarks typically are) can pipeline through. Ivan, could you > please post the asm here? Assuming you guys are interested in > investigating this further. > Sure, here they are: void substring_1(int, int, char[]); Code: 0: iload_1 1: iflt 15 4: iload_2 5: aload_3 6: arraylength 7: if_icmpgt 15 10: iload_1 11: iload_2 12: if_icmple 23 15: new #4 // class java/lang/Error 18: dup 19: invokespecial #5 // Method java/lang/Error."":()V 22: athrow 23: return void substring_2(int, int, char[]); Code: 0: iload_1 1: aload_3 2: arraylength 3: iload_2 4: isub 5: ior 6: iload_2 7: iload_1 8: isub 9: ior 10: ifge 21 13: new #4 // class java/lang/Error 16: dup 17: invokespecial #5 // Method java/lang/Error."":()V 20: athrow 21: return void substring_3(int, int, char[]); Code: 0: iload_1 1: aload_3 2: arraylength 3: iload_2 4: isub 5: ior 6: iflt 18 9: iload_2 10: iload_1 11: isub 12: dup 13: istore 4 15: ifge 26 18: new #4 // class java/lang/Error 21: dup 22: invokespecial #5 // Method java/lang/Error."":()V 25: athrow 26: return Sincerely yours, Ivan > sent from my phone > > On May 13, 2015 6:51 PM, "Martin Buchholz" > wrote: > > On Wed, May 13, 2015 at 2:25 PM, Ivan Gerasimov > > > wrote: > > > > > Benchmark Mode Cnt Score Error Units > > MyBenchmark.testMethod_1 thrpt 60 1132911599.680 ? > 42375177.640 ops/s > > MyBenchmark.testMethod_2 thrpt 60 813737659.576 ? > 14226427.823 ops/s > > MyBenchmark.testMethod_3 thrpt 60 810406621.145 ? > 12316864.045 ops/s > > > > The plain old ||-combined check was faster in this round. > > Some other tests showed different results. > > The speed seems to depend on the scope of the checked variables and > > complexity of the expressions to calculate. > > However, I still don't have a clear understanding of all the > aspects we > > need to pay attention to when doing such optimizations. > > > > I'm not sure, but the only thing that could explain such a huge > performance > gap is that hotspot was able to determine at jit time that some of the > comparisons did not need to be performed at all. If true, is this > cheating > or not? (you could retry with -Xint) One of the ideas is to > separate hot > and cold code (hotspot does not yet split code inside a single > method) so > that hotspot is more likely to inline, so that hotspot is more > likely to > optimize, and optimizing beginIndex < 0 away entirely is much > easier than > my more complex expression. So yeah, I could be persuaded that > keeping > beginIndex < 0 as an independent expression likely to be eliminated. > Micro-optimizing is hard, but for the very core of the platform, > important > (more than readability). > > One of these days I have to learn how to write a jmh benchmark. > From vitalyd at gmail.com Wed May 13 23:24:43 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Wed, 13 May 2015 19:24:43 -0400 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> Message-ID: By the way, this is pure speculation on my part by just looking at the code. To truly find out, at least say for Intel, you'd have to run these benchmarks under a cpu event profiler and see what it tells you for IPC, branch mispredictions, the various stalls, etc. JMH has perfasm I believe which you can use to run this under linux perf. sent from my phone On May 13, 2015 7:19 PM, "Vitaly Davidovich" wrote: > Yes, that should be the general rule of thumb for code targeting out of > order chips. The caveat is that microbenchmarks have the advantage of > being the only (typically very small) code running on the cpu, and will get > full use of execution resources; specifically in this case, it's very > likely that the branch history of this code will stay in the buffer and not > be evicted by other code, as you'd find in a more complex (non-microbench) > scenario. Microbenching is hard :). > > sent from my phone > On May 13, 2015 7:12 PM, "Martin Buchholz" wrote: > >> >> >> On Wed, May 13, 2015 at 4:06 PM, Vitaly Davidovich >> wrote: >> >>> :) The branch avoiding versions may cause data dependence hazards >>> whereas the branchy one just has branches but assuming perfectly predicted >>> (and microbenchmarks typically are) can pipeline through. Ivan, could you >>> please post the asm here? Assuming you guys are interested in investigating >>> this further. >>> >> there might be a new rule of thumb there: only eliminate branches if they >> are unlikely to be predicted. >> > From vitalyd at gmail.com Wed May 13 23:26:48 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Wed, 13 May 2015 19:26:48 -0400 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: <5553DCF2.7050004@oracle.com> References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> <5553DCF2.7050004@oracle.com> Message-ID: Need JIT generated assembly, not bytecode :). That will tell you at least which optimizations JIT applied, how it register allocated things, etc. If nothing obvious there, see my other reply regarding cpu event based profiling. I'm sure Aleksey Shipilev could help out if you're really inclined to figure this out. sent from my phone On May 13, 2015 7:23 PM, "Ivan Gerasimov" wrote: > > > On 14.05.2015 2:06, Vitaly Davidovich wrote: > > Why not look at the generated asm and not guess? :) The branch avoiding > versions may cause data dependence hazards whereas the branchy one just has > branches but assuming perfectly predicted (and microbenchmarks typically > are) can pipeline through. Ivan, could you please post the asm here? > Assuming you guys are interested in investigating this further. > > Sure, here they are: > > void substring_1(int, int, char[]); > Code: > 0: iload_1 > 1: iflt 15 > 4: iload_2 > 5: aload_3 > 6: arraylength > 7: if_icmpgt 15 > 10: iload_1 > 11: iload_2 > 12: if_icmple 23 > 15: new #4 // class java/lang/Error > 18: dup > 19: invokespecial #5 // Method > java/lang/Error."":()V > 22: athrow > 23: return > > void substring_2(int, int, char[]); > Code: > 0: iload_1 > 1: aload_3 > 2: arraylength > 3: iload_2 > 4: isub > 5: ior > 6: iload_2 > 7: iload_1 > 8: isub > 9: ior > 10: ifge 21 > 13: new #4 // class java/lang/Error > 16: dup > 17: invokespecial #5 // Method > java/lang/Error."":()V > 20: athrow > 21: return > > void substring_3(int, int, char[]); > Code: > 0: iload_1 > 1: aload_3 > 2: arraylength > 3: iload_2 > 4: isub > 5: ior > 6: iflt 18 > 9: iload_2 > 10: iload_1 > 11: isub > 12: dup > 13: istore 4 > 15: ifge 26 > 18: new #4 // class java/lang/Error > 21: dup > 22: invokespecial #5 // Method > java/lang/Error."":()V > 25: athrow > 26: return > > Sincerely yours, > Ivan > > sent from my phone > On May 13, 2015 6:51 PM, "Martin Buchholz" wrote: > >> On Wed, May 13, 2015 at 2:25 PM, Ivan Gerasimov < >> ivan.gerasimov at oracle.com> >> wrote: >> >> > >> > Benchmark Mode Cnt Score Error >> Units >> > MyBenchmark.testMethod_1 thrpt 60 1132911599.680 ? 42375177.640 >> ops/s >> > MyBenchmark.testMethod_2 thrpt 60 813737659.576 ? 14226427.823 >> ops/s >> > MyBenchmark.testMethod_3 thrpt 60 810406621.145 ? 12316864.045 >> ops/s >> > >> > The plain old ||-combined check was faster in this round. >> > Some other tests showed different results. >> > The speed seems to depend on the scope of the checked variables and >> > complexity of the expressions to calculate. >> > However, I still don't have a clear understanding of all the aspects we >> > need to pay attention to when doing such optimizations. >> > >> >> I'm not sure, but the only thing that could explain such a huge >> performance >> gap is that hotspot was able to determine at jit time that some of the >> comparisons did not need to be performed at all. If true, is this >> cheating >> or not? (you could retry with -Xint) One of the ideas is to separate hot >> and cold code (hotspot does not yet split code inside a single method) so >> that hotspot is more likely to inline, so that hotspot is more likely to >> optimize, and optimizing beginIndex < 0 away entirely is much easier than >> my more complex expression. So yeah, I could be persuaded that keeping >> beginIndex < 0 as an independent expression likely to be eliminated. >> Micro-optimizing is hard, but for the very core of the platform, important >> (more than readability). >> >> One of these days I have to learn how to write a jmh benchmark. >> > > From john.r.rose at oracle.com Wed May 13 23:33:48 2015 From: john.r.rose at oracle.com (John Rose) Date: Wed, 13 May 2015 16:33:48 -0700 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: <5553C13F.5080900@oracle.com> References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> Message-ID: <2C536098-1C1D-4263-915D-75FCB8D7C961@oracle.com> On May 13, 2015, at 2:25 PM, Ivan Gerasimov wrote: > > My third concern is this: Wouldn't it be possible to implement this type of optimization at jvm level? > At least some conditions can automatically be combined into one. > Given the information about which execution path is expected to be fast, hotspot should be able to quickly perform that one combined condition check and move to the fast path in most situations. I think this is the high-order bit: Such optimizations are done, or should be done, at the JVM level. If you can tell there's a missing JVM optimization, file a bug against the JVM JIT, and keep the clearest code style. If you can't tell, still try to keep the clean code style. HotSpot's optimizing JIT does not respond equally well to all source (bytecode) code styles; it works harder to optimize commonly encountered cases, like the simpler JMH cases in the current example. Writing strange code that seems to map to smaller or less branchy assembly code might work for one micro-version of the JVM, and then be defeated by the next micro-version. Here are two reasons "||" might be preferable to "|" in your source code: 1. The JVM interpreter profiles "||" outcomes but not "|". (Side effect of profiling branches *in the interpreter*.) 2. The C2 JIT looks for small control flow diamonds that it can turn into conditional moves or other consolidated instructions. If the "||" gets suboptimal assembly code for you, and if your code has a commonly-occuring shape, it would be better for all of us to leave the code alone and fix the optimizer. ? John From vitalyd at gmail.com Wed May 13 23:46:08 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Wed, 13 May 2015 19:46:08 -0400 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: <2C536098-1C1D-4263-915D-75FCB8D7C961@oracle.com> References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> <2C536098-1C1D-4263-915D-75FCB8D7C961@oracle.com> Message-ID: I'd add "And always look at generated asm for these types of constructs". There's really nothing to profile in terms of "|" outcome unless JIT starts tracking bit position values, and it's a cheap instruction on its own. I'd be surprised if conditional moves are emitted here since these branches should be perfectly predicted (we're not testing the error path right?) and cmovs themselves have data dependence. sent from my phone On May 13, 2015 7:34 PM, "John Rose" wrote: > On May 13, 2015, at 2:25 PM, Ivan Gerasimov > wrote: > > > > My third concern is this: Wouldn't it be possible to implement this > type of optimization at jvm level? > > At least some conditions can automatically be combined into one. > > Given the information about which execution path is expected to be fast, > hotspot should be able to quickly perform that one combined condition check > and move to the fast path in most situations. > > I think this is the high-order bit: Such optimizations are done, or > should be done, at the JVM level. If you can tell there's a missing JVM > optimization, file a bug against the JVM JIT, and keep the clearest code > style. If you can't tell, still try to keep the clean code style. > > HotSpot's optimizing JIT does not respond equally well to all source > (bytecode) code styles; it works harder to optimize commonly encountered > cases, like the simpler JMH cases in the current example. Writing strange > code that seems to map to smaller or less branchy assembly code might work > for one micro-version of the JVM, and then be defeated by the next > micro-version. > > Here are two reasons "||" might be preferable to "|" in your source code: > 1. The JVM interpreter profiles "||" outcomes but not "|". (Side effect > of profiling branches *in the interpreter*.) > 2. The C2 JIT looks for small control flow diamonds that it can turn into > conditional moves or other consolidated instructions. > > If the "||" gets suboptimal assembly code for you, and if your code has a > commonly-occuring shape, it would be better for all of us to leave the code > alone and fix the optimizer. > > ? John From john.r.rose at oracle.com Wed May 13 23:59:44 2015 From: john.r.rose at oracle.com (John Rose) Date: Wed, 13 May 2015 16:59:44 -0700 Subject: RFR: 8071571: Move substring of same string to slow path In-Reply-To: References: <55156FB3.1080006@oracle.com> <555116AB.3030603@oracle.com> <55524D64.5080808@oracle.com> <5553C13F.5080900@oracle.com> <2C536098-1C1D-4263-915D-75FCB8D7C961@oracle.com> Message-ID: On May 13, 2015, at 4:46 PM, Vitaly Davidovich wrote: > I'd add "And always look at generated asm for these types of constructs". +1, with caveats about micro-versions changing stuff at that level From martinrb at google.com Thu May 14 01:02:59 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 13 May 2015 18:02:59 -0700 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: Message-ID: I'm also in the business of maintaining List implementations and would like to share implementation code. Unfortunately, Java does not provide much help. Java confuses inheritance and subtyping. Public abstract superclasses leak through (users might mistakenly use AbstractList in their API) and of course we only have single inheritance. Default methods are not Traits, much as we would like them to be - they were explicitly designed to enable interface evolution. They are leaky in the same way as abstract classes. Will Jigsaw help? I'm not sure, but I'm pessimistic. On Fri, May 8, 2015 at 8:25 AM, Attila Szegedi wrote: > Well then those would obviously be left out, documenting that it?s the > responsibility of the implementor to provide them. This would be true in > general for other interfaces as well that have a specification for expected > meaning of equals/hashCode. > > There?s still a lot of boilerplate code that could be saved from > repetition, though. > > > On May 8, 2015, at 12:15 PM, Pavel Rappo wrote: > > > > > >> (I?ll hand-wave the issue of ?protected int modCount? issue for now.) > > > > Not only. Consider this: java.util.AbstractList overrides some methods > from > > java.lang.Object such as equals and hashCode. And this is a no-no [1]: > > > > ...It is a compile-time error if a default method is > override-equivalent > > with a non-private method of the class Object, because any class > > implementing the interface will inherit its own implementation of the > > method... > > > > > ------------------------------------------------------------------------------- > > [1] > https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.4.1.2 > > From brian.goetz at oracle.com Thu May 14 01:16:43 2015 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 13 May 2015 21:16:43 -0400 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: Message-ID: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> Not only is there a problem with modCount, but also with equals/hashCode/toString. You can?t define these Object methods in an interface. On May 8, 2015, at 5:41 AM, Attila Szegedi wrote: > So I?m in a position where I?d need to have a class implement List, but it already extends something else, so I can?t have it extend AbstractList, which leaves me with a lot of boilerplate methods to implement. > > Would it seem like a good idea to reimagine AbstractList and friends as interfaces with default methods? > > Of course, I know that technically for backwards compatibility we can?t really do this, but what we could do is: > > public interface DefaultList extends List { > ? add all methods from AbstractList here as default methods ? > } > > public abstract class AbstractList implements DefaultList { > } > > (I?ll hand-wave the issue of ?protected int modCount? issue for now.) > > Actually, this seems like such an obvious idea that I?m 100% sure it must?ve been considered before, but I can?t find any related discussion. > > Attila. From stuart.marks at oracle.com Thu May 14 01:44:38 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 13 May 2015 18:44:38 -0700 Subject: RFR(s): 8078463: optimize java/util/Map/Collisions.java Message-ID: <5553FE06.40006@oracle.com> Hi all, Please review this change to optimize a test. Basically the test did string formatting for every assertion, but the string was thrown away if the assertion passed -- the most common case. The change is to do the string formatting only when an assertion fails and information needs to be printed out. Thanks to Andrey Zakharov for discovering and investigating this. Bug report: https://bugs.openjdk.java.net/browse/JDK-8078463 Webrev: http://cr.openjdk.java.net/~smarks/reviews/8078463/webrev.0/ On my (new, fast) laptop, with JVM options -Xcomp -XX:+DeoptimizeALot -client, the unmodified test takes about 21.4 seconds to run. The modified test takes only 12.3 seconds. Note that I have added several overloads of check() with different arguments. I tried an alternative, which is a varargs version of check(): static void check(boolean cond, String fmt, Object... args) { if (cond) { pass(); } else { fail(String.format(fmt, args)); } } This of course is much simpler code, but it took 14.2 seconds, about 15% slower than the proposed version. Is the simpler code worth the slowdown? I could go either way. Thanks. s'marks From martinrb at google.com Thu May 14 02:24:50 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 13 May 2015 19:24:50 -0700 Subject: RFR(s): 8078463: optimize java/util/Map/Collisions.java In-Reply-To: <5553FE06.40006@oracle.com> References: <5553FE06.40006@oracle.com> Message-ID: Your changes look good, but: 204 check(map.size() == i, "insertion: map expected size m%d != i%d", map.size(), i); many of those detail messages look like leftovers from a long debugging session. Here I would consider converting to a testng test (I ended up doing this a few times myself) and writing very simply, standardly, efficiently and readably assertEquals(map.size(), i); only adding more breadcrumbs if it's non-obvious, which is generally not the case in this test. testMap already prints out keys_desc, so the test output is unambiguous. On Wed, May 13, 2015 at 6:44 PM, Stuart Marks wrote: > Hi all, > > Please review this change to optimize a test. Basically the test did > string formatting for every assertion, but the string was thrown away if > the assertion passed -- the most common case. The change is to do the > string formatting only when an assertion fails and information needs to be > printed out. > > Thanks to Andrey Zakharov for discovering and investigating this. > > Bug report: > > https://bugs.openjdk.java.net/browse/JDK-8078463 > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8078463/webrev.0/ > > On my (new, fast) laptop, with JVM options -Xcomp -XX:+DeoptimizeALot > -client, the unmodified test takes about 21.4 seconds to run. The modified > test takes only 12.3 seconds. > > Note that I have added several overloads of check() with different > arguments. I tried an alternative, which is a varargs version of check(): > > static void check(boolean cond, String fmt, Object... args) { > if (cond) { > pass(); > } else { > fail(String.format(fmt, args)); > } > } > > This of course is much simpler code, but it took 14.2 seconds, about 15% > slower than the proposed version. Is the simpler code worth the slowdown? I > could go either way. > > Thanks. > > s'marks > > > From martinrb at google.com Thu May 14 06:08:18 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 13 May 2015 23:08:18 -0700 Subject: PriorityQueue In-Reply-To: References: Message-ID: Software is hard. We tried and got stuck, although the former effort can be revived. RFR : 6799426 : (xs) Add constructor PriorityQueue(Comparator) http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-July/019124.html On Wed, May 13, 2015 at 10:17 PM, Brett Bernstein wrote: > To whom this may concern: > I believe the list of PriorityQueue constructors has a glaring omission > that could be easily rectified. That is, there is no constructor that > takes a Collection and a Comparator. What steps should I go through to get > this suggested to be added to the class? > > Thanks, > Brett Bernstein > From martinrb at google.com Thu May 14 06:21:06 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 13 May 2015 23:21:06 -0700 Subject: PriorityQueue In-Reply-To: References: Message-ID: On Wed, May 13, 2015 at 11:17 PM, Brett Bernstein wrote: > I believe the linked sequence of messages refer to the addition of a > PriorityQueue constructor only taking a Comparator which was does appear in > Java 1.8. Did you have a link to something regarding the a constructor > taking a Collection and a Comparator (2 arguments)? > Oops - you are right... The one I referenced did get added, and your constructor is still missing. You may have trouble finding someone with the same enthusiasm for this constructor as yourself. From dawid.weiss at gmail.com Thu May 14 07:03:09 2015 From: dawid.weiss at gmail.com (Dawid Weiss) Date: Thu, 14 May 2015 09:03:09 +0200 Subject: PriorityQueue In-Reply-To: References: Message-ID: > You may have trouble finding someone with the same enthusiasm for this constructor as yourself. This probably applies to many data structures that have specific (and rare) applications. A priority queue that takes a custom comparator seems like a pretty frequent (algorithmic) use case to me, however (and so does a limited capacity queue). As an example, you can see the implementation of such a PQ in Apache Lucene -- it is used all over the place [1]. Dawid [1] https://github.com/apache/lucene-solr/blob/trunk/lucene/core/src/java/org/apache/lucene/util/PriorityQueue.java#L75-L79 On Thu, May 14, 2015 at 8:21 AM, Martin Buchholz wrote: > On Wed, May 13, 2015 at 11:17 PM, Brett Bernstein > wrote: > >> I believe the linked sequence of messages refer to the addition of a >> PriorityQueue constructor only taking a Comparator which was does appear in >> Java 1.8. Did you have a link to something regarding the a constructor >> taking a Collection and a Comparator (2 arguments)? >> > > Oops - you are right... The one I referenced did get added, and your > constructor is still missing. > You may have trouble finding someone with the same enthusiasm for this > constructor as yourself. From peter.levart at gmail.com Thu May 14 07:50:18 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 14 May 2015 09:50:18 +0200 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5553B552.9060900@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> Message-ID: <555453BA.2070205@gmail.com> Hi Derek, On 05/13/2015 10:34 PM, Derek White wrote: > Hi Peter, > > I don't have smoking gun evidence that your change introduces a bug, > but I have some concerns... I did have a concern too, ... > > On 5/12/15 6:05 PM, Peter Levart wrote: >> Hi Dmitry, >> >> You iterate the queue then, not the unfinalized list. That's more >> logical. >> >> Holding the queue's lock may pause reference handler and finalizer >> threads for the entire time of iteration. This can blow up the >> application. Suppose one wants to diagnose the application because he >> suspects that finalizer thread hardly keeps up with production of >> finalizable instances. This can happen if the allocation rate of >> finalizable objects is very high and/or finalize() methods are not >> coded to be fast enough. Suppose the queue of Finalizer(s) builds up >> gradually and is already holding several million objects. Now you >> initiate the diagnostic command to print the queue. The iteration >> over and grouping/counting of several millions of Finalizer(s) takes >> some time. This blocks finalizer thread and reference handler thread. >> But does not block the threads that allocate finalizable objects. By >> the time the iteration is over, the JVM blows up and application >> slows down to a halt doing GCs most of the time, getting OOMEs, etc... >> >> It is possible to iterate the elements of the queue for diagnostic >> purposes without holding a lock. The modification required to do that >> is the following (havent tested this, but I think it should work): >> >> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >> > One issue to watch out for is the garbage collectors inspect the > Reference.next field from C code directly (to distinguish active vs. > pending, iterate over oops, etc.). You can search hotspot for > java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. > > Your change makes "inactive" References superficially look like > "enqueued" References. The GC code is rather subtle and I haven't yet > seen a case where it would get confused by this change, but there > could easily be something like that lurking in the GC code. ...but then I thought that GC can in no way treat a Reference differently whether it is still enqueued in a ReferenceQueue or already dequeued (inactive) - responsibility is already on the Java side. Currently the definition of Reference.next is this: /* When active: NULL * pending: this * Enqueued: next reference in queue (or this if last) * Inactive: this */ @SuppressWarnings("rawtypes") Reference next; We see that, unless GC inspects all ReferenceQueue instances and scans their lists too, the state of a Reference that is enqueued as last in list is indistinguishable from the state of inactive Reference. So I deduced that this distinction (enqueued/inactive) can't be established solely on the value of .next field ( == this or != this)... But I should inspect the GC code too to build a better understanding of that part of the story... Anyway. It turns out that there is already enough state in Reference to destinguish between it being enqueued as last in list and already dequeued (inactive) - the additional state is Reference.queue that transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in ReferenceQueue.reallyPoll. We need to just make sure the two fields (r.next and r.queue) are assigned and read in correct order. This can be achieved either by making Reference.next a volatile field or by a couple of explicit fences: http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ The assignment of r.queue to ReferenceQueue.ENQUEUED already happens before linking the reference into the queue's head in ReferenceQueue.enqueue(): r.queue = ENQUEUED; r.next = (head == null) ? r : head; head = r; Both stores are volatile. > >> I also suggest the addition to the ReferenceQueue to be contained >> (package-private) and as generic as possible. That's why I suggest >> forEach iteration method with no concrete logic. >> >> It would be possible to encapsulate the entire logic into a special >> package-private class (say java.lang.ref.DiagnosticCommands) with >> static method(s) (printFinalizationQueue)... You could just expose a >> package-private forEach static method from Finalizer and code the >> rest in DiagnosticCommands. > That's good for encapsulation. But I'm concerned that if "forEach" got > exposed beyond careful use in DiagnosticCommands, and the Referents > were leaked back into the heap, then we could get unexpected object > resurrection after finalization. This isn't a bug on it's own - any > finalizer might resurrect its object if not careful, but ordinarily > /only/ the finalizer could resurrect the object. This could invalidate > application invariants? Well, it all stays in the confines of package-private API - internal to JDK. Any future additional use should be reviewed carefully. Comments on the forEach() method should warn about that. > > I agree that using a lock over the ReferenceQueue iteration opens up > /another/ case of diagnostics affecting application behavior. And > there are pathological scenarios where this gets severe. This is > unfortunate but not uncommon. There is enough complication here that > you should be sure that the fix for diagnostics performance doesn't > introduce subtle bugs to the system in general. A change in this area > should get a thorough review from both the runtime and GC sides. Is the webrev.02 proposed above more acceptable in that respect? It does not introduce any logical changes to existing code. > > Better yet, the reference handling code in GC and runtime should > probably be thrown out and re-written, but that's another issue :-) I may have some proposals in that direction. Stay tuned. Regards, Peter > > - Derek > >> Regards, Peter >> >> >> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>> Everybody, >>> >>> Updated version: >>> >>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>> >>> Now it iterates over queue and output result sorted by number of instances. >>> >>> -Dmitry >>> >>> On 2015-05-07 00:51, Derek White wrote: >>>> Hi Dmitry, Staffan, >>>> >>>> Lots of good comments here. >>>> >>>> On the topic of what list should be printed out, I think we should focus >>>> on objects waiting to be finalized - e.g. the contents of the >>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>> could add a summerizeQueue(TreeMap) method, or a >>>> general iterator and lambda. >>>> >>>> A histogram of objects with finalize methods might also be interesting, >>>> but you can get most of the same information from a heap histogram >>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>> >>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>> FinalizerThread from making progress (and I think there's a GC thread >>>> that runs after GC that sorts found References objects that need >>>> processing into their respective ReferenceQueues). But locking the >>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>> >>>> The sorting suggestion is a nice touch. >>>> >>>> - Derek White, GC team >>>> >>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>> Hi Dmitry, Staffan, >>>>> >>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>> Dmitry, >>>>>> >>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>> well considering the changes to Finalizer. >>>>>> >>>>>> I?m a little worried about the potentially very large String that is >>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>> That would allow for outputting one line at a time. The output would >>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>> the data is only saved once in memory, then. It would make the code a >>>>>> bit harder to write, so its a question of how scared we are of >>>>>> running out of memory. >>>>> If the output is just a histogram of # of instances per class name, >>>>> then it should not be too large, as there are not many different >>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>> finalize() method in the whole jdk/src tree). >>>>> >>>>> I'm more concerned about the fact that while traversing the list, a >>>>> lock is held, which might impact prompt finalization(). Is it >>>>> acceptable for diagnostic output to impact performance and/or >>>>> interfere with synchronization? >>>>> >>>>> It might be possible to scan the list without holding a lock for >>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>> Finalizer.next pointer to point back to itself: >>>>> >>>>> private void remove() { >>>>> synchronized (lock) { >>>>> if (unfinalized == this) { >>>>> if (this.next != null) { >>>>> unfinalized = this.next; >>>>> } else { >>>>> unfinalized = this.prev; >>>>> } >>>>> } >>>>> if (this.next != null) { >>>>> this.next.prev = this.prev; >>>>> } >>>>> if (this.prev != null) { >>>>> this.prev.next = this.next; >>>>> } >>>>> // this.next = this; must not be set so that we can >>>>> traverse the list unsynchronized >>>>> this.prev = this; /* Indicates that this has been >>>>> finalized */ >>>>> } >>>>> } >>>>> >>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>> pointer could be used instead: >>>>> >>>>> private boolean hasBeenFinalized() { >>>>> return (prev == this); >>>>> } >>>>> >>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>> initialized Finalizer instance (in particular the next pointer), you >>>>> would have to make the 'unfinalized' field volatile or insert an >>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>> >>>>> private void add() { >>>>> synchronized (lock) { >>>>> if (unfinalized != null) { >>>>> this.next = unfinalized; >>>>> unfinalized.prev = this; >>>>> } >>>>> // make sure a data race dereferencing 'unfinalized' >>>>> // in printFinalizationQueue() does see the Finalizer >>>>> // instance fully initialized >>>>> // (in particular the 'next' pointer) >>>>> U.storeFence(); >>>>> unfinalized = this; >>>>> } >>>>> } >>>>> >>>>> >>>>> By doing these modifications, I think you can remove >>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>> >>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>> out? >>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>> instances pending processing by finalizer thread because their >>>>> referents are eligible for finalization (they are not reachable any >>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>> instances for which their referents have not been finalized yet >>>>> (including those that are still reachable and alive). The later serves >>>>> two purposes: >>>>> - it keeps Finalizer instances reachable until they are processed >>>>> - it is a source of unfinalized instances for >>>>> running-finalizers-on-exit if requested by >>>>> System.runFinalizersOnExit(true); >>>>> >>>>> So it really depends on what one would like to see. Showing the queue >>>>> may be interesting if one wants to see how the finalizer thread is >>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>> list may be interesting if one wants to know how many live + >>>>> finalization pending instances are there on the heap that override >>>>> finalize() method. >>>>> >>>>> Regards, Peter >>>>> >>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>> references for each type. Perhaps outputting it more like a table >>>>>> (see the old code again) would also make it easier to digest. >>>>>> >>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>> permission() and limit access: >>>>>> >>>>>> static const JavaPermission permission() { >>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>> "monitor", NULL}; >>>>>> return p; >>>>>> } >>>>>> >>>>>> The two tests don?t validate the output in any way. Would it be >>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>> the finalizer queue? Hmm. >>>>>> >>>>>> Thanks, >>>>>> /Staffan >>>>>> >>>>>> >>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>> wrote: >>>>>>> >>>>>>> Everyone, >>>>>>> >>>>>>> Please review the fix: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>> >>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>> >>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>> with count >>>>>>> >>>>>>> -Dmitry >>>>>>> >>>>>>> -- >>>>>>> Dmitry Samersoff >>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>> * I would love to change the world, but they won't give me the sources. >> > From chris.hegarty at oracle.com Thu May 14 07:58:52 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 14 May 2015 08:58:52 +0100 Subject: RFR(s): 8078463: optimize java/util/Map/Collisions.java In-Reply-To: References: <5553FE06.40006@oracle.com> Message-ID: On 14 May 2015, at 03:24, Martin Buchholz wrote: > Your changes look good, Yes, this is a nice improvement. > but: > > 204 check(map.size() == i, "insertion: map expected size > m%d != i%d", map.size(), i); > > many of those detail messages look like leftovers from a long debugging > session. Here I would consider converting to a testng test (I ended up > doing this a few times myself) and writing very simply, standardly, > efficiently and readably > > assertEquals(map.size(), i); Or could use jdk.testlibrary.Asserts.assertEquals, if you want to avoid spinning up the testng machinery, and generating yet another xml test report. If you are only interested in assertEquals. > only adding more breadcrumbs if it's non-obvious, which is generally not > the case in this test. Either if ok with me. > testMap already prints out keys_desc, so the test output is unambiguous. > > On Wed, May 13, 2015 at 6:44 PM, Stuart Marks > wrote: > >> Hi all, >> >> Please review this change to optimize a test. Basically the test did >> string formatting for every assertion, but the string was thrown away if >> the assertion passed -- the most common case. The change is to do the >> string formatting only when an assertion fails and information needs to be >> printed out. >> >> Thanks to Andrey Zakharov for discovering and investigating this. >> >> Bug report: >> >> https://bugs.openjdk.java.net/browse/JDK-8078463 >> >> Webrev: >> >> http://cr.openjdk.java.net/~smarks/reviews/8078463/webrev.0/ >> >> On my (new, fast) laptop, with JVM options -Xcomp -XX:+DeoptimizeALot >> -client, the unmodified test takes about 21.4 seconds to run. The modified >> test takes only 12.3 seconds. >> >> Note that I have added several overloads of check() with different >> arguments. I tried an alternative, which is a varargs version of check(): >> >> static void check(boolean cond, String fmt, Object... args) { >> if (cond) { >> pass(); >> } else { >> fail(String.format(fmt, args)); >> } >> } >> >> This of course is much simpler code, but it took 14.2 seconds, about 15% >> slower than the proposed version. Is the simpler code worth the slowdown? I >> could go either way. I?ve used the varargs version a number of times in my own tests. It is simple and easy to read. But if this 15% is important, then it could be worth the extra overloads. Either way I?m happy to this this change going in. -Chris. >> >> Thanks. >> >> s'marks >> >> >> From daniel.fuchs at oracle.com Thu May 14 08:22:58 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Thu, 14 May 2015 10:22:58 +0200 Subject: RFR(s): 8078463: optimize java/util/Map/Collisions.java In-Reply-To: <5553FE06.40006@oracle.com> References: <5553FE06.40006@oracle.com> Message-ID: <55545B62.1050608@oracle.com> Hi Stuart, On 5/14/15 3:44 AM, Stuart Marks wrote: > Hi all, > > Please review this change to optimize a test. Basically the test did > string formatting for every assertion, but the string was thrown away > if the assertion passed -- the most common case. The change is to do > the string formatting only when an assertion fails and information > needs to be printed out. > > Thanks to Andrey Zakharov for discovering and investigating this. > > Bug report: > > https://bugs.openjdk.java.net/browse/JDK-8078463 > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8078463/webrev.0/ > > On my (new, fast) laptop, with JVM options -Xcomp -XX:+DeoptimizeALot > -client, the unmodified test takes about 21.4 seconds to run. The > modified test takes only 12.3 seconds. > > Note that I have added several overloads of check() with different > arguments. I tried an alternative, which is a varargs version of check(): > > static void check(boolean cond, String fmt, Object... args) { > if (cond) { > pass(); > } else { > fail(String.format(fmt, args)); > } > } > > This of course is much simpler code, but it took 14.2 seconds, about > 15% slower than the proposed version. Is the simpler code worth the > slowdown? I could go either way. I'm curious: have you tried with using a lambda instead? changing: 394 static void check(String desc, boolean cond) { 395 if (cond) { 396 pass(); 397 } else { 398 fail(desc); 399 } 400 } into static void check(Supplier descSupplier, boolean cond) { if (cond) { pass(); } else { fail(descSupplier.get()) } } I wonder how the performance would compare... best regards, -- daniel > > Thanks. > > s'marks > > From chris.hegarty at oracle.com Thu May 14 08:26:41 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 14 May 2015 09:26:41 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> Message-ID: I think we?ve agreed that we are not going to attempt to re-introduce the problematic interruptible I/O mechanism. These new methods are targeted at specific use-cases and common patterns found in code. I?d like to do a final review of the spec before finalising it. http://cr.openjdk.java.net/~chegar/readBytes/webrev.00 -Chris. On 7 May 2015, at 15:10, Chris Hegarty wrote: > Thanks for the comments. All have been considered and incorporated ( where applicable ). > > I sketched out a readAllBytes, added some basic tests, and moved this into a webrev. I have not created a specdiff, as the changes simply add two new methods, that are easily readable. > > I think this version, less review comments, covers the most common use-cases. > > http://cr.openjdk.java.net/~chegar/readBytes/webrev.00/ > > -Chris. > > On 5 May 2015, at 10:54, Alan Bateman wrote: > >> On 02/05/2015 09:27, Chris Hegarty wrote: >>> : >>> Thanks, this was an editing issue. Removed. >> I think the javadoc looks quite good now, except may be the first statement "Reads some bytes ...". It might be clearer to start with "Reads a given number of bytes ...". The subsequent text makes the short read case and the return value clear. >> >>> >>> As Alan has commented, another readAllBytes() returning a byte[] maybe useful too ( but a different use case ). Let?s park this momentarily, while I sketch up the readAllBytes variant, so we can ensure that the typical use cases have been addressed. Doing so may feedback into the spec of this method. I?ll push this latest draft into the sandbox so it is not lost. >> Yes, a separate use-case but once that I would expect to be common. >> >> -Alan. >> > From peter.levart at gmail.com Thu May 14 08:35:58 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 14 May 2015 10:35:58 +0200 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5553C7A1.8060004@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <5553C7A1.8060004@oracle.com> Message-ID: <55545E6E.9030304@gmail.com> I also have some comments on Dmitry's code... On 05/13/2015 11:52 PM, Derek White wrote: > Hi Dmitry, > > Some review comments below... > > On 5/12/15 1:10 PM, Dmitry Samersoff wrote: >> Everybody, >> >> Updated version: >> >> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >> >> Now it iterates over queue and output result sorted by number of >> instances. > FinalReference.java > - Update copyright to 2015. > > ReferenceQueue.java > - Update copyright to 2015. > > class "mutableInt": > - Should be "MutableInt" > - Not a collections lawyer, but should MutableInt implement Comparable? An alternative is a one-element int[] and the need for additional MutableInt class is eliminated. If you must have it, then perhaps you could make it Comparable and contain an additional String className field. Why? You could then dump the values() of the Map into an array and sort the array without the need for custom Comparator and then iterate the sorted array to build a message. > > countInstances(): > - Javadoc should mention may return null. > - Can countInstances() be package-private? It must be package-private, since ReferenceQueue is public API. Regards, Peter > - After you get the lock in line 138, you should recheck for "head == > null", and return null if so. Otherwise it might sometimes return null > and sometimes return an empty map. > - BIG: Is loop missing? Should "if" at line 140 be "while"? > - Merge lines 147, 148: "} else {" > - Check for consistent line spacing. > > - Derek >> >> -Dmitry >> >> On 2015-05-07 00:51, Derek White wrote: >>> Hi Dmitry, Staffan, >>> >>> Lots of good comments here. >>> >>> On the topic of what list should be printed out, I think we should >>> focus >>> on objects waiting to be finalized - e.g. the contents of the >>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>> could add a summerizeQueue(TreeMap) method, or a >>> general iterator and lambda. >>> >>> A histogram of objects with finalize methods might also be interesting, >>> but you can get most of the same information from a heap histogram >>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>> >>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>> FinalizerThread from making progress (and I think there's a GC thread >>> that runs after GC that sorts found References objects that need >>> processing into their respective ReferenceQueues). But locking the >>> "unfinalized" list blocks initializing any object with a finalize() >>> method. >>> >>> The sorting suggestion is a nice touch. >>> >>> - Derek White, GC team >>> >>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>> Hi Dmitry, Staffan, >>>> >>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>> Dmitry, >>>>> >>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>> well considering the changes to Finalizer. >>>>> >>>>> I?m a little worried about the potentially very large String that is >>>>> returned from printFinalizationQueue(). A possible different approach >>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>> That would allow for outputting one line at a time. The output would >>>>> still be saved in memory (since the stream is buffered), but at least >>>>> the data is only saved once in memory, then. It would make the code a >>>>> bit harder to write, so its a question of how scared we are of >>>>> running out of memory. >>>> If the output is just a histogram of # of instances per class name, >>>> then it should not be too large, as there are not many different >>>> classes overriding finalize() method (I counted 72 overriddings of >>>> finalize() method in the whole jdk/src tree). >>>> >>>> I'm more concerned about the fact that while traversing the list, a >>>> lock is held, which might impact prompt finalization(). Is it >>>> acceptable for diagnostic output to impact performance and/or >>>> interfere with synchronization? >>>> >>>> It might be possible to scan the list without holding a lock for >>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>> Finalizer.next pointer to point back to itself: >>>> >>>> private void remove() { >>>> synchronized (lock) { >>>> if (unfinalized == this) { >>>> if (this.next != null) { >>>> unfinalized = this.next; >>>> } else { >>>> unfinalized = this.prev; >>>> } >>>> } >>>> if (this.next != null) { >>>> this.next.prev = this.prev; >>>> } >>>> if (this.prev != null) { >>>> this.prev.next = this.next; >>>> } >>>> // this.next = this; must not be set so that we can >>>> traverse the list unsynchronized >>>> this.prev = this; /* Indicates that this has been >>>> finalized */ >>>> } >>>> } >>>> >>>> For detecting whether a Finalizer is already processed, the 'prev' >>>> pointer could be used instead: >>>> >>>> private boolean hasBeenFinalized() { >>>> return (prev == this); >>>> } >>>> >>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>> unsynchronized printFinalizationQueue() would get you a fully >>>> initialized Finalizer instance (in particular the next pointer), you >>>> would have to make the 'unfinalized' field volatile or insert an >>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>> >>>> private void add() { >>>> synchronized (lock) { >>>> if (unfinalized != null) { >>>> this.next = unfinalized; >>>> unfinalized.prev = this; >>>> } >>>> // make sure a data race dereferencing 'unfinalized' >>>> // in printFinalizationQueue() does see the Finalizer >>>> // instance fully initialized >>>> // (in particular the 'next' pointer) >>>> U.storeFence(); >>>> unfinalized = this; >>>> } >>>> } >>>> >>>> >>>> By doing these modifications, I think you can remove >>>> synchronized(lock) {} from printFinalizationQueue(). >>>> >>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>> not sure of the difference, perhaps someone from the GC team can help >>>>> out? >>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>> instances pending processing by finalizer thread because their >>>> referents are eligible for finalization (they are not reachable any >>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>> instances for which their referents have not been finalized yet >>>> (including those that are still reachable and alive). The later serves >>>> two purposes: >>>> - it keeps Finalizer instances reachable until they are processed >>>> - it is a source of unfinalized instances for >>>> running-finalizers-on-exit if requested by >>>> System.runFinalizersOnExit(true); >>>> >>>> So it really depends on what one would like to see. Showing the queue >>>> may be interesting if one wants to see how the finalizer thread is >>>> coping with processing the finalize() invocations. Showing unfinalized >>>> list may be interesting if one wants to know how many live + >>>> finalization pending instances are there on the heap that override >>>> finalize() method. >>>> >>>> Regards, Peter >>>> >>>>> For the output, it would be a nice touch to sort it on the number of >>>>> references for each type. Perhaps outputting it more like a table >>>>> (see the old code again) would also make it easier to digest. >>>>> >>>>> In diagnosticCommand.hpp, the new commands should override >>>>> permission() and limit access: >>>>> >>>>> static const JavaPermission permission() { >>>>> JavaPermission p = >>>>> {"java.lang.management.ManagementPermission", >>>>> "monitor", NULL}; >>>>> return p; >>>>> } >>>>> >>>>> The two tests don?t validate the output in any way. Would it be >>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>> the finalizer queue? Hmm. >>>>> >>>>> Thanks, >>>>> /Staffan >>>>> >>>>> >>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>> wrote: >>>>>> >>>>>> Everyone, >>>>>> >>>>>> Please review the fix: >>>>>> >>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>> >>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>> >>>>>> finalizerinfo dcmd outputs a list of all classes in finalization >>>>>> queue >>>>>> with count >>>>>> >>>>>> -Dmitry >>>>>> >>>>>> -- >>>>>> Dmitry Samersoff >>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>> * I would love to change the world, but they won't give me the >>>>>> sources. >> > From patrick at reini.net Thu May 14 10:05:08 2015 From: patrick at reini.net (Patrick Reinhart) Date: Thu, 14 May 2015 12:05:08 +0200 Subject: Updating existing JDK code to use InputStream.transferTo() In-Reply-To: References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <55539C1B.2060909@reini.net> Message-ID: <55547354.6080401@reini.net> Hi Pavel, On 14.05.2015 01:28, Pavel Rappo wrote: >>> Let me start then. >>> >>> 1. I've seen several cases where current behaviour >>> >>> while ((n = in.read(buffer)) > 0) >>> ~~~ >>> has been changed to >>> >>> while ((read = this.read(buffer, 0, TRANSFER_BUFFER_SIZE)) >= 0) >>> ~~~ >>> >>> Those things jump out at you, but don't seem to be harmful, since the only case >>> where: >>> >>> java.io.InputStream.read(byte[], int off, int len) >>> java.io.InputStream#read(byte[]) >>> >>> may return 0, is when len == 0. And it's never the case here. Unless, of course, >>> some misbehaving implementation of InputStream is used. >> Do you think we should change our general behaviour to "> -1" instead of ">=0" ? > (Currently being discussed on core-libs-dev) I saw that... >>> 2. jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java >>> >>> Some of the refactored methods there seem to be unused: >>> >>> getBytesFromFile(String) >>> writeBytesToFilename(String, byte[]) >>> >>> Should we remove them instead? >> When it's no longer used, it makes no sense to have this method I would say. Due to the edit process has took >> place within a simple editor, I simply overlooked that fact. > No problem. In fact I will need to check this with my colleagues to make sure we > can safely do this. Otherwise if this thing, say, is regularly updated from some > Apache project, they might bring it (and/or dependencies on it) the next time > they update. This doesn't sound right to me. Thus we have to be super careful > even with the update you've proposed. Or we leave that out in those special cases where we use "external" sources >>> 4. I wonder if javax.management.loading.MLet.loadLibraryAsResource and >>> sun.net.www.MimeLauncher.run could be refactored with more appropriate >>> >>> Files.copy(is, file.toPath()) >>> >>> as it seems to fit there perfectly. >> I will try to do so and send in a new Patch for this... > It's absolutely fine for now. You can leave it as it is. java.nio.Files' time > will come. I've put this on my list of things to do later then... ;-) >>> 6. I've run into several cases where code use explicit `flush()` for >>> ByteArrayOutputStream, BufferedOutputStream. For the former one it's never >>> needed. The latter one does it automatically on `close()`. >>> Should we still call them? >> There I'm not really sure, as a matter of fact, the close() is being done on the try block exit and that is >> being done after putting the return value on the stack as I believe (but I could be wrong). >> >> For the reason of my uncertainty I left the flush() method call in... > Which one is that you're not sure about? > > BTW, looks like we've missed one more snippet in sun.print.UnixPrintJob: > > try { > while ((cread = br.read(buffer, 0, buffer.length)) >=0) { > bw.write(buffer, 0, cread); > } > br.close(); > bw.flush(); > bw.close(); > } catch (IOException e) { > notifyEvent(PrintJobEvent.JOB_FAILED); > throw new PrintException (e); > } Sould I make the change or will you do it? >>> 7. org.jcp.xml.dsig.internal.dom.Utils.readBytesFromStream is a little bit >>> awkward since it used 1024 as some sort of a cut-off. >>> It might've had something to do with EOF detection, but I'm not sure. >> The way I was coming to the current implementation was based on due the fact, that we almost would have one read >> operation iteration more in case the last read amount would be less than 1024 but instead having a comparison more >> in each loop. > The same thing as with (2). I don't like the package name. It might be synced > from the outside of the JDK. Seem reasonable to me too. >>> It seems ok to remove the FileNotFoundException branch. Or I'm missing something. >> No, I thing you're right due to the fact that the FileNotFoundException extends IOException anyway. Or would a >> multi catch block make more sense? >> >> } catch (FileNotFoundException | IOException e) { >> notifyEvent(PrintJobEvent.JOB_FAILED); >> throw new PrintException(e.toString()); >> } > I think we'd better remove it. As we both noticed, FileNotFoundException is a > subtype of IOException. That's totally fine for me >> When looking closer to that code part now, I ask myself if it's a good thing to have the causing stack being lost >> there and would it not be better to pass the causing exception? >> >> } catch (FileNotFoundException | IOException e) { >> notifyEvent(PrintJobEvent.JOB_FAILED); >> throw new PrintException(e); >> } > It would, you're right. Unfortunately we don't know how this exception might be > used. Maybe there was a reason for not including the cause or it might have been > just done before the "cause" field in Throwable became available (before > JDK1.4) I'm pretty sure about this. Here I guess we could ask the responsible group. Besides that, we could compose the PrintException in a way, that the message stays the same and we additionally have the causing exception: } catch (IOException e) { notifyEvent(PrintJobEvent.JOB_FAILED); throw new PrintException(e.toString(), e); } >>> 9. I don't think I would agree with some changes in sun.net.www.MimeLauncher.run >>> as they obviously make the new version not equivalent to the old one. Non >>> swallowed IOException, additional null check. Way too much for the cleanup >>> change. >> Well, the null check I agree. To have the same behaviour, we simply skip remove the null check. >> >> Your objection about the not swallowed IOException I can not see because it's being swallowed in the >> outer try-catch block at last. So I think that will result in the same result here. > Yes, it's swallowed by the outer block. But as far as I can see it now doesn't > do all these things after an exception is thrown from inside `transferTo`: > > int inx = 0; > String c = execPath; > while ((inx = c.indexOf("%t")) >= 0) { > c = c.substring(0, inx) + uc.getContentType() > + c.substring(inx + 2); > } > > boolean substituted = false; > while ((inx = c.indexOf("%s")) >= 0) { > c = c.substring(0, inx) + ofn + c.substring(inx + 2); > substituted = true; > } > if (!substituted) > c = c + " <" + ofn; > > // System.out.println("Execing " +c); > > Runtime.getRuntime().exec(c); Now I got the your point. I should stop writing emails and looking into code at 1 am ;-) > ------------------------------------------------------------------------------- > P.S. And yes, Remi is right, we'd better split this thing into several pieces -- > according to areas. I agree, the Linux find command does not stop on responsible groups boundaries ;-) > Following 3-4 weeks I might become unresponsive on core-libs or privately as I'm > busy with another project (just in case). No problem, thanks for informing me. I also applied for author role, so that it's becoming easier, to maintain webrev's by myself instead of posting diff's and you have to create again a webrev in turn.... > Thanks a lot for doing this, Patrick. It's really useful. You're welcome, I'de love to some more in the future... -Patrick From peter.levart at gmail.com Thu May 14 11:27:58 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 14 May 2015 13:27:58 +0200 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> Message-ID: <555486BE.50000@gmail.com> On 05/14/2015 03:16 AM, Brian Goetz wrote: > Not only is there a problem with modCount, but also with equals/hashCode/toString. You can?t define these Object methods in an interface. They could be defined as static methods to delegate to. From API consistency perspective, we have for example the following static methods on primitive wrapper classes: Boolean.hashCode(boolean) Byte.hashCode(byte) Character.hashCode(char) Short.hashCode(short) ... They are defined to return the same as instance methods of corresponding wrapper classes. What I am missing sometimes is the equivalent of equals methods: Boolean.equals(boolean, boolean) Byte.equals(byte, byte) That's perhaps because one can use '==' operator instead, but the definition of '==' operator is different for float and double values from corresponding .equals() methods for their wrapper classes. If for nothing else, static equals methods could be useful to avoid boxing the primitive to access the semantics of wrapper .equals(). Bringing this to List interface, there could be three static methods implementing the basic List contract: static int hashCode(List list) { ... } static boolean equals(List list, Object obj); static String toString(List list); Fortunately, static interface methods are not "inherited" so they don't pollute the namespace of implementing classes and can't be invoked via instance either so they don't pollute the IDE auto-completion pop-ups. Regards, Peter > > On May 8, 2015, at 5:41 AM, Attila Szegedi wrote: > >> So I?m in a position where I?d need to have a class implement List, but it already extends something else, so I can?t have it extend AbstractList, which leaves me with a lot of boilerplate methods to implement. >> >> Would it seem like a good idea to reimagine AbstractList and friends as interfaces with default methods? >> >> Of course, I know that technically for backwards compatibility we can?t really do this, but what we could do is: >> >> public interface DefaultList extends List { >> ? add all methods from AbstractList here as default methods ? >> } >> >> public abstract class AbstractList implements DefaultList { >> } >> >> (I?ll hand-wave the issue of ?protected int modCount? issue for now.) >> >> Actually, this seems like such an obvious idea that I?m 100% sure it must?ve been considered before, but I can?t find any related discussion. >> >> Attila. From vladimir.x.ivanov at oracle.com Thu May 14 11:43:57 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Thu, 14 May 2015 14:43:57 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <882B8D85-62B4-4734-8CA7-0BFD45DB73B3@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <882B8D85-62B4-4734-8CA7-0BFD45DB73B3@oracle.com> Message-ID: <55548A7D.3000606@oracle.com> Thanks, Roland. Best regards, Vladimir Ivanov On 5/13/15 4:47 PM, Roland Westrelin wrote: >> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02/ > > The hotspot code looks good to me. > > Roland. > From Alan.Bateman at oracle.com Thu May 14 11:49:03 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 14 May 2015 12:49:03 +0100 Subject: 8080330: (cs) Charset.availableCharsets failing with NPE on several platforms Message-ID: <55548BAF.8070808@oracle.com> This method is currently broken in jdk9/dev and is causing several test failures. It looks like the changes JDK-8035302 missed a file. I need a Reviewer for the patch below. Additionally the test/sun/nio/cs/TestCompoundTest.java can be removed. I'm sure Sherman will have suggestions for other clean-up but for now I think it would be good to get jdk9/dev stable again. Thanks, Alan. diff --git a/make/data/charsetmapping/charsets b/make/data/charsetmapping/charsets --- a/make/data/charsetmapping/charsets +++ b/make/data/charsetmapping/charsets @@ -1833,10 +1833,3 @@ ## ######################################################## -charset x-COMPOUND_TEXT COMPOUND_TEXT - package sun.nio.cs.ext - type source - os unix - alias COMPOUND_TEXT # JDK historical - alias x11-compound_text - alias x-compound-text From vladimir.x.ivanov at oracle.com Thu May 14 12:18:31 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Thu, 14 May 2015 15:18:31 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> <55533CAE.3050201@oracle.com> Message-ID: <55549297.5020002@oracle.com> Small update in JDK code (webrev updated in place): http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 Changes: - hid Context.dependencies field from Reflection - new test case: CallSiteDepContextTest.testHiddenDepField() Best regards, Vladimir Ivanov On 5/13/15 5:56 PM, Paul Sandoz wrote: > > On May 13, 2015, at 1:59 PM, Vladimir Ivanov wrote: > >> Peter, Paul, thanks for the feedback! >> >> Updated the webrev in place: >> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 >> > > +1 > > >>> I am not an export in the HS area but the code mostly made sense to me. I also like Peter's suggestion of Context implementing Runnable. >> I agree. Integrated. >> >>> Some minor comments. >>> >>> CallSite.java: >>> >>> 145 private final long dependencies = 0; // Used by JVM to store JVM_nmethodBucket* >>> >>> It's a little odd to see this field be final, but i think i understand the motivation as it's essentially acting as a memory address pointing to the head of the nbucket list, so in Java code you don't want to assign it to anything other than 0. >> Yes, my motivation was to forbid reads & writes of the field from Java code. I was experimenting with injecting the field by VM, but it's less attractive. >> > > I was wondering if that were possible. > > >>> Is VM access, via java_lang_invoke_CallSite_Context, affected by treating final fields as really final in the j.l.i package? >> No, field modifiers aren't respected. oopDesc::*_field_[get|put] does a raw read/write using field offset. >> > > Ok. > > Paul. > From peter.levart at gmail.com Thu May 14 12:19:40 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 14 May 2015 14:19:40 +0200 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <55535CC7.3000503@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> Message-ID: <555492DC.7030707@gmail.com> Hi Roger, The new API using Optional(s) looks fine. In particular for the ProcessHandle returning methods. They now either return Stream or Optional. At some point in the development of this API, the implementation introduced the AsyncExecutor to execute synchronous continuations of the onExit() returned CompletableFuture(s). What was the main motivation for this given that: - previously, ForkJoinPoll.commonPool() was used instead that by default possesses some similar characteristics (Innocuous threads when SecurityManager is active) - this AsyncExecutor is only effective for 1st "wave" of synchronous continuations. Asynchronous continuations and synchronous continuations following them will still use ForkJoinPoll.commonPool() Would an alternative be to define two overloaded onExit() methods in the style of CompletableFuture itself? CompletableFuture onExit(); CompletableFuture onExit(Executor executor); ...and give the user a chance to supply it's own Executor if the default ForkJoinPoll.commonPool() does not fit? Is there expectation that ForkJoinPoll.commonPool() will not fit in the common case? Regards, Peter On 05/13/2015 04:16 PM, Roger Riggs wrote: > Hi, > > Are there any comments about the use of java.util.Optional in the > ProcessHandle API? > Or a review of the changes? > > Thanks, Roger > > > On 5/11/2015 11:49 AM, Roger Riggs wrote: >> Please review clarifications and updates to the proposed Precess API. >> >> A few loose ends in the ProcessHandle API were identified. >> >> 1) The ProcessHandle.parent() method currently returns null if the >> parent cannot >> be determined and the ProcessHandle.of(PID) method returns null if >> the PID does not exist. >> It has been suggested to return an Optional to make >> these methods more flexible and allow a fluent style and work better >> with streams. >> >> 2) The behavior of Processhandle.destroy and destroyForcibly are >> different >> than Process.destroy and destroyForcibly. Those functions always >> succeed because >> they are children of the spawning process. >> >> In contrast, ProcessHandle.destroy and destroyForcible are requests to >> destroy the process and may not succeed due to operating system >> restrictions such >> as the process not being a child or not having enough privilege. >> The description of the methods needs to be clarified that it is a >> request to destroy >> and it may not succeed, In that case the destroy and destroyForcibly >> methods >> should indicate that the request was not successful. In particular, >> the caller >> may not want to wait for the process to terminate (its not going to). >> >> The proposed update is to return an Optional . >> It can be streamed and can take advantage of the conditional >> operations on the Optional. >> >> 3) Using Optional is also attractive for the return values of the >> information >> about a ProcessHandles, since not all values are available from every >> OS. >> The returns values of Info.command, arguments, startInstant, >> totalDuration, and user >> are proposed to be updated to return Optional. >> It allows for more compact code and fewer explicit checks for null. >> >> Please review and comment: >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-ph/ >> >> javadoc: >> http://cr.openjdk.java.net/~rriggs/ph-apidraft/ >> >> Diffs of the spec/javadoc from previous draft: >> http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-11/overview-summary.html >> >> >> Thanks, Roger >> >> >> > From Alan.Bateman at oracle.com Thu May 14 12:30:03 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 14 May 2015 13:30:03 +0100 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <55536981.80505@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555365E3.2020700@oracle.com> <55536981.80505@Oracle.com> Message-ID: <5554954B.6020606@oracle.com> On 13/05/2015 16:10, Roger Riggs wrote: > Hi Alan, > > Yes, the destroy use looks a bit odd. In Process, destroyForcibly > returns this so that the application can fluently wait for the > termination to complete. > Returning Optional enables the case to fluently > perform an action on the process when it does exit. > > ProcessHandle ph = ...; > ph.destroy().ifPresent(p -> p.onExit( ...)); > > Optional.isPresent() provides a boolean if that's needed. Optional is good and the usages with parent(), etc. are nice update to the API. Chaining methods invocations is good too. It's just destroy that seems a bit much as it's too easy to mix up "present" and "alive", e.g.: the process was present so we attempted to destroy it, it may or may not be present now. In that context using ifPresent in this example is confusing to read because it's really "was present, on its way to not being present" (if you know what I mean). That's the only one that might need to be looked at again to see if there are better candidates. Related to this is that the destroy methods don't have a way to communicate anything useful to log when they fail. With Process no long implementing ProcessHandle then there is an opportunity to look at that again. -Alan. From chris.hegarty at oracle.com Thu May 14 12:47:11 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 14 May 2015 13:47:11 +0100 Subject: 8080330: (cs) Charset.availableCharsets failing with NPE on several platforms In-Reply-To: <55548BAF.8070808@oracle.com> References: <55548BAF.8070808@oracle.com> Message-ID: <5932511D-7C70-4C98-ACA4-165360022078@oracle.com> The changes looks fine Alan. -Chris. On 14 May 2015, at 12:49, Alan Bateman wrote: > > This method is currently broken in jdk9/dev and is causing several test failures. It looks like the changes JDK-8035302 missed a file. > > I need a Reviewer for the patch below. Additionally the test/sun/nio/cs/TestCompoundTest.java can be removed. I'm sure Sherman will have suggestions for other clean-up but for now I think it would be good to get jdk9/dev stable again. > > Thanks, > Alan. > > > diff --git a/make/data/charsetmapping/charsets b/make/data/charsetmapping/charsets > --- a/make/data/charsetmapping/charsets > +++ b/make/data/charsetmapping/charsets > @@ -1833,10 +1833,3 @@ > ## > ######################################################## > > -charset x-COMPOUND_TEXT COMPOUND_TEXT > - package sun.nio.cs.ext > - type source > - os unix > - alias COMPOUND_TEXT # JDK historical > - alias x11-compound_text > - alias x-compound-text From brian.goetz at oracle.com Thu May 14 13:05:33 2015 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 14 May 2015 09:05:33 -0400 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: <555486BE.50000@gmail.com> References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> Message-ID: <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> >> Not only is there a problem with modCount, but also with equals/hashCode/toString. You can?t define these Object methods in an interface. > > They could be defined as static methods to delegate to. From API consistency perspective, we have for example the following static methods on primitive wrapper classes: Right. We considered this during Lambda, but by the time we got here, we concluded that this was mostly trading one downside for another. It seemed overwhelmingly likely that people would forget to override equals/hashCode/toString in this case, and create collections that violated the contract. From forax at univ-mlv.fr Thu May 14 13:24:53 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 14 May 2015 15:24:53 +0200 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> Message-ID: <5554A225.4070107@univ-mlv.fr> On 05/14/2015 03:05 PM, Brian Goetz wrote: >>> Not only is there a problem with modCount, but also with equals/hashCode/toString. You can?t define these Object methods in an interface. >> They could be defined as static methods to delegate to. From API consistency perspective, we have for example the following static methods on primitive wrapper classes: > Right. We considered this during Lambda, but by the time we got here, we concluded that this was mostly trading one downside for another. It seemed overwhelmingly likely that people would forget to override equals/hashCode/toString in this case, and create collections that violated the contract. > The other problem is that it creates ambiguous method references, if you have a class or an interface like: class A { public static int hashCode(A a) { ... } } A::hashCode is ambiguous. cheers, R?mi From aph at redhat.com Thu May 14 13:40:13 2015 From: aph at redhat.com (Andrew Haley) Date: Thu, 14 May 2015 14:40:13 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5553997A.7030401@oracle.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> <5553784A.4030607@redhat.com> <5553997A.7030401@oracle.com> Message-ID: <5554A5BD.2080602@redhat.com> On 05/13/2015 07:35 PM, Alan Bateman wrote: > > > A few passing comments on the test > - Is errors incremented anywhere? Oops. I realized after sending the email that I needed to strengthen the test. If one of the four {get,put} operations fails then all four should fail. I added a check for this. > - You could reduce the code a bit by catching Throwable once. Also would > be good to have it be the cause for the RuntimeException so that the > original exception/error isn't lost. OK. > - Personally I would reduce the line length but this area might be okay > with very long lines. I tried. Fix: http://cr.openjdk.java.net/~aph/8079459-3-jdk/ Testcase: http://cr.openjdk.java.net/~aph/8079459-3-hs/ Andrew. From Roger.Riggs at Oracle.com Thu May 14 13:44:52 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 14 May 2015 09:44:52 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555492DC.7030707@gmail.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> Message-ID: <5554A6D4.6060902@Oracle.com> Hi Peter, On 5/14/15 8:19 AM, Peter Levart wrote: > Hi Roger, > > The new API using Optional(s) looks fine. In particular for the > ProcessHandle returning methods. They now either return > Stream or Optional. > > At some point in the development of this API, the implementation > introduced the AsyncExecutor to execute synchronous continuations of > the onExit() returned CompletableFuture(s). What was the main > motivation for this given that: > - previously, ForkJoinPoll.commonPool() was used instead that by > default possesses some similar characteristics (Innocuous threads when > SecurityManager is active) The AsyncExecutor also uses InnocuousThreads. > - this AsyncExecutor is only effective for 1st "wave" of synchronous > continuations. Asynchronous continuations and synchronous > continuations following them will still use ForkJoinPoll.commonPool() Unfortunately, the common ForkJoinPool assumes that tasks queued to it complete relatively quickly and free the thread. It does not grow the number of threads and is not appropriate for tasks that block for indefinite periods as might be need to wait for a Process to exit. > > Would an alternative be to define two overloaded onExit() methods in > the style of CompletableFuture itself? > > CompletableFuture onExit(); > CompletableFuture onExit(Executor executor); > > ...and give the user a chance to supply it's own Executor if the > default ForkJoinPoll.commonPool() does not fit? It is only one more method in PH and Process but that function is available from CompletableFuture though perhaps not as conveniently. The onExit method returns a CompletableFuture that has the entire complement of synchronous and async methods available to it. The application can control where subsequent computations are performed. That convenience method could be added later when the use case and frequency is clearer. > > Is there expectation that ForkJoinPoll.commonPool() will not fit in > the common case? I don't have a sense of how onExit would be used or how often it would be used. The common FJP seems like a good start for computations to be performed after the Process has exited. I'd wait and see what needs can be articulated., hopefully within the JDK 9 timeframe. Thanks, Roger > > Regards, Peter > > On 05/13/2015 04:16 PM, Roger Riggs wrote: >> Hi, >> >> Are there any comments about the use of java.util.Optional in the >> ProcessHandle API? >> Or a review of the changes? >> >> Thanks, Roger >> >> >> On 5/11/2015 11:49 AM, Roger Riggs wrote: >>> Please review clarifications and updates to the proposed Precess API. >>> >>> A few loose ends in the ProcessHandle API were identified. >>> >>> 1) The ProcessHandle.parent() method currently returns null if the >>> parent cannot >>> be determined and the ProcessHandle.of(PID) method returns null if >>> the PID does not exist. >>> It has been suggested to return an Optional to make >>> these methods more flexible and allow a fluent style and work better >>> with streams. >>> >>> 2) The behavior of Processhandle.destroy and destroyForcibly are >>> different >>> than Process.destroy and destroyForcibly. Those functions always >>> succeed because >>> they are children of the spawning process. >>> >>> In contrast, ProcessHandle.destroy and destroyForcible are requests to >>> destroy the process and may not succeed due to operating system >>> restrictions such >>> as the process not being a child or not having enough privilege. >>> The description of the methods needs to be clarified that it is a >>> request to destroy >>> and it may not succeed, In that case the destroy and destroyForcibly >>> methods >>> should indicate that the request was not successful. In particular, >>> the caller >>> may not want to wait for the process to terminate (its not going to). >>> >>> The proposed update is to return an Optional . >>> It can be streamed and can take advantage of the conditional >>> operations on the Optional. >>> >>> 3) Using Optional is also attractive for the return values of the >>> information >>> about a ProcessHandles, since not all values are available from >>> every OS. >>> The returns values of Info.command, arguments, startInstant, >>> totalDuration, and user >>> are proposed to be updated to return Optional. >>> It allows for more compact code and fewer explicit checks for null. >>> >>> Please review and comment: >>> >>> Webrev: >>> http://cr.openjdk.java.net/~rriggs/webrev-ph/ >>> >>> javadoc: >>> http://cr.openjdk.java.net/~rriggs/ph-apidraft/ >>> >>> Diffs of the spec/javadoc from previous draft: >>> http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-11/overview-summary.html >>> >>> >>> Thanks, Roger >>> >>> >>> >> > From peter.levart at gmail.com Thu May 14 13:51:22 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 14 May 2015 15:51:22 +0200 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: <5554A225.4070107@univ-mlv.fr> References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> <5554A225.4070107@univ-mlv.fr> Message-ID: <5554A85A.3020204@gmail.com> On 05/14/2015 03:24 PM, Remi Forax wrote: > > > On 05/14/2015 03:05 PM, Brian Goetz wrote: >>>> Not only is there a problem with modCount, but also with >>>> equals/hashCode/toString. You can?t define these Object methods in >>>> an interface. >>> They could be defined as static methods to delegate to. From API >>> consistency perspective, we have for example the following static >>> methods on primitive wrapper classes: >> Right. We considered this during Lambda, but by the time we got >> here, we concluded that this was mostly trading one downside for >> another. It seemed overwhelmingly likely that people would forget to >> override equals/hashCode/toString in this case, and create >> collections that violated the contract. That's a good reason. >> > > The other problem is that it creates ambiguous method references, > if you have a class or an interface like: > class A { > public static int hashCode(A a) { ... } > } > > A::hashCode is ambiguous. Ah, I see. Then Integer::hashCode is ambiguous too if the target functional interface takes boxed Integer parameter. Regards, Peter > > cheers, > R?mi > From vitalyd at gmail.com Thu May 14 13:52:38 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 14 May 2015 09:52:38 -0400 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: <5554A225.4070107@univ-mlv.fr> References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> <5554A225.4070107@univ-mlv.fr> Message-ID: Ambiguous in isolation, but within context they're quite different: one takes an arg and the other is void. sent from my phone On May 14, 2015 9:25 AM, "Remi Forax" wrote: > > > On 05/14/2015 03:05 PM, Brian Goetz wrote: > >> Not only is there a problem with modCount, but also with >>>> equals/hashCode/toString. You can?t define these Object methods in an >>>> interface. >>>> >>> They could be defined as static methods to delegate to. From API >>> consistency perspective, we have for example the following static methods >>> on primitive wrapper classes: >>> >> Right. We considered this during Lambda, but by the time we got here, we >> concluded that this was mostly trading one downside for another. It seemed >> overwhelmingly likely that people would forget to override >> equals/hashCode/toString in this case, and create collections that violated >> the contract. >> >> > The other problem is that it creates ambiguous method references, > if you have a class or an interface like: > class A { > public static int hashCode(A a) { ... } > } > > A::hashCode is ambiguous. > > cheers, > R?mi > > From Roger.Riggs at Oracle.com Thu May 14 13:53:25 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 14 May 2015 09:53:25 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <5554954B.6020606@oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555365E3.2020700@oracle.com> <55536981.80505@Oracle.com> <5554954B.6020606@oracle.com> Message-ID: <5554A8D5.3020008@Oracle.com> Hi Alan, For something to log from an inoperative destroy call, are you thinking it should throw an exception? In that case the return value could be void and the exception message could expose the OS specific reason. None of the currently available exceptions seem appropriate; A bare RuntimeException might do but perhaps a new exception class is needed. Thanks, Roger On 5/14/15 8:30 AM, Alan Bateman wrote: > > > On 13/05/2015 16:10, Roger Riggs wrote: >> Hi Alan, >> >> Yes, the destroy use looks a bit odd. In Process, destroyForcibly >> returns this so that the application can fluently wait for the >> termination to complete. >> Returning Optional enables the case to fluently >> perform an action on the process when it does exit. >> >> ProcessHandle ph = ...; >> ph.destroy().ifPresent(p -> p.onExit( ...)); >> >> Optional.isPresent() provides a boolean if that's needed. > Optional is good and the usages with parent(), etc. are nice update to > the API. Chaining methods invocations is good too. > > It's just destroy that seems a bit much as it's too easy to mix up > "present" and "alive", e.g.: the process was present so we attempted > to destroy it, it may or may not be present now. In that context using > ifPresent in this example is confusing to read because it's really > "was present, on its way to not being present" (if you know what I > mean). That's the only one that might need to be looked at again to > see if there are better candidates. Related to this is that the > destroy methods don't have a way to communicate anything useful to log > when they fail. With Process no long implementing ProcessHandle then > there is an opportunity to look at that again. > > -Alan. > From brian.goetz at oracle.com Thu May 14 14:04:03 2015 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 14 May 2015 10:04:03 -0400 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> <5554A225.4070107@univ-mlv.fr> Message-ID: The static-instance asymmetry cancels that one out. If you have class Foo { void m(int x) static void m(Foo f, int x) } Then Foo::x could either be an unbound mref to the instance method or a static mref. Even with a perfect target type (Foo, int) -> void, compiler will still report ambiguity. On May 14, 2015, at 9:52 AM, Vitaly Davidovich wrote: > Ambiguous in isolation, but within context they're quite different: one > takes an arg and the other is void. > > sent from my phone > On May 14, 2015 9:25 AM, "Remi Forax" wrote: > >> >> >> On 05/14/2015 03:05 PM, Brian Goetz wrote: >> >>> Not only is there a problem with modCount, but also with >>>>> equals/hashCode/toString. You can?t define these Object methods in an >>>>> interface. >>>>> >>>> They could be defined as static methods to delegate to. From API >>>> consistency perspective, we have for example the following static methods >>>> on primitive wrapper classes: >>>> >>> Right. We considered this during Lambda, but by the time we got here, we >>> concluded that this was mostly trading one downside for another. It seemed >>> overwhelmingly likely that people would forget to override >>> equals/hashCode/toString in this case, and create collections that violated >>> the contract. >>> >>> >> The other problem is that it creates ambiguous method references, >> if you have a class or an interface like: >> class A { >> public static int hashCode(A a) { ... } >> } >> >> A::hashCode is ambiguous. >> >> cheers, >> R?mi >> >> From vitalyd at gmail.com Thu May 14 14:06:46 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 14 May 2015 10:06:46 -0400 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> <5554A225.4070107@univ-mlv.fr> Message-ID: That's an implementation detail not a fundamental issue right? sent from my phone On May 14, 2015 10:04 AM, "Brian Goetz" wrote: > The static-instance asymmetry cancels that one out. If you have > > class Foo { > void m(int x) > static void m(Foo f, int x) > } > > Then Foo::x could either be an unbound mref to the instance method or a > static mref. Even with a perfect target type (Foo, int) -> void, compiler > will still report ambiguity. > > On May 14, 2015, at 9:52 AM, Vitaly Davidovich wrote: > > > Ambiguous in isolation, but within context they're quite different: one > > takes an arg and the other is void. > > > > sent from my phone > > On May 14, 2015 9:25 AM, "Remi Forax" wrote: > > > >> > >> > >> On 05/14/2015 03:05 PM, Brian Goetz wrote: > >> > >>> Not only is there a problem with modCount, but also with > >>>>> equals/hashCode/toString. You can?t define these Object methods in > an > >>>>> interface. > >>>>> > >>>> They could be defined as static methods to delegate to. From API > >>>> consistency perspective, we have for example the following static > methods > >>>> on primitive wrapper classes: > >>>> > >>> Right. We considered this during Lambda, but by the time we got here, > we > >>> concluded that this was mostly trading one downside for another. It > seemed > >>> overwhelmingly likely that people would forget to override > >>> equals/hashCode/toString in this case, and create collections that > violated > >>> the contract. > >>> > >>> > >> The other problem is that it creates ambiguous method references, > >> if you have a class or an interface like: > >> class A { > >> public static int hashCode(A a) { ... } > >> } > >> > >> A::hashCode is ambiguous. > >> > >> cheers, > >> R?mi > >> > >> > > From forax at univ-mlv.fr Thu May 14 14:26:45 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 14 May 2015 16:26:45 +0200 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> <5554A225.4070107@univ-mlv.fr> Message-ID: <5554B0A5.7020104@univ-mlv.fr> javac should emit a lint warning in these cases to help API designers. I have created 8080413 [1] to track that. R?mi [1] https://bugs.openjdk.java.net/browse/JDK-8080413 On 05/14/2015 04:04 PM, Brian Goetz wrote: > The static-instance asymmetry cancels that one out. If you have > > class Foo { > void m(int x) > static void m(Foo f, int x) > } > > Then Foo::x could either be an unbound mref to the instance method or a static mref. Even with a perfect target type (Foo, int) -> void, compiler will still report ambiguity. > > On May 14, 2015, at 9:52 AM, Vitaly Davidovich wrote: > >> Ambiguous in isolation, but within context they're quite different: one >> takes an arg and the other is void. >> >> sent from my phone >> On May 14, 2015 9:25 AM, "Remi Forax" wrote: >> >>> >>> On 05/14/2015 03:05 PM, Brian Goetz wrote: >>> >>>> Not only is there a problem with modCount, but also with >>>>>> equals/hashCode/toString. You can?t define these Object methods in an >>>>>> interface. >>>>>> >>>>> They could be defined as static methods to delegate to. From API >>>>> consistency perspective, we have for example the following static methods >>>>> on primitive wrapper classes: >>>>> >>>> Right. We considered this during Lambda, but by the time we got here, we >>>> concluded that this was mostly trading one downside for another. It seemed >>>> overwhelmingly likely that people would forget to override >>>> equals/hashCode/toString in this case, and create collections that violated >>>> the contract. >>>> >>>> >>> The other problem is that it creates ambiguous method references, >>> if you have a class or an interface like: >>> class A { >>> public static int hashCode(A a) { ... } >>> } >>> >>> A::hashCode is ambiguous. >>> >>> cheers, >>> R?mi >>> >>> From brian.goetz at oracle.com Thu May 14 14:27:14 2015 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 14 May 2015 10:27:14 -0400 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> <5554A225.4070107@univ-mlv.fr> Message-ID: <2374ACA5-8CE2-44FE-89CC-0AF40C23ED21@oracle.com> No, it?s fundamental, and it was a conscious trade-off. The uniformity of using the same syntax for all flavors of method references outweighed the small number of collisions like this one. On May 14, 2015, at 10:06 AM, Vitaly Davidovich wrote: > That's an implementation detail not a fundamental issue right? > > sent from my phone > > On May 14, 2015 10:04 AM, "Brian Goetz" wrote: > The static-instance asymmetry cancels that one out. If you have > > class Foo { > void m(int x) > static void m(Foo f, int x) > } > > Then Foo::x could either be an unbound mref to the instance method or a static mref. Even with a perfect target type (Foo, int) -> void, compiler will still report ambiguity. > > On May 14, 2015, at 9:52 AM, Vitaly Davidovich wrote: > > > Ambiguous in isolation, but within context they're quite different: one > > takes an arg and the other is void. > > > > sent from my phone > > On May 14, 2015 9:25 AM, "Remi Forax" wrote: > > > >> > >> > >> On 05/14/2015 03:05 PM, Brian Goetz wrote: > >> > >>> Not only is there a problem with modCount, but also with > >>>>> equals/hashCode/toString. You can?t define these Object methods in an > >>>>> interface. > >>>>> > >>>> They could be defined as static methods to delegate to. From API > >>>> consistency perspective, we have for example the following static methods > >>>> on primitive wrapper classes: > >>>> > >>> Right. We considered this during Lambda, but by the time we got here, we > >>> concluded that this was mostly trading one downside for another. It seemed > >>> overwhelmingly likely that people would forget to override > >>> equals/hashCode/toString in this case, and create collections that violated > >>> the contract. > >>> > >>> > >> The other problem is that it creates ambiguous method references, > >> if you have a class or an interface like: > >> class A { > >> public static int hashCode(A a) { ... } > >> } > >> > >> A::hashCode is ambiguous. > >> > >> cheers, > >> R?mi > >> > >> > From vitalyd at gmail.com Thu May 14 14:34:46 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 14 May 2015 10:34:46 -0400 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: <2374ACA5-8CE2-44FE-89CC-0AF40C23ED21@oracle.com> References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> <5554A225.4070107@univ-mlv.fr> <2374ACA5-8CE2-44FE-89CC-0AF40C23ED21@oracle.com> Message-ID: That's fine, not complaining, but as you say, it was a conscious design decision; alternative syntax could have been used to not make this ambiguous. Given that APIs try to be lean and only support minimal required functionality, "extensions" are bolted on via static helper methods, so having a way to avoid this ambiguity would've been nice. But not a big deal, we can just name things differently then :) On Thu, May 14, 2015 at 10:27 AM, Brian Goetz wrote: > No, it?s fundamental, and it was a conscious trade-off. The uniformity of > using the same syntax for all flavors of method references outweighed the > small number of collisions like this one. > > On May 14, 2015, at 10:06 AM, Vitaly Davidovich wrote: > > That's an implementation detail not a fundamental issue right? > > sent from my phone > On May 14, 2015 10:04 AM, "Brian Goetz" wrote: > >> The static-instance asymmetry cancels that one out. If you have >> >> class Foo { >> void m(int x) >> static void m(Foo f, int x) >> } >> >> Then Foo::x could either be an unbound mref to the instance method or a >> static mref. Even with a perfect target type (Foo, int) -> void, compiler >> will still report ambiguity. >> >> On May 14, 2015, at 9:52 AM, Vitaly Davidovich wrote: >> >> > Ambiguous in isolation, but within context they're quite different: one >> > takes an arg and the other is void. >> > >> > sent from my phone >> > On May 14, 2015 9:25 AM, "Remi Forax" wrote: >> > >> >> >> >> >> >> On 05/14/2015 03:05 PM, Brian Goetz wrote: >> >> >> >>> Not only is there a problem with modCount, but also with >> >>>>> equals/hashCode/toString. You can?t define these Object methods in >> an >> >>>>> interface. >> >>>>> >> >>>> They could be defined as static methods to delegate to. From API >> >>>> consistency perspective, we have for example the following static >> methods >> >>>> on primitive wrapper classes: >> >>>> >> >>> Right. We considered this during Lambda, but by the time we got >> here, we >> >>> concluded that this was mostly trading one downside for another. It >> seemed >> >>> overwhelmingly likely that people would forget to override >> >>> equals/hashCode/toString in this case, and create collections that >> violated >> >>> the contract. >> >>> >> >>> >> >> The other problem is that it creates ambiguous method references, >> >> if you have a class or an interface like: >> >> class A { >> >> public static int hashCode(A a) { ... } >> >> } >> >> >> >> A::hashCode is ambiguous. >> >> >> >> cheers, >> >> R?mi >> >> >> >> >> >> > From daniel.smith at oracle.com Thu May 14 14:39:17 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 14 May 2015 08:39:17 -0600 Subject: AbstractList etc. functionality as interfaces with default methods? In-Reply-To: <5554A225.4070107@univ-mlv.fr> References: <9CD1255A-C501-41EC-B1B2-5ED9E8C403D7@oracle.com> <555486BE.50000@gmail.com> <318A358E-74FC-4523-BEB4-55EB0ADCC38E@oracle.com> <5554A225.4070107@univ-mlv.fr> Message-ID: > On May 14, 2015, at 7:24 AM, Remi Forax wrote: > > On 05/14/2015 03:05 PM, Brian Goetz wrote: >>>> Not only is there a problem with modCount, but also with equals/hashCode/toString. You can?t define these Object methods in an interface. >>> They could be defined as static methods to delegate to. From API consistency perspective, we have for example the following static methods on primitive wrapper classes: >> Right. We considered this during Lambda, but by the time we got here, we concluded that this was mostly trading one downside for another. It seemed overwhelmingly likely that people would forget to override equals/hashCode/toString in this case, and create collections that violated the contract. >> > > The other problem is that it creates ambiguous method references, > if you have a class or an interface like: > class A { > public static int hashCode(A a) { ... } > } > > A::hashCode is ambiguous. An easy solution to both of these problems is to use a different name. We discussed this as a workaround when designing the "no default 'hashCode' method" restriction. interface List { ... /** Returns the hash code for this list. The hash code of a list is defined as ... */ int hashCode(); /** Computes a hash code consistent with the specification of 'hashCode'. */ default int defaultHashCode() { ... } } (Details like whether it's static or instance, and what interface it lives in, are flexible.) ?Dan From huizhe.wang at oracle.com Thu May 14 16:21:49 2015 From: huizhe.wang at oracle.com (huizhe wang) Date: Thu, 14 May 2015 09:21:49 -0700 Subject: RFR: 8080344: Incorrect GPL header Message-ID: <5554CB9D.6000008@oracle.com> Hi, The license header in these files contain an incorrect YEAR format, e.g. "Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved." where the YEAR should have been "2013,". Please review: http://cr.openjdk.java.net/~joehw/jdk9/8080344/webrev/ Thanks, Joe From lance.andersen at oracle.com Thu May 14 16:24:23 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 14 May 2015 12:24:23 -0400 Subject: RFR: 8080344: Incorrect GPL header In-Reply-To: <5554CB9D.6000008@oracle.com> References: <5554CB9D.6000008@oracle.com> Message-ID: <4BB440C9-078E-4402-A5F8-5BBBF103E995@oracle.com> Looks fine Joe On May 14, 2015, at 12:21 PM, huizhe wang wrote: > Hi, > > The license header in these files contain an incorrect YEAR format, e.g. "Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved." where the YEAR should have been "2013,". > > Please review: > http://cr.openjdk.java.net/~joehw/jdk9/8080344/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 Thu May 14 16:31:53 2015 From: naoto.sato at oracle.com (Naoto Sato) Date: Thu, 14 May 2015 09:31:53 -0700 Subject: [9] RFR: 8080342: Incorrect GPL header causes RE script to miss swap to commercial header for licensee source bundle Message-ID: <5554CDF9.6060303@oracle.com> Hello, Another GPL header fix. Please review. http://cr.openjdk.java.net/~naoto/8080342/webrev.00/ Naoto From lance.andersen at oracle.com Thu May 14 16:32:38 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 14 May 2015 12:32:38 -0400 Subject: [9] RFR: 8080342: Incorrect GPL header causes RE script to miss swap to commercial header for licensee source bundle In-Reply-To: <5554CDF9.6060303@oracle.com> References: <5554CDF9.6060303@oracle.com> Message-ID: +1 On May 14, 2015, at 12:31 PM, Naoto Sato wrote: > Hello, > > Another GPL header fix. Please review. > > http://cr.openjdk.java.net/~naoto/8080342/webrev.00/ > > 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 huizhe.wang at oracle.com Thu May 14 16:34:54 2015 From: huizhe.wang at oracle.com (huizhe wang) Date: Thu, 14 May 2015 09:34:54 -0700 Subject: RFR: 8080344: Incorrect GPL header In-Reply-To: <4BB440C9-078E-4402-A5F8-5BBBF103E995@oracle.com> References: <5554CB9D.6000008@oracle.com> <4BB440C9-078E-4402-A5F8-5BBBF103E995@oracle.com> Message-ID: <5554CEAE.2000802@oracle.com> Thanks Lance! Joe On 5/14/2015 9:24 AM, Lance Andersen wrote: > Looks fine Joe > > > On May 14, 2015, at 12:21 PM, huizhe wang > wrote: > >> Hi, >> >> The license header in these files contain an incorrect YEAR format, >> e.g. "Copyright (c) 2013 Oracle and/or its affiliates. All rights >> reserved." where the YEAR should have been "2013,". >> >> Please review: >> http://cr.openjdk.java.net/~joehw/jdk9/8080344/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 dmitry.samersoff at oracle.com Thu May 14 17:41:53 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Thu, 14 May 2015 20:41:53 +0300 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <555453BA.2070205@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> Message-ID: <5554DE61.5010403@oracle.com> Peter, Could we just bail out on r == r.next? It gives us less accurate result, but I suspect that If we restart from head we need to flush all counters. As far I understand queue poller removes items one by one from a queue end so if we overtaken by queue poller we can safely assume that we are at the end of the queue. Is it correct? -Dmitry On 2015-05-14 10:50, Peter Levart wrote: > Hi Derek, > > On 05/13/2015 10:34 PM, Derek White wrote: >> Hi Peter, >> >> I don't have smoking gun evidence that your change introduces a bug, >> but I have some concerns... > > I did have a concern too, ... > >> >> On 5/12/15 6:05 PM, Peter Levart wrote: >>> Hi Dmitry, >>> >>> You iterate the queue then, not the unfinalized list. That's more >>> logical. >>> >>> Holding the queue's lock may pause reference handler and finalizer >>> threads for the entire time of iteration. This can blow up the >>> application. Suppose one wants to diagnose the application because he >>> suspects that finalizer thread hardly keeps up with production of >>> finalizable instances. This can happen if the allocation rate of >>> finalizable objects is very high and/or finalize() methods are not >>> coded to be fast enough. Suppose the queue of Finalizer(s) builds up >>> gradually and is already holding several million objects. Now you >>> initiate the diagnostic command to print the queue. The iteration >>> over and grouping/counting of several millions of Finalizer(s) takes >>> some time. This blocks finalizer thread and reference handler thread. >>> But does not block the threads that allocate finalizable objects. By >>> the time the iteration is over, the JVM blows up and application >>> slows down to a halt doing GCs most of the time, getting OOMEs, etc... >>> >>> It is possible to iterate the elements of the queue for diagnostic >>> purposes without holding a lock. The modification required to do that >>> is the following (havent tested this, but I think it should work): >>> >>> >>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>> >> One issue to watch out for is the garbage collectors inspect the >> Reference.next field from C code directly (to distinguish active vs. >> pending, iterate over oops, etc.). You can search hotspot for >> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >> >> Your change makes "inactive" References superficially look like >> "enqueued" References. The GC code is rather subtle and I haven't yet >> seen a case where it would get confused by this change, but there >> could easily be something like that lurking in the GC code. > > ...but then I thought that GC can in no way treat a Reference > differently whether it is still enqueued in a ReferenceQueue or already > dequeued (inactive) - responsibility is already on the Java side. > Currently the definition of Reference.next is this: > > /* When active: NULL > * pending: this > * Enqueued: next reference in queue (or this if last) > * Inactive: this > */ > @SuppressWarnings("rawtypes") > Reference next; > > We see that, unless GC inspects all ReferenceQueue instances and scans > their lists too, the state of a Reference that is enqueued as last in > list is indistinguishable from the state of inactive Reference. So I > deduced that this distinction (enqueued/inactive) can't be established > solely on the value of .next field ( == this or != this)... > > But I should inspect the GC code too to build a better understanding of > that part of the story... > > Anyway. It turns out that there is already enough state in Reference to > destinguish between it being enqueued as last in list and already > dequeued (inactive) - the additional state is Reference.queue that > transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in > ReferenceQueue.reallyPoll. We need to just make sure the two fields > (r.next and r.queue) are assigned and read in correct order. This can be > achieved either by making Reference.next a volatile field or by a couple > of explicit fences: > > > http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ > > The assignment of r.queue to ReferenceQueue.ENQUEUED already happens > before linking the reference into the queue's head in > ReferenceQueue.enqueue(): > > r.queue = ENQUEUED; > r.next = (head == null) ? r : head; > head = r; > > Both stores are volatile. > >> >>> I also suggest the addition to the ReferenceQueue to be contained >>> (package-private) and as generic as possible. That's why I suggest >>> forEach iteration method with no concrete logic. >>> >>> It would be possible to encapsulate the entire logic into a special >>> package-private class (say java.lang.ref.DiagnosticCommands) with >>> static method(s) (printFinalizationQueue)... You could just expose a >>> package-private forEach static method from Finalizer and code the >>> rest in DiagnosticCommands. >> That's good for encapsulation. But I'm concerned that if "forEach" got >> exposed beyond careful use in DiagnosticCommands, and the Referents >> were leaked back into the heap, then we could get unexpected object >> resurrection after finalization. This isn't a bug on it's own - any >> finalizer might resurrect its object if not careful, but ordinarily >> /only/ the finalizer could resurrect the object. This could invalidate >> application invariants? > > Well, it all stays in the confines of package-private API - internal to > JDK. Any future additional use should be reviewed carefully. Comments on > the forEach() method should warn about that. > >> >> I agree that using a lock over the ReferenceQueue iteration opens up >> /another/ case of diagnostics affecting application behavior. And >> there are pathological scenarios where this gets severe. This is >> unfortunate but not uncommon. There is enough complication here that >> you should be sure that the fix for diagnostics performance doesn't >> introduce subtle bugs to the system in general. A change in this area >> should get a thorough review from both the runtime and GC sides. > > Is the webrev.02 proposed above more acceptable in that respect? It does > not introduce any logical changes to existing code. > >> >> Better yet, the reference handling code in GC and runtime should >> probably be thrown out and re-written, but that's another issue :-) > > I may have some proposals in that direction. Stay tuned. > > Regards, Peter > >> >> - Derek >> >>> Regards, Peter >>> >>> >>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>> Everybody, >>>> >>>> Updated version: >>>> >>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>> >>>> Now it iterates over queue and output result sorted by number of instances. >>>> >>>> -Dmitry >>>> >>>> On 2015-05-07 00:51, Derek White wrote: >>>>> Hi Dmitry, Staffan, >>>>> >>>>> Lots of good comments here. >>>>> >>>>> On the topic of what list should be printed out, I think we should focus >>>>> on objects waiting to be finalized - e.g. the contents of the >>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>> could add a summerizeQueue(TreeMap) method, or a >>>>> general iterator and lambda. >>>>> >>>>> A histogram of objects with finalize methods might also be interesting, >>>>> but you can get most of the same information from a heap histogram >>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>> >>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>> that runs after GC that sorts found References objects that need >>>>> processing into their respective ReferenceQueues). But locking the >>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>> >>>>> The sorting suggestion is a nice touch. >>>>> >>>>> - Derek White, GC team >>>>> >>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>> Hi Dmitry, Staffan, >>>>>> >>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>> Dmitry, >>>>>>> >>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>> well considering the changes to Finalizer. >>>>>>> >>>>>>> I?m a little worried about the potentially very large String that is >>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>> That would allow for outputting one line at a time. The output would >>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>> running out of memory. >>>>>> If the output is just a histogram of # of instances per class name, >>>>>> then it should not be too large, as there are not many different >>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>> finalize() method in the whole jdk/src tree). >>>>>> >>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>> acceptable for diagnostic output to impact performance and/or >>>>>> interfere with synchronization? >>>>>> >>>>>> It might be possible to scan the list without holding a lock for >>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>> Finalizer.next pointer to point back to itself: >>>>>> >>>>>> private void remove() { >>>>>> synchronized (lock) { >>>>>> if (unfinalized == this) { >>>>>> if (this.next != null) { >>>>>> unfinalized = this.next; >>>>>> } else { >>>>>> unfinalized = this.prev; >>>>>> } >>>>>> } >>>>>> if (this.next != null) { >>>>>> this.next.prev = this.prev; >>>>>> } >>>>>> if (this.prev != null) { >>>>>> this.prev.next = this.next; >>>>>> } >>>>>> // this.next = this; must not be set so that we can >>>>>> traverse the list unsynchronized >>>>>> this.prev = this; /* Indicates that this has been >>>>>> finalized */ >>>>>> } >>>>>> } >>>>>> >>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>> pointer could be used instead: >>>>>> >>>>>> private boolean hasBeenFinalized() { >>>>>> return (prev == this); >>>>>> } >>>>>> >>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>> >>>>>> private void add() { >>>>>> synchronized (lock) { >>>>>> if (unfinalized != null) { >>>>>> this.next = unfinalized; >>>>>> unfinalized.prev = this; >>>>>> } >>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>> // instance fully initialized >>>>>> // (in particular the 'next' pointer) >>>>>> U.storeFence(); >>>>>> unfinalized = this; >>>>>> } >>>>>> } >>>>>> >>>>>> >>>>>> By doing these modifications, I think you can remove >>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>> >>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>> out? >>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>> instances pending processing by finalizer thread because their >>>>>> referents are eligible for finalization (they are not reachable any >>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>> instances for which their referents have not been finalized yet >>>>>> (including those that are still reachable and alive). The later serves >>>>>> two purposes: >>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>> - it is a source of unfinalized instances for >>>>>> running-finalizers-on-exit if requested by >>>>>> System.runFinalizersOnExit(true); >>>>>> >>>>>> So it really depends on what one would like to see. Showing the queue >>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>> list may be interesting if one wants to know how many live + >>>>>> finalization pending instances are there on the heap that override >>>>>> finalize() method. >>>>>> >>>>>> Regards, Peter >>>>>> >>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>> (see the old code again) would also make it easier to digest. >>>>>>> >>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>> permission() and limit access: >>>>>>> >>>>>>> static const JavaPermission permission() { >>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>> "monitor", NULL}; >>>>>>> return p; >>>>>>> } >>>>>>> >>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>> the finalizer queue? Hmm. >>>>>>> >>>>>>> Thanks, >>>>>>> /Staffan >>>>>>> >>>>>>> >>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>> wrote: >>>>>>>> >>>>>>>> Everyone, >>>>>>>> >>>>>>>> Please review the fix: >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>> >>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>> >>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>> with count >>>>>>>> >>>>>>>> -Dmitry >>>>>>>> >>>>>>>> -- >>>>>>>> Dmitry Samersoff >>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>> * I would love to change the world, but they won't give me the sources. >>> >> > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From peter.levart at gmail.com Thu May 14 20:11:27 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 14 May 2015 22:11:27 +0200 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5554DE61.5010403@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <5554DE61.5010403@oracle.com> Message-ID: <5555016F.2050802@gmail.com> Hi Dmitry, ReferenceQueue is not really a queue, but a LIFO stack. Scanner is walking the stack from top (the 'head') to bottom (the last element pointing to itself). When poller(s) overtake the scanner, it actually means that the top of the stack has been eaten under scanner's feet while trying to grab it. Restarting from 'head' actually means 'catching-up' wit poller(s) and trying to keep up with them. We don't get the 'eaten' elements, but might be lucky to get some more food until it's all eaten. Usually we will get all of the elements, since poller(s) must synchronize and do additional work, so they are slower and there's also enqueuer(s) that push elements on the top of the stack so poller(s) must eat those last pushed elements before they can continue chasing the scanner... When scanner is overtaken by poller, then there is a chance the scanner will get less elements than there were present in the stack if a snapshot was taken, so catching-up by restarting from 'head' tries to at least recover some of the rest of the elements of that snapshot before they are gone. Does this make more sense now? Regards, Peter On 05/14/2015 07:41 PM, Dmitry Samersoff wrote: > Peter, > > Could we just bail out on r == r.next? > > It gives us less accurate result, but I suspect that If we restart from > head we need to flush all counters. > > As far I understand queue poller removes items one by one from a queue > end so if we overtaken by queue poller we can safely assume that > we are at the end of the queue. > > Is it correct? > > -Dmitry > > On 2015-05-14 10:50, Peter Levart wrote: >> Hi Derek, >> >> On 05/13/2015 10:34 PM, Derek White wrote: >>> Hi Peter, >>> >>> I don't have smoking gun evidence that your change introduces a bug, >>> but I have some concerns... >> I did have a concern too, ... >> >>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>> Hi Dmitry, >>>> >>>> You iterate the queue then, not the unfinalized list. That's more >>>> logical. >>>> >>>> Holding the queue's lock may pause reference handler and finalizer >>>> threads for the entire time of iteration. This can blow up the >>>> application. Suppose one wants to diagnose the application because he >>>> suspects that finalizer thread hardly keeps up with production of >>>> finalizable instances. This can happen if the allocation rate of >>>> finalizable objects is very high and/or finalize() methods are not >>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds up >>>> gradually and is already holding several million objects. Now you >>>> initiate the diagnostic command to print the queue. The iteration >>>> over and grouping/counting of several millions of Finalizer(s) takes >>>> some time. This blocks finalizer thread and reference handler thread. >>>> But does not block the threads that allocate finalizable objects. By >>>> the time the iteration is over, the JVM blows up and application >>>> slows down to a halt doing GCs most of the time, getting OOMEs, etc... >>>> >>>> It is possible to iterate the elements of the queue for diagnostic >>>> purposes without holding a lock. The modification required to do that >>>> is the following (havent tested this, but I think it should work): >>>> >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>> >>> One issue to watch out for is the garbage collectors inspect the >>> Reference.next field from C code directly (to distinguish active vs. >>> pending, iterate over oops, etc.). You can search hotspot for >>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>> >>> Your change makes "inactive" References superficially look like >>> "enqueued" References. The GC code is rather subtle and I haven't yet >>> seen a case where it would get confused by this change, but there >>> could easily be something like that lurking in the GC code. >> ...but then I thought that GC can in no way treat a Reference >> differently whether it is still enqueued in a ReferenceQueue or already >> dequeued (inactive) - responsibility is already on the Java side. >> Currently the definition of Reference.next is this: >> >> /* When active: NULL >> * pending: this >> * Enqueued: next reference in queue (or this if last) >> * Inactive: this >> */ >> @SuppressWarnings("rawtypes") >> Reference next; >> >> We see that, unless GC inspects all ReferenceQueue instances and scans >> their lists too, the state of a Reference that is enqueued as last in >> list is indistinguishable from the state of inactive Reference. So I >> deduced that this distinction (enqueued/inactive) can't be established >> solely on the value of .next field ( == this or != this)... >> >> But I should inspect the GC code too to build a better understanding of >> that part of the story... >> >> Anyway. It turns out that there is already enough state in Reference to >> destinguish between it being enqueued as last in list and already >> dequeued (inactive) - the additional state is Reference.queue that >> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >> ReferenceQueue.reallyPoll. We need to just make sure the two fields >> (r.next and r.queue) are assigned and read in correct order. This can be >> achieved either by making Reference.next a volatile field or by a couple >> of explicit fences: >> >> >> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >> >> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >> before linking the reference into the queue's head in >> ReferenceQueue.enqueue(): >> >> r.queue = ENQUEUED; >> r.next = (head == null) ? r : head; >> head = r; >> >> Both stores are volatile. >> >>>> I also suggest the addition to the ReferenceQueue to be contained >>>> (package-private) and as generic as possible. That's why I suggest >>>> forEach iteration method with no concrete logic. >>>> >>>> It would be possible to encapsulate the entire logic into a special >>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>> static method(s) (printFinalizationQueue)... You could just expose a >>>> package-private forEach static method from Finalizer and code the >>>> rest in DiagnosticCommands. >>> That's good for encapsulation. But I'm concerned that if "forEach" got >>> exposed beyond careful use in DiagnosticCommands, and the Referents >>> were leaked back into the heap, then we could get unexpected object >>> resurrection after finalization. This isn't a bug on it's own - any >>> finalizer might resurrect its object if not careful, but ordinarily >>> /only/ the finalizer could resurrect the object. This could invalidate >>> application invariants? >> Well, it all stays in the confines of package-private API - internal to >> JDK. Any future additional use should be reviewed carefully. Comments on >> the forEach() method should warn about that. >> >>> I agree that using a lock over the ReferenceQueue iteration opens up >>> /another/ case of diagnostics affecting application behavior. And >>> there are pathological scenarios where this gets severe. This is >>> unfortunate but not uncommon. There is enough complication here that >>> you should be sure that the fix for diagnostics performance doesn't >>> introduce subtle bugs to the system in general. A change in this area >>> should get a thorough review from both the runtime and GC sides. >> Is the webrev.02 proposed above more acceptable in that respect? It does >> not introduce any logical changes to existing code. >> >>> Better yet, the reference handling code in GC and runtime should >>> probably be thrown out and re-written, but that's another issue :-) >> I may have some proposals in that direction. Stay tuned. >> >> Regards, Peter >> >>> - Derek >>> >>>> Regards, Peter >>>> >>>> >>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>> Everybody, >>>>> >>>>> Updated version: >>>>> >>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>> >>>>> Now it iterates over queue and output result sorted by number of instances. >>>>> >>>>> -Dmitry >>>>> >>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>> Hi Dmitry, Staffan, >>>>>> >>>>>> Lots of good comments here. >>>>>> >>>>>> On the topic of what list should be printed out, I think we should focus >>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>> general iterator and lambda. >>>>>> >>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>> but you can get most of the same information from a heap histogram >>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>> >>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>> that runs after GC that sorts found References objects that need >>>>>> processing into their respective ReferenceQueues). But locking the >>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>> >>>>>> The sorting suggestion is a nice touch. >>>>>> >>>>>> - Derek White, GC team >>>>>> >>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>> Hi Dmitry, Staffan, >>>>>>> >>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>> Dmitry, >>>>>>>> >>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>> well considering the changes to Finalizer. >>>>>>>> >>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>> running out of memory. >>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>> then it should not be too large, as there are not many different >>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>> finalize() method in the whole jdk/src tree). >>>>>>> >>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>> interfere with synchronization? >>>>>>> >>>>>>> It might be possible to scan the list without holding a lock for >>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>> Finalizer.next pointer to point back to itself: >>>>>>> >>>>>>> private void remove() { >>>>>>> synchronized (lock) { >>>>>>> if (unfinalized == this) { >>>>>>> if (this.next != null) { >>>>>>> unfinalized = this.next; >>>>>>> } else { >>>>>>> unfinalized = this.prev; >>>>>>> } >>>>>>> } >>>>>>> if (this.next != null) { >>>>>>> this.next.prev = this.prev; >>>>>>> } >>>>>>> if (this.prev != null) { >>>>>>> this.prev.next = this.next; >>>>>>> } >>>>>>> // this.next = this; must not be set so that we can >>>>>>> traverse the list unsynchronized >>>>>>> this.prev = this; /* Indicates that this has been >>>>>>> finalized */ >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>> pointer could be used instead: >>>>>>> >>>>>>> private boolean hasBeenFinalized() { >>>>>>> return (prev == this); >>>>>>> } >>>>>>> >>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>> >>>>>>> private void add() { >>>>>>> synchronized (lock) { >>>>>>> if (unfinalized != null) { >>>>>>> this.next = unfinalized; >>>>>>> unfinalized.prev = this; >>>>>>> } >>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>> // instance fully initialized >>>>>>> // (in particular the 'next' pointer) >>>>>>> U.storeFence(); >>>>>>> unfinalized = this; >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> >>>>>>> By doing these modifications, I think you can remove >>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>> >>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>> out? >>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>> instances pending processing by finalizer thread because their >>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>> instances for which their referents have not been finalized yet >>>>>>> (including those that are still reachable and alive). The later serves >>>>>>> two purposes: >>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>> - it is a source of unfinalized instances for >>>>>>> running-finalizers-on-exit if requested by >>>>>>> System.runFinalizersOnExit(true); >>>>>>> >>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>> list may be interesting if one wants to know how many live + >>>>>>> finalization pending instances are there on the heap that override >>>>>>> finalize() method. >>>>>>> >>>>>>> Regards, Peter >>>>>>> >>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>> >>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>> permission() and limit access: >>>>>>>> >>>>>>>> static const JavaPermission permission() { >>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>> "monitor", NULL}; >>>>>>>> return p; >>>>>>>> } >>>>>>>> >>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>> the finalizer queue? Hmm. >>>>>>>> >>>>>>>> Thanks, >>>>>>>> /Staffan >>>>>>>> >>>>>>>> >>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>> Everyone, >>>>>>>>> >>>>>>>>> Please review the fix: >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>> >>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>> >>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>> with count >>>>>>>>> >>>>>>>>> -Dmitry >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dmitry Samersoff >>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>> * I would love to change the world, but they won't give me the sources. From stuart.marks at oracle.com Thu May 14 20:25:18 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 14 May 2015 13:25:18 -0700 Subject: RFR(s): 8078463: optimize java/util/Map/Collisions.java In-Reply-To: References: <5553FE06.40006@oracle.com> Message-ID: <555504AE.7080700@oracle.com> Hi Martin, thanks for taking a look. It probably would be a good idea to convert this test (and a whole bunch of others) to Test-NG. However, that's more change than I want to bite off at this point, so I'd prefer to stick with my change as it stands right now. s'marks On 5/13/15 7:24 PM, Martin Buchholz wrote: > Your changes look good, but: > 204 check(map.size() == i, "insertion: map expected size m%d != i%d", map.size(), i); > many of those detail messages look like leftovers from a long debugging > session. Here I would consider converting to a testng test (I ended up doing > this a few times myself) and writing very simply, standardly, efficiently and > readably > > assertEquals(map.size(), i); > > only adding more breadcrumbs if it's non-obvious, which is generally not the > case in this test. > > testMap already prints out keys_desc, so the test output is unambiguous. > > On Wed, May 13, 2015 at 6:44 PM, Stuart Marks > wrote: > > Hi all, > > Please review this change to optimize a test. Basically the test did > string formatting for every assertion, but the string was thrown away if > the assertion passed -- the most common case. The change is to do the > string formatting only when an assertion fails and information needs to be > printed out. > > Thanks to Andrey Zakharov for discovering and investigating this. > > Bug report: > > https://bugs.openjdk.java.net/browse/JDK-8078463 > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8078463/webrev.0/ > > > On my (new, fast) laptop, with JVM options -Xcomp -XX:+DeoptimizeALot > -client, the unmodified test takes about 21.4 seconds to run. The modified > test takes only 12.3 seconds. > > Note that I have added several overloads of check() with different > arguments. I tried an alternative, which is a varargs version of check(): > > static void check(boolean cond, String fmt, Object... args) { > if (cond) { > pass(); > } else { > fail(String.format(fmt, args)); > } > } > > This of course is much simpler code, but it took 14.2 seconds, about 15% > slower than the proposed version. Is the simpler code worth the slowdown? > I could go either way. > > Thanks. > > s'marks > > > From stuart.marks at oracle.com Thu May 14 20:30:22 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 14 May 2015 13:30:22 -0700 Subject: RFR(s): 8078463: optimize java/util/Map/Collisions.java In-Reply-To: References: <5553FE06.40006@oracle.com> Message-ID: <555505DE.6090706@oracle.com> On 5/14/15 12:58 AM, Chris Hegarty wrote: > Or could use jdk.testlibrary.Asserts.assertEquals, if you want to avoid spinning up the testng machinery, and generating yet another xml test report. If you are only interested in assertEquals. Unfortunately there are several assertions that aren't simple equality assertions, so something else would have to be done for those. >>> This of course is much simpler code, but it took 14.2 seconds, about 15% >>> slower than the proposed version. Is the simpler code worth the slowdown? I >>> could go either way. > > I?ve used the varargs version a number of times in my own tests. It is simple and easy to read. But if this 15% is important, then it could be worth the extra overloads. Either way I?m happy to this this change going in. OK, thanks. I think I'll keep the multiple overloads. The reason this came up in the first place was that the test timed out because it ran too long. Now arguably (and I have argued) that this is a test environment problem. Since this is a quick and easy speedup, though, we might as well do it. And as long as we're speeding things up, we might as well speed them up as much as is (reasonably) possible. s'marks From mandy.chung at oracle.com Thu May 14 20:30:51 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Thu, 14 May 2015 13:30:51 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <1290B915-DA74-4D41-96D9-5E1E7DB3428D@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> <1290B915-DA74-4D41-96D9-5E1E7DB3428D@oracle.com> Message-ID: <555505FB.8050700@oracle.com> On 05/13/2015 01:45 AM, Paul Sandoz wrote: > On May 12, 2015, at 10:49 PM, Mandy Chung wrote: >> How likely does existing code do this? A proper way is to call System.setProperty. One pattern I found on System.setProperties is like this to add a system property of key/value pair: >> >> Properties props = System.getProperties(); >> props.put(key, value); >> System.setProperties(props); >> >> More investigation needs to be done (e.g. look at System.setProperties and other system property related APIs and any spec change is needed to be made and the compatibility implication) if we agree that it worths keeping this change local to system properties. >> > FWIW you can see some usages here: > > http://grepcode.com/search/usages?type=method&id=repository.grepcode.com%24java%24root at jdk%24openjdk at 7u40-b43@java%24lang at System@setProperties%28java.util.Properties%29&k=u Thanks. I skimmed on several safe usages before I suggested to consider doing something for system properties but the first one on the above link and there s another one WriteOnceProperties depending on System.setProperties to replace the system Properties object with the argument directly. Definitely if we want to change any behavior, careful evaluation on the compatibility is required (maybe we can't change it and this is something for the future). Mandy From peter.levart at gmail.com Thu May 14 20:35:36 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 14 May 2015 22:35:36 +0200 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5555016F.2050802@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <5554DE61.5010403@oracle.com> <5555016F.2050802@gmail.com> Message-ID: <55550718.1000507@gmail.com> On 05/14/2015 10:11 PM, Peter Levart wrote: > Hi Dmitry, > > ReferenceQueue is not really a queue, but a LIFO stack. Scanner is > walking the stack from top (the 'head') to bottom (the last element > pointing to itself). When poller(s) overtake the scanner, it actually > means that the top of the stack has been eaten under scanner's feet > while trying to grab it. Restarting from 'head' actually means > 'catching-up' wit poller(s) and trying to keep up with them. We don't > get the 'eaten' elements, but might be lucky to get some more food > until it's all eaten. Usually we will get all of the elements, since > poller(s) must synchronize and do additional work, so they are slower > and there's also enqueuer(s) that push elements on the top of the > stack so poller(s) must eat those last pushed elements before they can > continue chasing the scanner... > > When scanner is overtaken by poller, then there is a chance the > scanner will get less elements than there were present in the stack if > a snapshot was taken, so catching-up by restarting from 'head' tries > to at least recover some of the rest of the elements of that snapshot > before they are gone. Also, the chance that the scanner is overtaken by poller is greater at the start of race. The scanner and poller start from the same spot and as we know threads are "jumpy" so it will happen quite frequently that a poller jumps before scanner. So just giving-up when overtaken might return 0 or just a few elements when there are millions there in the queue. When scanner finally gets a head start, it will usually lead the race to the end. Peter > > Does this make more sense now? > > Regards, Peter > > On 05/14/2015 07:41 PM, Dmitry Samersoff wrote: >> Peter, >> >> Could we just bail out on r == r.next? >> >> It gives us less accurate result, but I suspect that If we restart from >> head we need to flush all counters. >> >> As far I understand queue poller removes items one by one from a queue >> end so if we overtaken by queue poller we can safely assume that >> we are at the end of the queue. >> >> Is it correct? >> >> -Dmitry >> >> On 2015-05-14 10:50, Peter Levart wrote: >>> Hi Derek, >>> >>> On 05/13/2015 10:34 PM, Derek White wrote: >>>> Hi Peter, >>>> >>>> I don't have smoking gun evidence that your change introduces a bug, >>>> but I have some concerns... >>> I did have a concern too, ... >>> >>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>> Hi Dmitry, >>>>> >>>>> You iterate the queue then, not the unfinalized list. That's more >>>>> logical. >>>>> >>>>> Holding the queue's lock may pause reference handler and finalizer >>>>> threads for the entire time of iteration. This can blow up the >>>>> application. Suppose one wants to diagnose the application because he >>>>> suspects that finalizer thread hardly keeps up with production of >>>>> finalizable instances. This can happen if the allocation rate of >>>>> finalizable objects is very high and/or finalize() methods are not >>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds up >>>>> gradually and is already holding several million objects. Now you >>>>> initiate the diagnostic command to print the queue. The iteration >>>>> over and grouping/counting of several millions of Finalizer(s) takes >>>>> some time. This blocks finalizer thread and reference handler thread. >>>>> But does not block the threads that allocate finalizable objects. By >>>>> the time the iteration is over, the JVM blows up and application >>>>> slows down to a halt doing GCs most of the time, getting OOMEs, etc... >>>>> >>>>> It is possible to iterate the elements of the queue for diagnostic >>>>> purposes without holding a lock. The modification required to do that >>>>> is the following (havent tested this, but I think it should work): >>>>> >>>>> >>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>> >>>> One issue to watch out for is the garbage collectors inspect the >>>> Reference.next field from C code directly (to distinguish active vs. >>>> pending, iterate over oops, etc.). You can search hotspot for >>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>> >>>> Your change makes "inactive" References superficially look like >>>> "enqueued" References. The GC code is rather subtle and I haven't yet >>>> seen a case where it would get confused by this change, but there >>>> could easily be something like that lurking in the GC code. >>> ...but then I thought that GC can in no way treat a Reference >>> differently whether it is still enqueued in a ReferenceQueue or already >>> dequeued (inactive) - responsibility is already on the Java side. >>> Currently the definition of Reference.next is this: >>> >>> /* When active: NULL >>> * pending: this >>> * Enqueued: next reference in queue (or this if last) >>> * Inactive: this >>> */ >>> @SuppressWarnings("rawtypes") >>> Reference next; >>> >>> We see that, unless GC inspects all ReferenceQueue instances and scans >>> their lists too, the state of a Reference that is enqueued as last in >>> list is indistinguishable from the state of inactive Reference. So I >>> deduced that this distinction (enqueued/inactive) can't be established >>> solely on the value of .next field ( == this or != this)... >>> >>> But I should inspect the GC code too to build a better understanding of >>> that part of the story... >>> >>> Anyway. It turns out that there is already enough state in Reference to >>> destinguish between it being enqueued as last in list and already >>> dequeued (inactive) - the additional state is Reference.queue that >>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>> (r.next and r.queue) are assigned and read in correct order. This can be >>> achieved either by making Reference.next a volatile field or by a couple >>> of explicit fences: >>> >>> >>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>> >>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>> before linking the reference into the queue's head in >>> ReferenceQueue.enqueue(): >>> >>> r.queue = ENQUEUED; >>> r.next = (head == null) ? r : head; >>> head = r; >>> >>> Both stores are volatile. >>> >>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>> (package-private) and as generic as possible. That's why I suggest >>>>> forEach iteration method with no concrete logic. >>>>> >>>>> It would be possible to encapsulate the entire logic into a special >>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>> static method(s) (printFinalizationQueue)... You could just expose a >>>>> package-private forEach static method from Finalizer and code the >>>>> rest in DiagnosticCommands. >>>> That's good for encapsulation. But I'm concerned that if "forEach" got >>>> exposed beyond careful use in DiagnosticCommands, and the Referents >>>> were leaked back into the heap, then we could get unexpected object >>>> resurrection after finalization. This isn't a bug on it's own - any >>>> finalizer might resurrect its object if not careful, but ordinarily >>>> /only/ the finalizer could resurrect the object. This could invalidate >>>> application invariants? >>> Well, it all stays in the confines of package-private API - internal to >>> JDK. Any future additional use should be reviewed carefully. Comments on >>> the forEach() method should warn about that. >>> >>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>> /another/ case of diagnostics affecting application behavior. And >>>> there are pathological scenarios where this gets severe. This is >>>> unfortunate but not uncommon. There is enough complication here that >>>> you should be sure that the fix for diagnostics performance doesn't >>>> introduce subtle bugs to the system in general. A change in this area >>>> should get a thorough review from both the runtime and GC sides. >>> Is the webrev.02 proposed above more acceptable in that respect? It does >>> not introduce any logical changes to existing code. >>> >>>> Better yet, the reference handling code in GC and runtime should >>>> probably be thrown out and re-written, but that's another issue :-) >>> I may have some proposals in that direction. Stay tuned. >>> >>> Regards, Peter >>> >>>> - Derek >>>> >>>>> Regards, Peter >>>>> >>>>> >>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>> Everybody, >>>>>> >>>>>> Updated version: >>>>>> >>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>> >>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>> >>>>>> -Dmitry >>>>>> >>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>> Hi Dmitry, Staffan, >>>>>>> >>>>>>> Lots of good comments here. >>>>>>> >>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>> general iterator and lambda. >>>>>>> >>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>> but you can get most of the same information from a heap histogram >>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>> >>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>> that runs after GC that sorts found References objects that need >>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>> >>>>>>> The sorting suggestion is a nice touch. >>>>>>> >>>>>>> - Derek White, GC team >>>>>>> >>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>> Hi Dmitry, Staffan, >>>>>>>> >>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>> Dmitry, >>>>>>>>> >>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>> well considering the changes to Finalizer. >>>>>>>>> >>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>> running out of memory. >>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>> then it should not be too large, as there are not many different >>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>> >>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>> interfere with synchronization? >>>>>>>> >>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>> >>>>>>>> private void remove() { >>>>>>>> synchronized (lock) { >>>>>>>> if (unfinalized == this) { >>>>>>>> if (this.next != null) { >>>>>>>> unfinalized = this.next; >>>>>>>> } else { >>>>>>>> unfinalized = this.prev; >>>>>>>> } >>>>>>>> } >>>>>>>> if (this.next != null) { >>>>>>>> this.next.prev = this.prev; >>>>>>>> } >>>>>>>> if (this.prev != null) { >>>>>>>> this.prev.next = this.next; >>>>>>>> } >>>>>>>> // this.next = this; must not be set so that we can >>>>>>>> traverse the list unsynchronized >>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>> finalized */ >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>> pointer could be used instead: >>>>>>>> >>>>>>>> private boolean hasBeenFinalized() { >>>>>>>> return (prev == this); >>>>>>>> } >>>>>>>> >>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>> >>>>>>>> private void add() { >>>>>>>> synchronized (lock) { >>>>>>>> if (unfinalized != null) { >>>>>>>> this.next = unfinalized; >>>>>>>> unfinalized.prev = this; >>>>>>>> } >>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>> // instance fully initialized >>>>>>>> // (in particular the 'next' pointer) >>>>>>>> U.storeFence(); >>>>>>>> unfinalized = this; >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> By doing these modifications, I think you can remove >>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>> >>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>> out? >>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>> instances pending processing by finalizer thread because their >>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>> instances for which their referents have not been finalized yet >>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>> two purposes: >>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>> - it is a source of unfinalized instances for >>>>>>>> running-finalizers-on-exit if requested by >>>>>>>> System.runFinalizersOnExit(true); >>>>>>>> >>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>> finalization pending instances are there on the heap that override >>>>>>>> finalize() method. >>>>>>>> >>>>>>>> Regards, Peter >>>>>>>> >>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>> >>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>> permission() and limit access: >>>>>>>>> >>>>>>>>> static const JavaPermission permission() { >>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>> "monitor", NULL}; >>>>>>>>> return p; >>>>>>>>> } >>>>>>>>> >>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>> the finalizer queue? Hmm. >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> /Staffan >>>>>>>>> >>>>>>>>> >>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> Everyone, >>>>>>>>>> >>>>>>>>>> Please review the fix: >>>>>>>>>> >>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>> >>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>> >>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>> with count >>>>>>>>>> >>>>>>>>>> -Dmitry >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dmitry Samersoff >>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>> * I would love to change the world, but they won't give me the sources. > From stuart.marks at oracle.com Thu May 14 20:47:10 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 14 May 2015 13:47:10 -0700 Subject: RFR(s): 8078463: optimize java/util/Map/Collisions.java In-Reply-To: <55545B62.1050608@oracle.com> References: <5553FE06.40006@oracle.com> <55545B62.1050608@oracle.com> Message-ID: <555509CE.3000005@oracle.com> On 5/14/15 1:22 AM, Daniel Fuchs wrote: > I'm curious: have you tried with using a lambda instead? changing: > > 394 static void check(String desc, boolean cond) { > 395 if (cond) { > 396 pass(); > 397 } else { > 398 fail(desc); > 399 } > 400 } > > into > > static void check(Supplier descSupplier, boolean cond) { > if (cond) { > pass(); > } else { > fail(descSupplier.get()) > } > } > > I wonder how the performance would compare... I hadn't tried this, but I did out of curiosity. It's not very good. Here are the numbers: (current jdk9-dev, -Xcomp -XX:+DeoptimizeALot -client, 3GHz i7, MBP 13" 2014, elapsed time in seconds, averaged over five runs) 21.4 original 18.7 lambda 14.2 varargs 12.3 multiple overloads (proposed version) I'm not too surprised. The lambda calls will look something like this: check(() -> String.format("map expected size m%d != k%d", map.size(), keys.length), map.size() == keys.length); Although the string formatting itself isn't performed unless the assertion fails, this is pretty much the worst case scenario for lambda. Every lambda is a capturing lambda, so the metafactory has to create a new lambda instance every time. However, the lambda itself is never actually called. That adds a lot of overhead. In addition, there are several cases where the captured variables aren't effectively final, so I had to copy them into local variables and capture those instead. This was merely annoying, but it's a inconvenient and it adds a bit of clutter. Anyway, good idea, but lambda didn't really work for this. I'm going to push my original patch. s'marks From joe.darcy at oracle.com Thu May 14 23:03:35 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Thu, 14 May 2015 16:03:35 -0700 Subject: Updating existing JDK code to use InputStream.transferTo() (jdk) In-Reply-To: <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> References: <908E8B05-285B-46BB-94E4-F999E283936B@reini.net> <56F48D19-61F6-41FB-94AF-138C0F6C5B26@oracle.com> <6DECE5D9-4F1D-4E8A-8B91-F0BB846492B3@oracle.com> <6EA0F8BD-A285-4B80-8E5A-2B25B949498E@reini.net> Message-ID: <555529C7.2010705@oracle.com> Hello, Not providing a code review, but I wanted to state I think this is a very good sort of cleanup and worthwhile to get into the platform once the details have been worked through. Thanks, -Joe On 5/12/2015 3:10 PM, Patrick Reinhart wrote: > Hi Pavel, > > Is there anything I can do in the meantime? > > Unfortunately I do not have no account on cr.openjdk.java.net , so I need to paste the patch to the mailing list directly. > > Cheers Patrick > >> Am 10.05.2015 um 21:16 schrieb Chris Hegarty : >> >> I have not looked at the changes in detail yet, but I think it is going in the right direction. Just a few comments: >> From mark.reinhold at oracle.com Thu May 14 23:05:13 2015 From: mark.reinhold at oracle.com (mark.reinhold at oracle.com) Date: Thu, 14 May 2015 16:05:13 -0700 (PDT) Subject: JEP 254: Compact Strings Message-ID: <20150514230513.0363C62D05@eggemoggin.niobe.net> New JEP Candidate: http://openjdk.java.net/jeps/254 - Mark From dmitry.samersoff at oracle.com Fri May 15 05:09:14 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Fri, 15 May 2015 08:09:14 +0300 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55550718.1000507@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <5554DE61.5010403@oracle.com> <5555016F.2050802@gmail.com> <55550718.1000507@gmail.com> Message-ID: <55557F7A.4050508@oracle.com> Peter, Thank you for the explanation! -Dmitry On 2015-05-14 23:35, Peter Levart wrote: > > > On 05/14/2015 10:11 PM, Peter Levart wrote: >> Hi Dmitry, >> >> ReferenceQueue is not really a queue, but a LIFO stack. Scanner is >> walking the stack from top (the 'head') to bottom (the last element >> pointing to itself). When poller(s) overtake the scanner, it actually >> means that the top of the stack has been eaten under scanner's feet >> while trying to grab it. Restarting from 'head' actually means >> 'catching-up' wit poller(s) and trying to keep up with them. We don't >> get the 'eaten' elements, but might be lucky to get some more food >> until it's all eaten. Usually we will get all of the elements, since >> poller(s) must synchronize and do additional work, so they are slower >> and there's also enqueuer(s) that push elements on the top of the >> stack so poller(s) must eat those last pushed elements before they can >> continue chasing the scanner... >> >> When scanner is overtaken by poller, then there is a chance the >> scanner will get less elements than there were present in the stack if >> a snapshot was taken, so catching-up by restarting from 'head' tries >> to at least recover some of the rest of the elements of that snapshot >> before they are gone. > > Also, the chance that the scanner is overtaken by poller is greater at > the start of race. The scanner and poller start from the same spot and > as we know threads are "jumpy" so it will happen quite frequently that a > poller jumps before scanner. So just giving-up when overtaken might > return 0 or just a few elements when there are millions there in the > queue. When scanner finally gets a head start, it will usually lead the > race to the end. > > Peter > >> >> Does this make more sense now? >> >> Regards, Peter >> >> On 05/14/2015 07:41 PM, Dmitry Samersoff wrote: >>> Peter, >>> >>> Could we just bail out on r == r.next? >>> >>> It gives us less accurate result, but I suspect that If we restart from >>> head we need to flush all counters. >>> >>> As far I understand queue poller removes items one by one from a queue >>> end so if we overtaken by queue poller we can safely assume that >>> we are at the end of the queue. >>> >>> Is it correct? >>> >>> -Dmitry >>> >>> On 2015-05-14 10:50, Peter Levart wrote: >>>> Hi Derek, >>>> >>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>> Hi Peter, >>>>> >>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>> but I have some concerns... >>>> I did have a concern too, ... >>>> >>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>> Hi Dmitry, >>>>>> >>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>> logical. >>>>>> >>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>> threads for the entire time of iteration. This can blow up the >>>>>> application. Suppose one wants to diagnose the application because he >>>>>> suspects that finalizer thread hardly keeps up with production of >>>>>> finalizable instances. This can happen if the allocation rate of >>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds up >>>>>> gradually and is already holding several million objects. Now you >>>>>> initiate the diagnostic command to print the queue. The iteration >>>>>> over and grouping/counting of several millions of Finalizer(s) takes >>>>>> some time. This blocks finalizer thread and reference handler thread. >>>>>> But does not block the threads that allocate finalizable objects. By >>>>>> the time the iteration is over, the JVM blows up and application >>>>>> slows down to a halt doing GCs most of the time, getting OOMEs, etc... >>>>>> >>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>> purposes without holding a lock. The modification required to do that >>>>>> is the following (havent tested this, but I think it should work): >>>>>> >>>>>> >>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>> >>>>> One issue to watch out for is the garbage collectors inspect the >>>>> Reference.next field from C code directly (to distinguish active vs. >>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>> >>>>> Your change makes "inactive" References superficially look like >>>>> "enqueued" References. The GC code is rather subtle and I haven't yet >>>>> seen a case where it would get confused by this change, but there >>>>> could easily be something like that lurking in the GC code. >>>> ...but then I thought that GC can in no way treat a Reference >>>> differently whether it is still enqueued in a ReferenceQueue or already >>>> dequeued (inactive) - responsibility is already on the Java side. >>>> Currently the definition of Reference.next is this: >>>> >>>> /* When active: NULL >>>> * pending: this >>>> * Enqueued: next reference in queue (or this if last) >>>> * Inactive: this >>>> */ >>>> @SuppressWarnings("rawtypes") >>>> Reference next; >>>> >>>> We see that, unless GC inspects all ReferenceQueue instances and scans >>>> their lists too, the state of a Reference that is enqueued as last in >>>> list is indistinguishable from the state of inactive Reference. So I >>>> deduced that this distinction (enqueued/inactive) can't be established >>>> solely on the value of .next field ( == this or != this)... >>>> >>>> But I should inspect the GC code too to build a better understanding of >>>> that part of the story... >>>> >>>> Anyway. It turns out that there is already enough state in Reference to >>>> destinguish between it being enqueued as last in list and already >>>> dequeued (inactive) - the additional state is Reference.queue that >>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>> (r.next and r.queue) are assigned and read in correct order. This can be >>>> achieved either by making Reference.next a volatile field or by a couple >>>> of explicit fences: >>>> >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>> >>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>> before linking the reference into the queue's head in >>>> ReferenceQueue.enqueue(): >>>> >>>> r.queue = ENQUEUED; >>>> r.next = (head == null) ? r : head; >>>> head = r; >>>> >>>> Both stores are volatile. >>>> >>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>> forEach iteration method with no concrete logic. >>>>>> >>>>>> It would be possible to encapsulate the entire logic into a special >>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>> static method(s) (printFinalizationQueue)... You could just expose a >>>>>> package-private forEach static method from Finalizer and code the >>>>>> rest in DiagnosticCommands. >>>>> That's good for encapsulation. But I'm concerned that if "forEach" got >>>>> exposed beyond careful use in DiagnosticCommands, and the Referents >>>>> were leaked back into the heap, then we could get unexpected object >>>>> resurrection after finalization. This isn't a bug on it's own - any >>>>> finalizer might resurrect its object if not careful, but ordinarily >>>>> /only/ the finalizer could resurrect the object. This could invalidate >>>>> application invariants? >>>> Well, it all stays in the confines of package-private API - internal to >>>> JDK. Any future additional use should be reviewed carefully. Comments on >>>> the forEach() method should warn about that. >>>> >>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>> /another/ case of diagnostics affecting application behavior. And >>>>> there are pathological scenarios where this gets severe. This is >>>>> unfortunate but not uncommon. There is enough complication here that >>>>> you should be sure that the fix for diagnostics performance doesn't >>>>> introduce subtle bugs to the system in general. A change in this area >>>>> should get a thorough review from both the runtime and GC sides. >>>> Is the webrev.02 proposed above more acceptable in that respect? It does >>>> not introduce any logical changes to existing code. >>>> >>>>> Better yet, the reference handling code in GC and runtime should >>>>> probably be thrown out and re-written, but that's another issue :-) >>>> I may have some proposals in that direction. Stay tuned. >>>> >>>> Regards, Peter >>>> >>>>> - Derek >>>>> >>>>>> Regards, Peter >>>>>> >>>>>> >>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>> Everybody, >>>>>>> >>>>>>> Updated version: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>> >>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>> >>>>>>> -Dmitry >>>>>>> >>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>> Hi Dmitry, Staffan, >>>>>>>> >>>>>>>> Lots of good comments here. >>>>>>>> >>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>> general iterator and lambda. >>>>>>>> >>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>> >>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>> >>>>>>>> The sorting suggestion is a nice touch. >>>>>>>> >>>>>>>> - Derek White, GC team >>>>>>>> >>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>> >>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>> Dmitry, >>>>>>>>>> >>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>> >>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>> running out of memory. >>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>> >>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>> interfere with synchronization? >>>>>>>>> >>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>> >>>>>>>>> private void remove() { >>>>>>>>> synchronized (lock) { >>>>>>>>> if (unfinalized == this) { >>>>>>>>> if (this.next != null) { >>>>>>>>> unfinalized = this.next; >>>>>>>>> } else { >>>>>>>>> unfinalized = this.prev; >>>>>>>>> } >>>>>>>>> } >>>>>>>>> if (this.next != null) { >>>>>>>>> this.next.prev = this.prev; >>>>>>>>> } >>>>>>>>> if (this.prev != null) { >>>>>>>>> this.prev.next = this.next; >>>>>>>>> } >>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>> traverse the list unsynchronized >>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>> finalized */ >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>> pointer could be used instead: >>>>>>>>> >>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>> return (prev == this); >>>>>>>>> } >>>>>>>>> >>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>> >>>>>>>>> private void add() { >>>>>>>>> synchronized (lock) { >>>>>>>>> if (unfinalized != null) { >>>>>>>>> this.next = unfinalized; >>>>>>>>> unfinalized.prev = this; >>>>>>>>> } >>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>> // instance fully initialized >>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>> U.storeFence(); >>>>>>>>> unfinalized = this; >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> >>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>> >>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>> out? >>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>> two purposes: >>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>> >>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>> finalize() method. >>>>>>>>> >>>>>>>>> Regards, Peter >>>>>>>>> >>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>> >>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>> permission() and limit access: >>>>>>>>>> >>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>> "monitor", NULL}; >>>>>>>>>> return p; >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>> >>>>>>>>>> Thanks, >>>>>>>>>> /Staffan >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> Everyone, >>>>>>>>>>> >>>>>>>>>>> Please review the fix: >>>>>>>>>>> >>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>> >>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>> >>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>> with count >>>>>>>>>>> >>>>>>>>>>> -Dmitry >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>> * I would love to change the world, but they won't give me the sources. >> > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the source code. From Alan.Bateman at oracle.com Fri May 15 07:41:12 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 15 May 2015 08:41:12 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5554A5BD.2080602@redhat.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> <5553784A.4030607@redhat.com> <5553997A.7030401@oracle.com> <5554A5BD.2080602@redhat.com> Message-ID: <5555A318.3080504@oracle.com> On 14/05/2015 14:40, Andrew Haley wrote: > > > : > > Fix: > > http://cr.openjdk.java.net/~aph/8079459-3-jdk/ > > Testcase: > > http://cr.openjdk.java.net/~aph/8079459-3-hs/ > This looks good to me. We'll need to address the splitting of the tests between two repos at some point. -Alan. From aph at redhat.com Fri May 15 08:10:57 2015 From: aph at redhat.com (Andrew Haley) Date: Fri, 15 May 2015 09:10:57 +0100 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5555A318.3080504@oracle.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> <5553784A.4030607@redhat.com> <5553997A.7030401@oracle.com> <5554A5BD.2080602@redhat.com> <5555A318.3080504@oracle.com> Message-ID: <5555AA11.4070409@redhat.com> On 15/05/15 08:41, Alan Bateman wrote: > his looks good to me. We'll need to address the splitting of the tests > between two repos at some point. Well, we did discuss it at the time. It wasn't clear what was being tested, the VM or the class library, and in the end the answer was "both". In the end we just had to decide to put the test in one repository or the other. Andrew. From Sunny.Chan at gs.com Fri May 15 09:48:11 2015 From: Sunny.Chan at gs.com (Chan, Sunny) Date: Fri, 15 May 2015 17:48:11 +0800 Subject: Patch to improve primitives Array.sort() In-Reply-To: <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> Message-ID: <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> I have provided Paul with an updated patch: * The test has been updated using data provider and reduce as much repetition as possible. * The GS copyright notice from the main JDK patch. However we retain it on our test cases as we developed ourselves. In our previous contributions where we provided new tests we have put our copyright along with oracle copyright and it was accepted (see: http://hg.openjdk.java.net/jdk9/dev/jdk/file/ed94f3e7ba6b/test/java/lang/instrument/DaemonThread/TestDaemonThread.java) * Alan has commented that there were older benchmark but searching through the archive I can see it mention "BentleyBasher" I cannot find the actual code that Vladimir used (thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2009-September/002633.html). Is there anywhere I can get hold of it? Thanks. -----Original Message----- From: O'Leary, Kristen [Tech] Sent: 11 May 2015 23:33 To: 'Alan Bateman'; Paul Sandoz; Chan, Sunny [Tech] Cc: 'core-libs-dev at openjdk.java.net'; Rezaei, Mohammad A. [Tech] Subject: RE: Patch to improve primitives Array.sort() Hi Alan, For MAX_RUN_LENGTH, the constant was used to limit the size of a run when the numbers were equal. We treat equal numbers as part of the same run and do not require such a limitation. We have created a consolidated test based upon your feedback and Sunny will work on getting a new revision sent out. Thanks! Kristen -----Original Message----- From: Alan Bateman [mailto:Alan.Bateman at oracle.com] Sent: Friday, April 24, 2015 5:09 AM To: Paul Sandoz; Chan, Sunny [Tech] Cc: 'core-libs-dev at openjdk.java.net'; O'Leary, Kristen [Tech] Subject: Re: Patch to improve primitives Array.sort() On 24/04/2015 09:57, Paul Sandoz wrote: > See here: > > http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev/ > > Some very quick comments as i have not yet had time to review more closely: > > - IANAL so i dunno about the GS copyright in the files. > > - The constant MAX_RUN_LENGTH is no longer used so could be removed. But i would like to understand why it's no longer required. > > - There is quite a bit of duplication in the tests. AFAICT data sources are all derived from ints that are then converted. The sources could be data providers, so only one test method per data type is required, each data can come with a descriptive string so it shows up in the test reports. The goal here being if another source of data is added (which is derivable) it could be added just once. > Also overall with the existing Sorting test should be examined as it tests a lot of cases with varying data sizes (and consequentially runs for a long time). We should also go back through the archives for all the other benchmarks that were created in the move to the dual pivot implementation. -Alan From frank.yuan at oracle.com Fri May 15 09:48:19 2015 From: frank.yuan at oracle.com (Frank Yuan) Date: Fri, 15 May 2015 17:48:19 +0800 Subject: Review request for JDK-8078596: jaxp tests failed in modular jdk due to internal class access Message-ID: <020101d08ef4$48504950$d8f0dbf0$@oracle.com> Hi, Joe and All This is a test bug on 9-repo-jigsaw, jaxp tests failed due to internal class access. To fix this bug, I made the following changes: 1. moved the tests which test internal APIs to separate directory and added @modules for them 2. for other tests which don't intend to test internal APIs but have some internal API dependencies: 2.1. replaced internal APIs usage with public APIs 2.2. replaced the constants defined in internal classes with local constants As Alan's suggestion, I would push the changes to jdk9/dev and ask an open review. Would you like to take a look? Any comment will be appreciated. bug: https://bugs.openjdk.java.net/browse/JDK-8078596 webrev: http://cr.openjdk.java.net/~fyuan/8078596/webrev.00/ Thanks, Frank From peter.levart at gmail.com Fri May 15 10:35:50 2015 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 15 May 2015 12:35:50 +0200 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <5554A6D4.6060902@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> Message-ID: <5555CC06.4020507@gmail.com> Hi Roger, On 05/14/2015 03:44 PM, Roger Riggs wrote: > Hi Peter, > > On 5/14/15 8:19 AM, Peter Levart wrote: >> Hi Roger, >> >> The new API using Optional(s) looks fine. In particular for the >> ProcessHandle returning methods. They now either return >> Stream or Optional. >> >> At some point in the development of this API, the implementation >> introduced the AsyncExecutor to execute synchronous continuations of >> the onExit() returned CompletableFuture(s). What was the main >> motivation for this given that: >> - previously, ForkJoinPoll.commonPool() was used instead that by >> default possesses some similar characteristics (Innocuous threads >> when SecurityManager is active) > The AsyncExecutor also uses InnocuousThreads. So that's not what is lost or gained by AsyncExecutor when comparing it with commonPool(). > >> - this AsyncExecutor is only effective for 1st "wave" of synchronous >> continuations. Asynchronous continuations and synchronous >> continuations following them will still use ForkJoinPoll.commonPool() > Unfortunately, the common ForkJoinPool assumes that tasks queued to it > complete relatively > quickly and free the thread. It does not grow the number of threads > and is not appropriate > for tasks that block for indefinite periods as might be need to wait > for a Process to exit. Ok, AsyncExecutor might be required for default implementation of Process.onExit(). But waiting on process exit in ProcessImpl and ProcessHandle is performed by internal 32K stack-sized reaper threads and what we did in ProcessImpl.onExit() was this (before the AsyncExecutor): @Override public CompletableFuture onExit() { return ProcessHandleImpl.completion(pid, false) .handleAsync((exitStatus, unusedThrowable) -> this); } Which means that FJP.commonPool() thread is employed after ProcessHandleImpl.completion() is completed. Meaning that just user code is run by commonPool() and that code does not wait for process to exit because it already did exit. User code might run for extended period of time, but any use of CompletableFuture is susceptible to that abuse. Are you afraid that users of Process API are not common CompletableFuture users and are not aware of commonPool() constraints? >> >> Would an alternative be to define two overloaded onExit() methods in >> the style of CompletableFuture itself? >> >> CompletableFuture onExit(); >> CompletableFuture onExit(Executor executor); >> >> ...and give the user a chance to supply it's own Executor if the >> default ForkJoinPoll.commonPool() does not fit? > It is only one more method in PH and Process but that function is > available from CompletableFuture > though perhaps not as conveniently. > The onExit method returns a CompletableFuture that has the entire > complement of > synchronous and async methods available to it. The application can > control > where subsequent computations are performed. That's true for xxxxAsync methods. Synchronous continuations are executed by whichever thread executed the previous stage. We insert an asynchronous stage to shield the internal 32K threads from user code. What we do by executing that stage in AsyncExecutor might be desirable when the user attaches a synchronous continuation. But when he attaches an asynchronous one, the thread from AsyncExecutor is used just for mapping the result into Process instance and triggering the execution of next stage. Can we eliminate this unnecessary asynchronous stage? What would be if we stoped pretending that user can execute a synchronous onExit() continuation when in fact that continuation is always attached to an asynchronous stage so it is actually asynchronous? What if CompletableFuture had a public superclass called AsyncCompletableFuture that only exposed .xxxxAsync() continuation methods which returned normal CompletableFuture(s)? Such class would by definition shield the thread that completes an AsyncCompletableFuture from user code that attaches continuations. And user code would have exclusive control on what type of thread executes it. Isn't this a desirable property that jsr166 could provide? It could be useful in other scenarios too. The only problem with that approach is that we need a mapping stage that "attaches" the Proses[Handle] instance to AsyncCompletableFuture (which is generic and returns an exit status) to get AsyncCompletableFuture. Such operation could be provided by AsyncCompletableFuture as an "immediate" operation - not taking any lambda function which needs a thread to be executed, but a replacement object instead: public class AsyncCompletableFuture ... { /** * Returns a new CompletionStage that, when this stage completes * normally, completes with the given replacementResult. * * @param replacementResult the successful completion value of the returned * CompletionStage * @param the value's type * @return the new CompletionStage */ public AsyncCompletableFuture thenReplace(U replacementResult) { ... I can ask on the concurrency-interest list about the feasibility of such [Async]CompletableFuture split. Would you be interested in using AsyncCompletableFuture if it was available? > > That convenience method could be added later when the use case and > frequency is clearer. I saw it only as a workaround for needing AsyncExecutor. I don't like it either. Regards, Peter >> >> Is there expectation that ForkJoinPoll.commonPool() will not fit in >> the common case? > I don't have a sense of how onExit would be used or how often it would > be used. > The common FJP seems like a good start for computations to be performed > after the Process has exited. I'd wait and see what needs can be > articulated., > hopefully within the JDK 9 timeframe. > > Thanks, Roger > >> >> Regards, Peter >> >> On 05/13/2015 04:16 PM, Roger Riggs wrote: >>> Hi, >>> >>> Are there any comments about the use of java.util.Optional in the >>> ProcessHandle API? >>> Or a review of the changes? >>> >>> Thanks, Roger >>> >>> >>> On 5/11/2015 11:49 AM, Roger Riggs wrote: >>>> Please review clarifications and updates to the proposed Precess API. >>>> >>>> A few loose ends in the ProcessHandle API were identified. >>>> >>>> 1) The ProcessHandle.parent() method currently returns null if the >>>> parent cannot >>>> be determined and the ProcessHandle.of(PID) method returns null if >>>> the PID does not exist. >>>> It has been suggested to return an Optional to make >>>> these methods more flexible and allow a fluent style and work >>>> better with streams. >>>> >>>> 2) The behavior of Processhandle.destroy and destroyForcibly are >>>> different >>>> than Process.destroy and destroyForcibly. Those functions always >>>> succeed because >>>> they are children of the spawning process. >>>> >>>> In contrast, ProcessHandle.destroy and destroyForcible are requests to >>>> destroy the process and may not succeed due to operating system >>>> restrictions such >>>> as the process not being a child or not having enough privilege. >>>> The description of the methods needs to be clarified that it is a >>>> request to destroy >>>> and it may not succeed, In that case the destroy and >>>> destroyForcibly methods >>>> should indicate that the request was not successful. In >>>> particular, the caller >>>> may not want to wait for the process to terminate (its not going to). >>>> >>>> The proposed update is to return an Optional . >>>> It can be streamed and can take advantage of the conditional >>>> operations on the Optional. >>>> >>>> 3) Using Optional is also attractive for the return values of the >>>> information >>>> about a ProcessHandles, since not all values are available from >>>> every OS. >>>> The returns values of Info.command, arguments, startInstant, >>>> totalDuration, and user >>>> are proposed to be updated to return Optional. >>>> It allows for more compact code and fewer explicit checks for null. >>>> >>>> Please review and comment: >>>> >>>> Webrev: >>>> http://cr.openjdk.java.net/~rriggs/webrev-ph/ >>>> >>>> javadoc: >>>> http://cr.openjdk.java.net/~rriggs/ph-apidraft/ >>>> >>>> Diffs of the spec/javadoc from previous draft: >>>> http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-11/overview-summary.html >>>> >>>> >>>> Thanks, Roger >>>> >>>> >>>> >>> >> > From vladimir.x.ivanov at oracle.com Fri May 15 12:14:59 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 15 May 2015 15:14:59 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <55549297.5020002@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> <55533CAE.3050201@oracle.com> <55549297.5020002@oracle.com> Message-ID: <5555E343.5050600@oracle.com> After private discussion with Paul, here's an update: http://cr.openjdk.java.net/~vlivanov/8079205/webrev.03 Renamed CallSite$Context to MethodHandleNatives$Context. Best regards, Vladimir Ivanov On 5/14/15 3:18 PM, Vladimir Ivanov wrote: > Small update in JDK code (webrev updated in place): > http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 > > Changes: > - hid Context.dependencies field from Reflection > - new test case: CallSiteDepContextTest.testHiddenDepField() > > Best regards, > Vladimir Ivanov > > On 5/13/15 5:56 PM, Paul Sandoz wrote: >> >> On May 13, 2015, at 1:59 PM, Vladimir Ivanov >> wrote: >> >>> Peter, Paul, thanks for the feedback! >>> >>> Updated the webrev in place: >>> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 >>> >> >> +1 >> >> >>>> I am not an export in the HS area but the code mostly made sense to >>>> me. I also like Peter's suggestion of Context implementing Runnable. >>> I agree. Integrated. >>> >>>> Some minor comments. >>>> >>>> CallSite.java: >>>> >>>> 145 private final long dependencies = 0; // Used by JVM to >>>> store JVM_nmethodBucket* >>>> >>>> It's a little odd to see this field be final, but i think i >>>> understand the motivation as it's essentially acting as a memory >>>> address pointing to the head of the nbucket list, so in Java code >>>> you don't want to assign it to anything other than 0. >>> Yes, my motivation was to forbid reads & writes of the field from >>> Java code. I was experimenting with injecting the field by VM, but >>> it's less attractive. >>> >> >> I was wondering if that were possible. >> >> >>>> Is VM access, via java_lang_invoke_CallSite_Context, affected by >>>> treating final fields as really final in the j.l.i package? >>> No, field modifiers aren't respected. oopDesc::*_field_[get|put] does >>> a raw read/write using field offset. >>> >> >> Ok. >> >> Paul. >> From peter.levart at gmail.com Fri May 15 12:31:20 2015 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 15 May 2015 14:31:20 +0200 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <5555CC06.4020507@gmail.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> <5555CC06.4020507@gmail.com> Message-ID: <5555E718.8090000@gmail.com> Hi Roger, On 05/15/2015 12:35 PM, Peter Levart wrote: > public class AsyncCompletableFuture ... { > > /** > * Returns a new CompletionStage that, when this stage completes > * normally, completes with the given replacementResult. > * > * @param replacementResult the successful completion value of the > returned > * CompletionStage > * @param the value's type > * @return the new CompletionStage > */ > public AsyncCompletableFuture thenReplace(U > replacementResult) { ... > > I can ask on the concurrency-interest list about the feasibility of > such [Async]CompletableFuture split. Would you be interested in using > AsyncCompletableFuture if it was available? ...on a second thought, .xxxAsync(..., Executor) methods on [Async]CompletableFuture do not necessarily attach just asynchronous continuations if a SynchronousExecutor passed as Executor parameter, so we wouldn't get any guarantee of thread isolation. Only exposing xxxAsync() methods without custom Executor on the other hand precludes the possibility of supplying a custom executor. Sorry, but this was not a good idea. Regards, Peter From paul.sandoz at oracle.com Fri May 15 12:45:23 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 15 May 2015 14:45:23 +0200 Subject: PriorityQueue In-Reply-To: References: Message-ID: On May 14, 2015, at 8:17 AM, Brett Bernstein wrote: > I believe the linked sequence of messages refer to the addition of a > PriorityQueue constructor only taking a Comparator which was does appear in > Java 1.8. Did you have a link to something regarding the a constructor > taking a Collection and a Comparator (2 arguments)? > There is an old issue already logged for this: https://bugs.openjdk.java.net/browse/JDK-6356745 Give that one can already do: Collection c = ... Comparator cmp = ... PriorityQueue p =new PriorityQueue(c.size(), cmp); p.addAll(c); Is there a huge need for a new constructor that accepts a collection and a comparator? It seems a nice to have and may be marginally more efficient but AFAICT O-wise addAll and establishing the heap invariant for the entire tree that is initially unordered is the same (unless i am missing something obvious here). Paul. From paul.sandoz at oracle.com Fri May 15 13:05:37 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 15 May 2015 15:05:37 +0200 Subject: RFR: 8079459: JCK test api/java_nio/ByteBuffer/index.html#GetPutXXX start failing after JDK-8026049 In-Reply-To: <5555A318.3080504@oracle.com> References: <5550B92F.30101@redhat.com> <5550CD39.2010103@oracle.com> <5550D7FE.4030903@redhat.com> <5553784A.4030607@redhat.com> <5553997A.7030401@oracle.com> <5554A5BD.2080602@redhat.com> <5555A318.3080504@oracle.com> Message-ID: <4FDF3678-C911-4812-9CC6-3A58052390ED@oracle.com> On May 15, 2015, at 9:41 AM, Alan Bateman wrote: > > > On 14/05/2015 14:40, Andrew Haley wrote: >> >> >> : >> >> Fix: >> >> http://cr.openjdk.java.net/~aph/8079459-3-jdk/ >> >> Testcase: >> >> http://cr.openjdk.java.net/~aph/8079459-3-hs/ >> > This looks good to me. Saem here, Paul. > We'll need to address the splitting of the tests between two repos at some point. > > -Alan. From vitalyd at gmail.com Fri May 15 13:20:52 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Fri, 15 May 2015 09:20:52 -0400 Subject: PriorityQueue In-Reply-To: References: Message-ID: Paul, I don't think you're missing anything obvious (unless I am as well :)). What you wrote is basically what I meant by creating static helper method in Brett's own code that does exactly what you wrote. The asymptotic complexity will be nlogn in both cases, but the constant factor will be different since addAll() makes iterative add() calls with some overhead (branches, modCount bump, etc). The only O(n) constructors there are one taking SortedSet and copy constructor. Brett did mention he wanted the bulk add functionality (i.e. remove constant factor), and given the class already supports that internally, seems like a harmless change. sent from my phone On May 15, 2015 8:45 AM, "Paul Sandoz" wrote: > > On May 14, 2015, at 8:17 AM, Brett Bernstein > wrote: > > > I believe the linked sequence of messages refer to the addition of a > > PriorityQueue constructor only taking a Comparator which was does appear > in > > Java 1.8. Did you have a link to something regarding the a constructor > > taking a Collection and a Comparator (2 arguments)? > > > > There is an old issue already logged for this: > > https://bugs.openjdk.java.net/browse/JDK-6356745 > > Give that one can already do: > > Collection c = ... > Comparator cmp = ... > PriorityQueue p =new PriorityQueue(c.size(), cmp); > p.addAll(c); > > Is there a huge need for a new constructor that accepts a collection and a > comparator? > > It seems a nice to have and may be marginally more efficient but AFAICT > O-wise addAll and establishing the heap invariant for the entire tree that > is initially unordered is the same (unless i am missing something obvious > here). > > Paul. > From Alan.Bateman at oracle.com Fri May 15 13:23:27 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 15 May 2015 14:23:27 +0100 Subject: RFR: 8061254: SPECjvm2008-XML performance regressions in 9-b33 In-Reply-To: <55533AA9.7010304@oracle.com> References: <55533AA9.7010304@oracle.com> Message-ID: <5555F34F.9080005@oracle.com> On 13/05/2015 12:51, Claes Redestad wrote: > Hi, > > 9-b33 introduced a sustained regression in SPECjvm2008 > xml.transform on a number of our test setups. > > JDK-8058643 removed the check on value.length > 0, which > means repeated calls to "".hashCode() now do a store of the > calculated value (0) to the hash field. This has potential to > cause excessive cache coherence traffic in xml.transform[1] I remember the original change but of course didn't spot that empty String would result in a write of 0. I like Shipilev's First Law. The patch looks good to me. -Alan. From paul.sandoz at oracle.com Fri May 15 13:27:20 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 15 May 2015 15:27:20 +0200 Subject: PriorityQueue In-Reply-To: References: Message-ID: <3150B046-BBD8-4AF7-9575-9F870885CBE7@oracle.com> On May 15, 2015, at 3:20 PM, Vitaly Davidovich wrote: > Paul, > > I don't think you're missing anything obvious (unless I am as well :)). What you wrote is basically what I meant by creating static helper method in Brett's own code that does exactly what you wrote. The asymptotic complexity will be nlogn in both cases, but the constant factor will be different since addAll() makes iterative add() calls with some overhead (branches, modCount bump, etc). The only O(n) constructors there are one taking SortedSet and copy constructor. > > Yes. > Brett did mention he wanted the bulk add functionality (i.e. remove constant factor), and given the class already supports that internally, seems like a harmless change. > > I agree. This seems like an ideal issue for someone to pick up who is interesting in contributing a patch+tests to OpenJDK. Brett, i gather you might be interested in doing so? Paul. From claes.redestad at oracle.com Fri May 15 13:46:35 2015 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 15 May 2015 15:46:35 +0200 Subject: RFR: 8061254: SPECjvm2008-XML performance regressions in 9-b33 In-Reply-To: <5555F34F.9080005@oracle.com> References: <55533AA9.7010304@oracle.com> <5555F34F.9080005@oracle.com> Message-ID: <5555F8BB.1080902@oracle.com> On 2015-05-15 15:23, Alan Bateman wrote: > On 13/05/2015 12:51, Claes Redestad wrote: >> Hi, >> >> 9-b33 introduced a sustained regression in SPECjvm2008 >> xml.transform on a number of our test setups. >> >> JDK-8058643 removed the check on value.length > 0, which >> means repeated calls to "".hashCode() now do a store of the >> calculated value (0) to the hash field. This has potential to >> cause excessive cache coherence traffic in xml.transform[1] > I remember the original change but of course didn't spot that empty > String would result in a write of 0. I like Shipilev's First Law. Yes, this is a fine example of that law. :-) > > The patch looks good to me. Thanks! /Claes From chris.hegarty at oracle.com Fri May 15 14:04:44 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Fri, 15 May 2015 15:04:44 +0100 Subject: PriorityQueue In-Reply-To: References: Message-ID: <5555FCFC.5070609@oracle.com> And/Or should PriorityQueue override addAll and provide a more performant implementation for common Collection types ( just like the constructor )? -Chris. On 15/05/15 14:20, Vitaly Davidovich wrote: > Paul, > > I don't think you're missing anything obvious (unless I am as well :)). > What you wrote is basically what I meant by creating static helper method > in Brett's own code that does exactly what you wrote. The asymptotic > complexity will be nlogn in both cases, but the constant factor will be > different since addAll() makes iterative add() calls with some overhead > (branches, modCount bump, etc). The only O(n) constructors there are one > taking SortedSet and copy constructor. > > Brett did mention he wanted the bulk add functionality (i.e. remove > constant factor), and given the class already supports that internally, > seems like a harmless change. > > sent from my phone > On May 15, 2015 8:45 AM, "Paul Sandoz" wrote: > >> >> On May 14, 2015, at 8:17 AM, Brett Bernstein >> wrote: >> >>> I believe the linked sequence of messages refer to the addition of a >>> PriorityQueue constructor only taking a Comparator which was does appear >> in >>> Java 1.8. Did you have a link to something regarding the a constructor >>> taking a Collection and a Comparator (2 arguments)? >>> >> >> There is an old issue already logged for this: >> >> https://bugs.openjdk.java.net/browse/JDK-6356745 >> >> Give that one can already do: >> >> Collection c = ... >> Comparator cmp = ... >> PriorityQueue p =new PriorityQueue(c.size(), cmp); >> p.addAll(c); >> >> Is there a huge need for a new constructor that accepts a collection and a >> comparator? >> >> It seems a nice to have and may be marginally more efficient but AFAICT >> O-wise addAll and establishing the heap invariant for the entire tree that >> is initially unordered is the same (unless i am missing something obvious >> here). >> >> Paul. >> From vitalyd at gmail.com Fri May 15 14:21:59 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Fri, 15 May 2015 10:21:59 -0400 Subject: PriorityQueue In-Reply-To: <5555FCFC.5070609@oracle.com> References: <5555FCFC.5070609@oracle.com> Message-ID: Constructor has advantage in knowing it's working with a clean slate; addAll could check for that too, I suppose, and at least skip things like modCount increments. As a general rule of thumb, I always prefer to have dedicated methods for batch/bulk operations since you have more context to potentially optimize. sent from my phone On May 15, 2015 10:04 AM, "Chris Hegarty" wrote: > And/Or should PriorityQueue override addAll and provide a more performant > implementation for common Collection types ( just like the constructor )? > > -Chris. > > On 15/05/15 14:20, Vitaly Davidovich wrote: > >> Paul, >> >> I don't think you're missing anything obvious (unless I am as well :)). >> What you wrote is basically what I meant by creating static helper method >> in Brett's own code that does exactly what you wrote. The asymptotic >> complexity will be nlogn in both cases, but the constant factor will be >> different since addAll() makes iterative add() calls with some overhead >> (branches, modCount bump, etc). The only O(n) constructors there are one >> taking SortedSet and copy constructor. >> >> Brett did mention he wanted the bulk add functionality (i.e. remove >> constant factor), and given the class already supports that internally, >> seems like a harmless change. >> >> sent from my phone >> On May 15, 2015 8:45 AM, "Paul Sandoz" wrote: >> >> >>> On May 14, 2015, at 8:17 AM, Brett Bernstein >>> wrote: >>> >>> I believe the linked sequence of messages refer to the addition of a >>>> PriorityQueue constructor only taking a Comparator which was does appear >>>> >>> in >>> >>>> Java 1.8. Did you have a link to something regarding the a constructor >>>> taking a Collection and a Comparator (2 arguments)? >>>> >>>> >>> There is an old issue already logged for this: >>> >>> https://bugs.openjdk.java.net/browse/JDK-6356745 >>> >>> Give that one can already do: >>> >>> Collection c = ... >>> Comparator cmp = ... >>> PriorityQueue p =new PriorityQueue(c.size(), cmp); >>> p.addAll(c); >>> >>> Is there a huge need for a new constructor that accepts a collection and >>> a >>> comparator? >>> >>> It seems a nice to have and may be marginally more efficient but AFAICT >>> O-wise addAll and establishing the heap invariant for the entire tree >>> that >>> is initially unordered is the same (unless i am missing something obvious >>> here). >>> >>> Paul. >>> >>> From daniel.fuchs at oracle.com Fri May 15 15:05:29 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 15 May 2015 17:05:29 +0200 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <554860F3.6030909@oracle.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> <5542C2ED.1090100@gmail.com> <5547736A.4060805@gmail.com> <55477838.6020200@oracle.com> <55477D95.1010202@gmail.com> <55478658.4090700@gmail.com> <5547C000.9040005@oracle.com> <554860F3.6030909@oracle.com> Message-ID: <55560B39.5080601@oracle.com> On 05/05/15 08:19, Mandy Chung wrote: > > On 5/4/2015 11:52 AM, Daniel Fuchs wrote: >> On 04/05/15 16:46, Peter Levart wrote: >>> Hi Daniel, >>> >>> Here it is: >>> >>> http://cr.openjdk.java.net/~plevart/misc/LogManager.synchronization/webrev.04/ >>> >> >> Looks good for me Peter :-) >> Hopefully Mandy will like it too! >> > > Yes it looks good to me. Thanks to both of you for imprpving the > synchronization. This is the comment on the test I sent last round: > > TestConfigurationLock.java > > Copyright year should be 2015 > > TestConfigurationLock.properties > > It would be good to delete all commented lines except the lines > relevant to the setting to make it obvious what the configuration is. Right. Sorry I forgot about that. Here is an updated webrev containing Peter's webrev.04 in which I have updated the test: http://cr.openjdk.java.net/~dfuchs/webrev_8077846/webrev.05 Peter, are you still willing to push that? best regards, -- daniel > > Mandy > From miroslav.kos at oracle.com Fri May 15 15:13:47 2015 From: miroslav.kos at oracle.com (Miroslav Kos) Date: Fri, 15 May 2015 17:13:47 +0200 Subject: RFR [9] 8072839: JAX-B Plugability Layer: using java.util.ServiceLoader Message-ID: <55560D2B.3040400@oracle.com> Hi everybody, this is review request for: 8072839: JAX-B Plugability Layer: using java.util.ServiceLoader The JAX-B API changed a little bit - proprietary ServiceLoader-like code has been replaced by java.util.ServiceLoader. This change is required by Jigsaw, old configuration way still supported. JBS:https://bugs.openjdk.java.net/browse/JDK-8072839 webrev: http://cr.openjdk.java.net/~mkos/8072839/jaxws.02/index.html CCC: http://ccc.us.oracle.com/8072839 Testing: JAX-WS (standalone) unit tests, no, jtreg tests available now, TCK/JCK tests will require new tests. Thanks Miran From lance.andersen at oracle.com Fri May 15 15:35:21 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Fri, 15 May 2015 11:35:21 -0400 Subject: Review request for JDK-8078596: jaxp tests failed in modular jdk due to internal class access In-Reply-To: <020101d08ef4$48504950$d8f0dbf0$@oracle.com> References: <020101d08ef4$48504950$d8f0dbf0$@oracle.com> Message-ID: Hi Frank, Seems OK Best Lance On May 15, 2015, at 5:48 AM, Frank Yuan wrote: > Hi, Joe and All > > > > This is a test bug on 9-repo-jigsaw, jaxp tests failed due to internal class > access. > > > > To fix this bug, I made the following changes: > > 1. moved the tests which test internal APIs to separate directory and added > @modules for them > > 2. for other tests which don't intend to test internal APIs but have some > internal API dependencies: > > 2.1. replaced internal APIs usage with public APIs > > 2.2. replaced the constants defined in internal classes with local > constants > > > > As Alan's suggestion, I would push the changes to jdk9/dev and ask an open > review. Would you like to take a look? Any comment will be appreciated. > > > > bug: https://bugs.openjdk.java.net/browse/JDK-8078596 > > webrev: http://cr.openjdk.java.net/~fyuan/8078596/webrev.00/ > > > > > > > > Thanks, > > > > Frank > > > 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 May 15 16:12:40 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 15 May 2015 18:12:40 +0200 Subject: Patch to improve primitives Array.sort() In-Reply-To: <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> Message-ID: <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> On May 15, 2015, at 11:48 AM, "Chan, Sunny" wrote: > I have provided Paul with an updated patch: > Here it is: http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.1/ In DualPivotQuicksort 63 /** 64 * The maximum length of run in merge sort. 65 */ 66 private static final int MAX_RUN_LENGTH = 33; You can remove this constant. > * The test has been updated using data provider and reduce as much repetition as possible. Looking much better. Convention-wise if you don't have to deal with any check exceptions using a Supplier is more preferable to Callable. Up to you. 56 @Test(dataProvider = "arrays") 57 public void runTests(String testName, Callable dataMethod) throws Exception 58 { 59 int[] array = dataMethod.call(); 60 this.sortAndAssert(array); 61 this.sortAndAssert(this.floatCopyFromInt(array)); 62 this.sortAndAssert(this.doubleCopyFromInt(array)); 63 this.sortAndAssert(this.longCopyFromInt(array)); 64 this.sortAndAssert(this.shortCopyFromInt(array)); 65 this.sortAndAssert(this.charCopyFromInt(array)); At line 60 should you clone the array? otherwise, if i have looked correctly, that sorted result will be tested for other values. > * The GS copyright notice from the main JDK patch. However we retain it on our test cases as we developed ourselves. In our previous contributions where we provided new tests we have put our copyright along with oracle copyright and it was accepted (see: http://hg.openjdk.java.net/jdk9/dev/jdk/file/ed94f3e7ba6b/test/java/lang/instrument/DaemonThread/TestDaemonThread.java) Ok. It was more query on my part. I believe it's ok for you to add copyright on both files if you wish. > * Alan has commented that there were older benchmark but searching through the archive I can see it mention "BentleyBasher" I cannot find the actual code that Vladimir used (thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2009-September/002633.html). Is there anywhere I can get hold of it? > I tried looking, but i cannot find any. Paul. From lowasser at google.com Fri May 15 16:15:56 2015 From: lowasser at google.com (Louis Wasserman) Date: Fri, 15 May 2015 16:15:56 +0000 Subject: PriorityQueue In-Reply-To: References: <5555FCFC.5070609@oracle.com> Message-ID: http://lcm.csa.iisc.ernet.in/dsa/node139.html suggests an algorithm for heapifying an unsorted array in O(n), corroborated elsewhere at http://courses.csail.mit.edu/6.006/fall10/handouts/recitation10-8.pdf . Any particular reason we can't use that approach? On Fri, May 15, 2015 at 7:22 AM Vitaly Davidovich wrote: > Constructor has advantage in knowing it's working with a clean slate; > addAll could check for that too, I suppose, and at least skip things like > modCount increments. As a general rule of thumb, I always prefer to have > dedicated methods for batch/bulk operations since you have more context to > potentially optimize. > > sent from my phone > On May 15, 2015 10:04 AM, "Chris Hegarty" > wrote: > > > And/Or should PriorityQueue override addAll and provide a more performant > > implementation for common Collection types ( just like the constructor )? > > > > -Chris. > > > > On 15/05/15 14:20, Vitaly Davidovich wrote: > > > >> Paul, > >> > >> I don't think you're missing anything obvious (unless I am as well :)). > >> What you wrote is basically what I meant by creating static helper > method > >> in Brett's own code that does exactly what you wrote. The asymptotic > >> complexity will be nlogn in both cases, but the constant factor will be > >> different since addAll() makes iterative add() calls with some overhead > >> (branches, modCount bump, etc). The only O(n) constructors there are > one > >> taking SortedSet and copy constructor. > >> > >> Brett did mention he wanted the bulk add functionality (i.e. remove > >> constant factor), and given the class already supports that internally, > >> seems like a harmless change. > >> > >> sent from my phone > >> On May 15, 2015 8:45 AM, "Paul Sandoz" wrote: > >> > >> > >>> On May 14, 2015, at 8:17 AM, Brett Bernstein < > brett.bernstein at gmail.com> > >>> wrote: > >>> > >>> I believe the linked sequence of messages refer to the addition of a > >>>> PriorityQueue constructor only taking a Comparator which was does > appear > >>>> > >>> in > >>> > >>>> Java 1.8. Did you have a link to something regarding the a > constructor > >>>> taking a Collection and a Comparator (2 arguments)? > >>>> > >>>> > >>> There is an old issue already logged for this: > >>> > >>> https://bugs.openjdk.java.net/browse/JDK-6356745 > >>> > >>> Give that one can already do: > >>> > >>> Collection c = ... > >>> Comparator cmp = ... > >>> PriorityQueue p =new PriorityQueue(c.size(), cmp); > >>> p.addAll(c); > >>> > >>> Is there a huge need for a new constructor that accepts a collection > and > >>> a > >>> comparator? > >>> > >>> It seems a nice to have and may be marginally more efficient but AFAICT > >>> O-wise addAll and establishing the heap invariant for the entire tree > >>> that > >>> is initially unordered is the same (unless i am missing something > obvious > >>> here). > >>> > >>> Paul. > >>> > >>> > From paul.sandoz at oracle.com Fri May 15 16:40:15 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 15 May 2015 18:40:15 +0200 Subject: PriorityQueue In-Reply-To: References: <5555FCFC.5070609@oracle.com> Message-ID: <61D121A5-47E2-4B36-9EF4-6A7FA383F644@oracle.com> On May 15, 2015, at 6:15 PM, Louis Wasserman wrote: > http://lcm.csa.iisc.ernet.in/dsa/node139.html suggests an algorithm for > heapifying an unsorted array in O(n), corroborated elsewhere at > http://courses.csail.mit.edu/6.006/fall10/handouts/recitation10-8.pdf . > Any particular reason we can't use that approach? > Thanks. I got things wrong before. I believe the PQ.heapify() does exactly that: private void heapify() { for (int i = (size >>> 1) - 1; i >= 0; i--) siftDown(i, (E) queue[i]); } So there is more value in the constructor than i originally thought. Paul. From vitalyd at gmail.com Fri May 15 16:45:29 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Fri, 15 May 2015 12:45:29 -0400 Subject: PriorityQueue In-Reply-To: <61D121A5-47E2-4B36-9EF4-6A7FA383F644@oracle.com> References: <5555FCFC.5070609@oracle.com> <61D121A5-47E2-4B36-9EF4-6A7FA383F644@oracle.com> Message-ID: Whoops, I believe you're right -- I completely overlooked that as well :( On Fri, May 15, 2015 at 12:40 PM, Paul Sandoz wrote: > > On May 15, 2015, at 6:15 PM, Louis Wasserman wrote: > > > http://lcm.csa.iisc.ernet.in/dsa/node139.html suggests an algorithm for > > heapifying an unsorted array in O(n), corroborated elsewhere at > > http://courses.csail.mit.edu/6.006/fall10/handouts/recitation10-8.pdf . > > Any particular reason we can't use that approach? > > > > Thanks. I got things wrong before. I believe the PQ.heapify() does exactly > that: > > private void heapify() { > for (int i = (size >>> 1) - 1; i >= 0; i--) > siftDown(i, (E) queue[i]); > } > > So there is more value in the constructor than i originally thought. > > Paul. > From john.r.rose at oracle.com Fri May 15 17:06:50 2015 From: john.r.rose at oracle.com (John Rose) Date: Fri, 15 May 2015 10:06:50 -0700 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <5555E343.5050600@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> <55533CAE.3050201@oracle.com> <55549297.5020002@oracle.com> <5555E343.5050600@oracle.com> Message-ID: I know injected fields are somewhat hacky, but there are a couple of conditions here which would motivate their use: 1. The field is of a type not known to Java. Usually, and in this case, it is a C pointer to some metadata. We can make space for it with a Java long, but that is a size mismatch on 32-bit systems. Such mismatches have occasionally caused bugs on big-endian systems, although we try to defend against them by using long-wise reads followed by casts. 2. The field is useless to Java code, and would be a vulnerability if somebody found a way to touch it from Java. In both these ways the 'dependencies' field is like the MemberName.vmtarget field. (Suggestion: s/dependencies/vmdependencies/ to follow that pattern.) ? John On May 15, 2015, at 5:14 AM, Vladimir Ivanov wrote: > > After private discussion with Paul, here's an update: > http://cr.openjdk.java.net/~vlivanov/8079205/webrev.03 > > Renamed CallSite$Context to MethodHandleNatives$Context. > > Best regards, > Vladimir Ivanov > > On 5/14/15 3:18 PM, Vladimir Ivanov wrote: >> Small update in JDK code (webrev updated in place): >> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 >> >> Changes: >> - hid Context.dependencies field from Reflection >> - new test case: CallSiteDepContextTest.testHiddenDepField() >> >> Best regards, >> Vladimir Ivanov >> >> On 5/13/15 5:56 PM, Paul Sandoz wrote: >>> >>> On May 13, 2015, at 1:59 PM, Vladimir Ivanov >>> wrote: >>> >>>> Peter, Paul, thanks for the feedback! >>>> >>>> Updated the webrev in place: >>>> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 >>>> >>> >>> +1 >>> >>> >>>>> I am not an export in the HS area but the code mostly made sense to >>>>> me. I also like Peter's suggestion of Context implementing Runnable. >>>> I agree. Integrated. >>>> >>>>> Some minor comments. >>>>> >>>>> CallSite.java: >>>>> >>>>> 145 private final long dependencies = 0; // Used by JVM to >>>>> store JVM_nmethodBucket* >>>>> >>>>> It's a little odd to see this field be final, but i think i >>>>> understand the motivation as it's essentially acting as a memory >>>>> address pointing to the head of the nbucket list, so in Java code >>>>> you don't want to assign it to anything other than 0. >>>> Yes, my motivation was to forbid reads & writes of the field from >>>> Java code. I was experimenting with injecting the field by VM, but >>>> it's less attractive. >>>> >>> >>> I was wondering if that were possible. >>> >>> >>>>> Is VM access, via java_lang_invoke_CallSite_Context, affected by >>>>> treating final fields as really final in the j.l.i package? >>>> No, field modifiers aren't respected. oopDesc::*_field_[get|put] does >>>> a raw read/write using field offset. >>>> >>> >>> Ok. >>> >>> Paul. >>> From alexander.v.stepanov at oracle.com Fri May 15 17:16:50 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Fri, 15 May 2015 20:16:50 +0300 Subject: RFR [9] 8080422: some docs cleanup for core libs Message-ID: <55562A02.3000009@oracle.com> Hello, Could you please review the following fix http://cr.openjdk.java.net/~avstepan/8080422/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8080422 Just some HTML markup fix. The affected packages should (probably) not be visible in the new modular system, but nevertheless... Thanks, Alexander From stuart.marks at oracle.com Fri May 15 17:30:42 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 15 May 2015 10:30:42 -0700 Subject: PriorityQueue In-Reply-To: References: <5555FCFC.5070609@oracle.com> <61D121A5-47E2-4B36-9EF4-6A7FA383F644@oracle.com> Message-ID: <55562D42.5070005@oracle.com> Yes, this is very subtle, and Brett mentioned it (albeit somewhat obliquely) in an email on jdk9-dev: [1] > If someone needs to make a > heap and their data is Comparable, the corresponding constructor gives a > O(n) runtime. If their data uses a Comparator, the corresponding runtime > (using addAll) is O(n*log(n)). I was initially confused by this because it seems to attribute the algorithmic difference to Comparable vs Comparator, which doesn't make any sense. (I managed to unconfuse myself before opening my big mouth, though.) The real issue is that the Collection-consuming constructor code path goes through heapify() and siftDown(), whereas the non-Collection-consuming constructor followed by addAll() goes through siftUp(). The problem is that if you want your own Comparator, there's no constructor that takes a Collection, so you're forced to the slow path. Earlier in this thread, Paul unearthed JDK-6356745 [2] which says essentially the same thing as proposed here. I'll update it with some notes. s'marks [1] http://mail.openjdk.java.net/pipermail/jdk9-dev/2015-May/002205.html [2] https://bugs.openjdk.java.net/browse/JDK-6356745 On 5/15/15 9:45 AM, Vitaly Davidovich wrote: > Whoops, I believe you're right -- I completely overlooked that as well :( > > On Fri, May 15, 2015 at 12:40 PM, Paul Sandoz > wrote: > >> >> On May 15, 2015, at 6:15 PM, Louis Wasserman wrote: >> >>> http://lcm.csa.iisc.ernet.in/dsa/node139.html suggests an algorithm for >>> heapifying an unsorted array in O(n), corroborated elsewhere at >>> http://courses.csail.mit.edu/6.006/fall10/handouts/recitation10-8.pdf . >>> Any particular reason we can't use that approach? >>> >> >> Thanks. I got things wrong before. I believe the PQ.heapify() does exactly >> that: >> >> private void heapify() { >> for (int i = (size >>> 1) - 1; i >= 0; i--) >> siftDown(i, (E) queue[i]); >> } >> >> So there is more value in the constructor than i originally thought. >> >> Paul. >> From huizhe.wang at oracle.com Fri May 15 17:38:25 2015 From: huizhe.wang at oracle.com (huizhe wang) Date: Fri, 15 May 2015 10:38:25 -0700 Subject: Review request for JDK-8078596: jaxp tests failed in modular jdk due to internal class access In-Reply-To: References: <020101d08ef4$48504950$d8f0dbf0$@oracle.com> Message-ID: <55562F11.9090000@oracle.com> Hi Frank, The patch looks good. I'll check it in later today. Thanks, Joe On 5/15/2015 8:35 AM, Lance Andersen wrote: > Hi Frank, > > Seems OK > > Best > Lance > On May 15, 2015, at 5:48 AM, Frank Yuan > wrote: > >> Hi, Joe and All >> >> >> >> This is a test bug on 9-repo-jigsaw, jaxp tests failed due to >> internal class >> access. >> >> >> >> To fix this bug, I made the following changes: >> >> 1. moved the tests which test internal APIs to separate directory and >> added >> @modules for them >> >> 2. for other tests which don't intend to test internal APIs but have some >> internal API dependencies: >> >> 2.1. replaced internal APIs usage with public APIs >> >> 2.2. replaced the constants defined in internal classes with local >> constants >> >> >> >> As Alan's suggestion, I would push the changes to jdk9/dev and ask an >> open >> review. Would you like to take a look? Any comment will be appreciated. >> >> >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8078596 >> >> webrev: http://cr.openjdk.java.net/~fyuan/8078596/webrev.00/ >> >> >> >> >> >> >> >> >> Thanks, >> >> >> >> Frank >> >> >> > > > > 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 vitalyd at gmail.com Fri May 15 17:47:49 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Fri, 15 May 2015 13:47:49 -0400 Subject: PriorityQueue In-Reply-To: <55562D42.5070005@oracle.com> References: <5555FCFC.5070609@oracle.com> <61D121A5-47E2-4B36-9EF4-6A7FA383F644@oracle.com> <55562D42.5070005@oracle.com> Message-ID: > > I was initially confused by this because it seems to attribute the > algorithmic difference to Comparable vs Comparator, which doesn't make any > sense That's exactly what threw me off as well, but I didn't bother checking (doh!). Anyway, I think the upside is we're all in agreement now that this is *definitely* a worthwhile improvement :). On Fri, May 15, 2015 at 1:30 PM, Stuart Marks wrote: > Yes, this is very subtle, and Brett mentioned it (albeit somewhat > obliquely) in an email on jdk9-dev: [1] > > If someone needs to make a >> heap and their data is Comparable, the corresponding constructor gives a >> O(n) runtime. If their data uses a Comparator, the corresponding runtime >> (using addAll) is O(n*log(n)). >> > > I was initially confused by this because it seems to attribute the > algorithmic difference to Comparable vs Comparator, which doesn't make any > sense. (I managed to unconfuse myself before opening my big mouth, though.) > The real issue is that the Collection-consuming constructor code path goes > through heapify() and siftDown(), whereas the non-Collection-consuming > constructor followed by addAll() goes through siftUp(). > > The problem is that if you want your own Comparator, there's no > constructor that takes a Collection, so you're forced to the slow path. > > Earlier in this thread, Paul unearthed JDK-6356745 [2] which says > essentially the same thing as proposed here. I'll update it with some notes. > > > s'marks > > > [1] http://mail.openjdk.java.net/pipermail/jdk9-dev/2015-May/002205.html > > [2] https://bugs.openjdk.java.net/browse/JDK-6356745 > > > > > On 5/15/15 9:45 AM, Vitaly Davidovich wrote: > >> Whoops, I believe you're right -- I completely overlooked that as well :( >> >> On Fri, May 15, 2015 at 12:40 PM, Paul Sandoz >> wrote: >> >> >>> On May 15, 2015, at 6:15 PM, Louis Wasserman >>> wrote: >>> >>> http://lcm.csa.iisc.ernet.in/dsa/node139.html suggests an algorithm for >>>> heapifying an unsorted array in O(n), corroborated elsewhere at >>>> http://courses.csail.mit.edu/6.006/fall10/handouts/recitation10-8.pdf . >>>> Any particular reason we can't use that approach? >>>> >>>> >>> Thanks. I got things wrong before. I believe the PQ.heapify() does >>> exactly >>> that: >>> >>> private void heapify() { >>> for (int i = (size >>> 1) - 1; i >= 0; i--) >>> siftDown(i, (E) queue[i]); >>> } >>> >>> So there is more value in the constructor than i originally thought. >>> >>> Paul. >>> >>> From brent.christian at oracle.com Fri May 15 19:09:39 2015 From: brent.christian at oracle.com (Brent Christian) Date: Fri, 15 May 2015 12:09:39 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> <55526FF5.9000509@gmail.com> Message-ID: <55564473.3010704@oracle.com> On 5/13/15 8:53 AM, Mandy Chung wrote: >> On May 12, 2015, at 2:26 PM, Peter Levart >> wrote: >> On 05/12/2015 10:49 PM, Mandy Chung wrote: >>>> But I think it should be pretty safe to make the >>>> java.util.Properties object override all Hashtable methods and >>>> delegate to internal CMH so that: >>>> - all modification methods + all bulk read methods such as >>>> (keySet().toArray, values.toArray) are made synchronized again >>>> - individual entry read methods (get, containsKey, ...) are not >>>> synchronized. >>>> >>>> This way we get the benefits of non-synchronized read access >>>> but the change is hardly observable. In particular since >>>> external synchronization on the Properties object makes guarded >>>> code atomic like it is now and individual entry read accesses >>>> are almost equivalent whether they are synchronized or not and >>>> I would be surprised if any code using Properties for the >>>> purpose they were designed for worked any differently. >>> >>> I agree that making read-only methods not synchronized while >>> keeping any method with write-access with synchronized is pretty >>> safe change and low compatibility risk. On the other hand, would >>> most of the overrridden methods be synchronized then? >> >> Yes, and that doesn't seem to be a problem. Setting properties is >> not very frequent operation and is usually quite localized. Reading >> properties is, on the other hand, a very frequent operation >> dispersed throughout the code (almost like logging) and therefore >> very prone to deadlocks like the one in this issue. I think that by >> having an unsynchronized get(Property), most problems with >> Properties will be solved - deadlock and performance (scalability) >> related. > > I?m keen on cleaning up the system properties but it is a bigger > scope as it should take other related enhancement requests into > account that should be something for future. I think what you > propose seems a good solution to fix JDK-8029891 while it doesn?t > completely get us off the deadlock due to user code locking the > Properties object. Updated webrev: http://cr.openjdk.java.net/~bchristi/8029891/webrev.1/ I have restored synchronization to modification methods, and to my interpretation of "bulk read" operations: * forEach * replaceAll * store: (synchronized(this) in store0; also, entrySet() returns a synchronizedSet) * storeToXML: PropertiesDefaultsHandler.store() synchronizes on the Properties instance * propertyNames(): returns an Enumeration not backed by the Properies; calls (still synchronized) enumerate() * stringPropertyNames returns a Set not backed by the Properties; calls (still synchronized) enumerateStringProperties These continue to return a synchronized[Set|Collection]: * keySet * entrySet * values These methods should operate on a coherent snapshot: * clone * equals * hashCode I expect these two are only used for debugging. I wonder if we could get away with removing synchronization: * list * toString I'm still looking through the serialization code, though I suspect some synchronization should be added. The new webrev also has the updated test case from Peter. Thanks, -Brent From martinrb at google.com Fri May 15 19:31:02 2015 From: martinrb at google.com (Martin Buchholz) Date: Fri, 15 May 2015 12:31:02 -0700 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <5554A6D4.6060902@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> Message-ID: On Thu, May 14, 2015 at 6:44 AM, Roger Riggs wrote: > >> At some point in the development of this API, the implementation >> introduced the AsyncExecutor to execute synchronous continuations of the >> onExit() returned CompletableFuture(s). What was the main motivation for >> this given that: >> - previously, ForkJoinPoll.commonPool() was used instead that by default >> possesses some similar characteristics (Innocuous threads when >> SecurityManager is active) >> > The AsyncExecutor also uses InnocuousThreads. > > - this AsyncExecutor is only effective for 1st "wave" of synchronous >> continuations. Asynchronous continuations and synchronous continuations >> following them will still use ForkJoinPoll.commonPool() >> > Unfortunately, the common ForkJoinPool assumes that tasks queued to it > complete relatively > quickly and free the thread. It does not grow the number of threads and > is not appropriate > for tasks that block for indefinite periods as might be need to wait for a > Process to exit. > > Given that there's no known alternative to tying up a thread to execute waitpid, there's only small potential benefit to using forkjoinpool. But it might be reasonable if you use the ManagedBlocker mechanism to inform the pool that you are about to block. I liked the fact that we could use threads with a small stack size to run waitpid in the special purpose threadpool, but I don't know how valuable that is in practice. From daniel.fuchs at oracle.com Fri May 15 19:58:48 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 15 May 2015 21:58:48 +0200 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55564473.3010704@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> <55526FF5.9000509@gmail.com> <55564473.3010704@oracle.com> Message-ID: <55564FF8.3010802@oracle.com> Hi Brent, 1163 @Override 1164 public Enumeration keys() { 1165 return map.keys(); 1166 } I wonder if you should use: public Enumeration keys() { return Collections.enumeration(map.keySet()); } instead. ConcurrentHashMap.keys() returns an Enumeration which is also an Iterator which supports removal of elements, that might have unintended side effects WRT to concurrency & subclassing. best regards, -- daniel On 15/05/15 21:09, Brent Christian wrote: > On 5/13/15 8:53 AM, Mandy Chung wrote: >>> On May 12, 2015, at 2:26 PM, Peter Levart >>> wrote: >>> On 05/12/2015 10:49 PM, Mandy Chung wrote: >>>>> But I think it should be pretty safe to make the >>>>> java.util.Properties object override all Hashtable methods and >>>>> delegate to internal CMH so that: >>>>> - all modification methods + all bulk read methods such as >>>>> (keySet().toArray, values.toArray) are made synchronized again >>>>> - individual entry read methods (get, containsKey, ...) are not >>>>> synchronized. >>>>> >>>>> This way we get the benefits of non-synchronized read access >>>>> but the change is hardly observable. In particular since >>>>> external synchronization on the Properties object makes guarded >>>>> code atomic like it is now and individual entry read accesses >>>>> are almost equivalent whether they are synchronized or not and >>>>> I would be surprised if any code using Properties for the >>>>> purpose they were designed for worked any differently. >>>> >>>> I agree that making read-only methods not synchronized while >>>> keeping any method with write-access with synchronized is pretty >>>> safe change and low compatibility risk. On the other hand, would >>>> most of the overrridden methods be synchronized then? >>> >>> Yes, and that doesn't seem to be a problem. Setting properties is >>> not very frequent operation and is usually quite localized. Reading >>> properties is, on the other hand, a very frequent operation >>> dispersed throughout the code (almost like logging) and therefore >>> very prone to deadlocks like the one in this issue. I think that by >>> having an unsynchronized get(Property), most problems with >>> Properties will be solved - deadlock and performance (scalability) >>> related. >> >> I?m keen on cleaning up the system properties but it is a bigger >> scope as it should take other related enhancement requests into >> account that should be something for future. I think what you >> propose seems a good solution to fix JDK-8029891 while it doesn?t >> completely get us off the deadlock due to user code locking the >> Properties object. > > Updated webrev: > > http://cr.openjdk.java.net/~bchristi/8029891/webrev.1/ > > I have restored synchronization to modification methods, and to my > interpretation of "bulk read" operations: > > * forEach > * replaceAll > * store: (synchronized(this) in store0; also, entrySet() returns a > synchronizedSet) > * storeToXML: PropertiesDefaultsHandler.store() synchronizes on the > Properties instance > * propertyNames(): returns an Enumeration not backed by the > Properies; calls (still synchronized) enumerate() > * stringPropertyNames returns a Set not backed by the Properties; > calls (still synchronized) enumerateStringProperties > > These continue to return a synchronized[Set|Collection]: > * keySet > * entrySet > * values > > These methods should operate on a coherent snapshot: > * clone > * equals > * hashCode > > I expect these two are only used for debugging. I wonder if we could > get away with removing synchronization: > * list > * toString > > I'm still looking through the serialization code, though I suspect some > synchronization should be added. > > The new webrev also has the updated test case from Peter. > > Thanks, > -Brent > From dmitry.samersoff at oracle.com Fri May 15 20:23:45 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Fri, 15 May 2015 23:23:45 +0300 Subject: RFR(M,v6): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55550718.1000507@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <5554DE61.5010403@oracle.com> <5555016F.2050802@gmail.com> <55550718.1000507@gmail.com> Message-ID: <555655D1.90208@oracle.com> Everybody, Please review updated version. http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.06/ JDK part provided by Peter Levart, so all credentials belongs to him. -Dmitry On 2015-05-14 23:35, Peter Levart wrote: > > > On 05/14/2015 10:11 PM, Peter Levart wrote: >> Hi Dmitry, >> >> ReferenceQueue is not really a queue, but a LIFO stack. Scanner is >> walking the stack from top (the 'head') to bottom (the last element >> pointing to itself). When poller(s) overtake the scanner, it actually >> means that the top of the stack has been eaten under scanner's feet >> while trying to grab it. Restarting from 'head' actually means >> 'catching-up' wit poller(s) and trying to keep up with them. We don't >> get the 'eaten' elements, but might be lucky to get some more food >> until it's all eaten. Usually we will get all of the elements, since >> poller(s) must synchronize and do additional work, so they are slower >> and there's also enqueuer(s) that push elements on the top of the >> stack so poller(s) must eat those last pushed elements before they can >> continue chasing the scanner... >> >> When scanner is overtaken by poller, then there is a chance the >> scanner will get less elements than there were present in the stack if >> a snapshot was taken, so catching-up by restarting from 'head' tries >> to at least recover some of the rest of the elements of that snapshot >> before they are gone. > > Also, the chance that the scanner is overtaken by poller is greater at > the start of race. The scanner and poller start from the same spot and > as we know threads are "jumpy" so it will happen quite frequently that a > poller jumps before scanner. So just giving-up when overtaken might > return 0 or just a few elements when there are millions there in the > queue. When scanner finally gets a head start, it will usually lead the > race to the end. > > Peter > >> >> Does this make more sense now? >> >> Regards, Peter >> >> On 05/14/2015 07:41 PM, Dmitry Samersoff wrote: >>> Peter, >>> >>> Could we just bail out on r == r.next? >>> >>> It gives us less accurate result, but I suspect that If we restart from >>> head we need to flush all counters. >>> >>> As far I understand queue poller removes items one by one from a queue >>> end so if we overtaken by queue poller we can safely assume that >>> we are at the end of the queue. >>> >>> Is it correct? >>> >>> -Dmitry >>> >>> On 2015-05-14 10:50, Peter Levart wrote: >>>> Hi Derek, >>>> >>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>> Hi Peter, >>>>> >>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>> but I have some concerns... >>>> I did have a concern too, ... >>>> >>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>> Hi Dmitry, >>>>>> >>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>> logical. >>>>>> >>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>> threads for the entire time of iteration. This can blow up the >>>>>> application. Suppose one wants to diagnose the application because he >>>>>> suspects that finalizer thread hardly keeps up with production of >>>>>> finalizable instances. This can happen if the allocation rate of >>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds up >>>>>> gradually and is already holding several million objects. Now you >>>>>> initiate the diagnostic command to print the queue. The iteration >>>>>> over and grouping/counting of several millions of Finalizer(s) takes >>>>>> some time. This blocks finalizer thread and reference handler thread. >>>>>> But does not block the threads that allocate finalizable objects. By >>>>>> the time the iteration is over, the JVM blows up and application >>>>>> slows down to a halt doing GCs most of the time, getting OOMEs, etc... >>>>>> >>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>> purposes without holding a lock. The modification required to do that >>>>>> is the following (havent tested this, but I think it should work): >>>>>> >>>>>> >>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>> >>>>> One issue to watch out for is the garbage collectors inspect the >>>>> Reference.next field from C code directly (to distinguish active vs. >>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>> >>>>> Your change makes "inactive" References superficially look like >>>>> "enqueued" References. The GC code is rather subtle and I haven't yet >>>>> seen a case where it would get confused by this change, but there >>>>> could easily be something like that lurking in the GC code. >>>> ...but then I thought that GC can in no way treat a Reference >>>> differently whether it is still enqueued in a ReferenceQueue or already >>>> dequeued (inactive) - responsibility is already on the Java side. >>>> Currently the definition of Reference.next is this: >>>> >>>> /* When active: NULL >>>> * pending: this >>>> * Enqueued: next reference in queue (or this if last) >>>> * Inactive: this >>>> */ >>>> @SuppressWarnings("rawtypes") >>>> Reference next; >>>> >>>> We see that, unless GC inspects all ReferenceQueue instances and scans >>>> their lists too, the state of a Reference that is enqueued as last in >>>> list is indistinguishable from the state of inactive Reference. So I >>>> deduced that this distinction (enqueued/inactive) can't be established >>>> solely on the value of .next field ( == this or != this)... >>>> >>>> But I should inspect the GC code too to build a better understanding of >>>> that part of the story... >>>> >>>> Anyway. It turns out that there is already enough state in Reference to >>>> destinguish between it being enqueued as last in list and already >>>> dequeued (inactive) - the additional state is Reference.queue that >>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>> (r.next and r.queue) are assigned and read in correct order. This can be >>>> achieved either by making Reference.next a volatile field or by a couple >>>> of explicit fences: >>>> >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>> >>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>> before linking the reference into the queue's head in >>>> ReferenceQueue.enqueue(): >>>> >>>> r.queue = ENQUEUED; >>>> r.next = (head == null) ? r : head; >>>> head = r; >>>> >>>> Both stores are volatile. >>>> >>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>> forEach iteration method with no concrete logic. >>>>>> >>>>>> It would be possible to encapsulate the entire logic into a special >>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>> static method(s) (printFinalizationQueue)... You could just expose a >>>>>> package-private forEach static method from Finalizer and code the >>>>>> rest in DiagnosticCommands. >>>>> That's good for encapsulation. But I'm concerned that if "forEach" got >>>>> exposed beyond careful use in DiagnosticCommands, and the Referents >>>>> were leaked back into the heap, then we could get unexpected object >>>>> resurrection after finalization. This isn't a bug on it's own - any >>>>> finalizer might resurrect its object if not careful, but ordinarily >>>>> /only/ the finalizer could resurrect the object. This could invalidate >>>>> application invariants? >>>> Well, it all stays in the confines of package-private API - internal to >>>> JDK. Any future additional use should be reviewed carefully. Comments on >>>> the forEach() method should warn about that. >>>> >>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>> /another/ case of diagnostics affecting application behavior. And >>>>> there are pathological scenarios where this gets severe. This is >>>>> unfortunate but not uncommon. There is enough complication here that >>>>> you should be sure that the fix for diagnostics performance doesn't >>>>> introduce subtle bugs to the system in general. A change in this area >>>>> should get a thorough review from both the runtime and GC sides. >>>> Is the webrev.02 proposed above more acceptable in that respect? It does >>>> not introduce any logical changes to existing code. >>>> >>>>> Better yet, the reference handling code in GC and runtime should >>>>> probably be thrown out and re-written, but that's another issue :-) >>>> I may have some proposals in that direction. Stay tuned. >>>> >>>> Regards, Peter >>>> >>>>> - Derek >>>>> >>>>>> Regards, Peter >>>>>> >>>>>> >>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>> Everybody, >>>>>>> >>>>>>> Updated version: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>> >>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>> >>>>>>> -Dmitry >>>>>>> >>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>> Hi Dmitry, Staffan, >>>>>>>> >>>>>>>> Lots of good comments here. >>>>>>>> >>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>> general iterator and lambda. >>>>>>>> >>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>> >>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>> >>>>>>>> The sorting suggestion is a nice touch. >>>>>>>> >>>>>>>> - Derek White, GC team >>>>>>>> >>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>> >>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>> Dmitry, >>>>>>>>>> >>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>> >>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>> running out of memory. >>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>> >>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>> interfere with synchronization? >>>>>>>>> >>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>> >>>>>>>>> private void remove() { >>>>>>>>> synchronized (lock) { >>>>>>>>> if (unfinalized == this) { >>>>>>>>> if (this.next != null) { >>>>>>>>> unfinalized = this.next; >>>>>>>>> } else { >>>>>>>>> unfinalized = this.prev; >>>>>>>>> } >>>>>>>>> } >>>>>>>>> if (this.next != null) { >>>>>>>>> this.next.prev = this.prev; >>>>>>>>> } >>>>>>>>> if (this.prev != null) { >>>>>>>>> this.prev.next = this.next; >>>>>>>>> } >>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>> traverse the list unsynchronized >>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>> finalized */ >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>> pointer could be used instead: >>>>>>>>> >>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>> return (prev == this); >>>>>>>>> } >>>>>>>>> >>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>> >>>>>>>>> private void add() { >>>>>>>>> synchronized (lock) { >>>>>>>>> if (unfinalized != null) { >>>>>>>>> this.next = unfinalized; >>>>>>>>> unfinalized.prev = this; >>>>>>>>> } >>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>> // instance fully initialized >>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>> U.storeFence(); >>>>>>>>> unfinalized = this; >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> >>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>> >>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>> out? >>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>> two purposes: >>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>> >>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>> finalize() method. >>>>>>>>> >>>>>>>>> Regards, Peter >>>>>>>>> >>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>> >>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>> permission() and limit access: >>>>>>>>>> >>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>> "monitor", NULL}; >>>>>>>>>> return p; >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>> >>>>>>>>>> Thanks, >>>>>>>>>> /Staffan >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> Everyone, >>>>>>>>>>> >>>>>>>>>>> Please review the fix: >>>>>>>>>>> >>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>> >>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>> >>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>> with count >>>>>>>>>>> >>>>>>>>>>> -Dmitry >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>> * I would love to change the world, but they won't give me the sources. >> > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From martinrb at google.com Fri May 15 20:42:55 2015 From: martinrb at google.com (Martin Buchholz) Date: Fri, 15 May 2015 13:42:55 -0700 Subject: RFR(s): 8078463: optimize java/util/Map/Collisions.java In-Reply-To: <555509CE.3000005@oracle.com> References: <5553FE06.40006@oracle.com> <55545B62.1050608@oracle.com> <555509CE.3000005@oracle.com> Message-ID: Go ahead and push. (Optimizing test runs is pretty important long term) On Thu, May 14, 2015 at 1:47 PM, Stuart Marks wrote: > On 5/14/15 1:22 AM, Daniel Fuchs wrote: > >> I'm curious: have you tried with using a lambda instead? changing: >> >> 394 static void check(String desc, boolean cond) { >> 395 if (cond) { >> 396 pass(); >> 397 } else { >> 398 fail(desc); >> 399 } >> 400 } >> >> into >> >> static void check(Supplier descSupplier, boolean cond) { >> if (cond) { >> pass(); >> } else { >> fail(descSupplier.get()) >> } >> } >> >> I wonder how the performance would compare... >> > > I hadn't tried this, but I did out of curiosity. It's not very good. Here > are the numbers: > > (current jdk9-dev, -Xcomp -XX:+DeoptimizeALot -client, 3GHz i7, MBP 13" > 2014, elapsed time in seconds, averaged over five runs) > > 21.4 original > 18.7 lambda > 14.2 varargs > 12.3 multiple overloads (proposed version) > > I'm not too surprised. The lambda calls will look something like this: > > check(() -> String.format("map expected size m%d != k%d", map.size(), > keys.length), > map.size() == keys.length); > > Although the string formatting itself isn't performed unless the assertion > fails, this is pretty much the worst case scenario for lambda. Every lambda > is a capturing lambda, so the metafactory has to create a new lambda > instance every time. However, the lambda itself is never actually called. > That adds a lot of overhead. > > In addition, there are several cases where the captured variables aren't > effectively final, so I had to copy them into local variables and capture > those instead. This was merely annoying, but it's a inconvenient and it > adds a bit of clutter. > > Anyway, good idea, but lambda didn't really work for this. I'm going to > push my original patch. > > s'marks > From derek.white at oracle.com Fri May 15 22:46:32 2015 From: derek.white at oracle.com (Derek White) Date: Fri, 15 May 2015 18:46:32 -0400 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <555453BA.2070205@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> Message-ID: <55567748.6020304@oracle.com> Hi Peter, Some comments below... On 5/14/15 3:50 AM, Peter Levart wrote: > Hi Derek, > > On 05/13/2015 10:34 PM, Derek White wrote: >> Hi Peter, >> >> I don't have smoking gun evidence that your change introduces a bug, >> but I have some concerns... > > I did have a concern too, ... > >> >> On 5/12/15 6:05 PM, Peter Levart wrote: >>> Hi Dmitry, >>> >>> You iterate the queue then, not the unfinalized list. That's more >>> logical. >>> >>> Holding the queue's lock may pause reference handler and finalizer >>> threads for the entire time of iteration. This can blow up the >>> application. Suppose one wants to diagnose the application because >>> he suspects that finalizer thread hardly keeps up with production of >>> finalizable instances. This can happen if the allocation rate of >>> finalizable objects is very high and/or finalize() methods are not >>> coded to be fast enough. Suppose the queue of Finalizer(s) builds up >>> gradually and is already holding several million objects. Now you >>> initiate the diagnostic command to print the queue. The iteration >>> over and grouping/counting of several millions of Finalizer(s) takes >>> some time. This blocks finalizer thread and reference handler >>> thread. But does not block the threads that allocate finalizable >>> objects. By the time the iteration is over, the JVM blows up and >>> application slows down to a halt doing GCs most of the time, getting >>> OOMEs, etc... >>> >>> It is possible to iterate the elements of the queue for diagnostic >>> purposes without holding a lock. The modification required to do >>> that is the following (havent tested this, but I think it should work): >>> >>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>> >> One issue to watch out for is the garbage collectors inspect the >> Reference.next field from C code directly (to distinguish active vs. >> pending, iterate over oops, etc.). You can search hotspot for >> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >> >> Your change makes "inactive" References superficially look like >> "enqueued" References. The GC code is rather subtle and I haven't yet >> seen a case where it would get confused by this change, but there >> could easily be something like that lurking in the GC code. > > ...but then I thought that GC can in no way treat a Reference > differently whether it is still enqueued in a ReferenceQueue or > already dequeued (inactive) - responsibility is already on the Java > side. Currently the definition of Reference.next is this: > > /* When active: NULL > * pending: this > * Enqueued: next reference in queue (or this if last) > * Inactive: this > */ > @SuppressWarnings("rawtypes") > Reference next; > > We see that, unless GC inspects all ReferenceQueue instances and scans > their lists too, the state of a Reference that is enqueued as last in > list is indistinguishable from the state of inactive Reference. So I > deduced that this distinction (enqueued/inactive) can't be established > solely on the value of .next field ( == this or != this)... > > But I should inspect the GC code too to build a better understanding > of that part of the story... > > Anyway. It turns out that there is already enough state in Reference > to destinguish between it being enqueued as last in list and already > dequeued (inactive) - the additional state is Reference.queue that > transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in > ReferenceQueue.reallyPoll. We need to just make sure the two fields > (r.next and r.queue) are assigned and read in correct order. This can > be achieved either by making Reference.next a volatile field or by a > couple of explicit fences: > > http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ > > The assignment of r.queue to ReferenceQueue.ENQUEUED already happens > before linking the reference into the queue's head in > ReferenceQueue.enqueue(): > > r.queue = ENQUEUED; > r.next = (head == null) ? r : head; > head = r; > > Both stores are volatile. This sounds a bit better. I don't have a good handle on the pros and cons of a volatile field over explicit fences via Unsafe in this case. Kim might jump in soon. I'd like to suggest an entirely less-clever solution. Since the problem is that forEach() might see inconsistent values for the queue and next fields of a Reference, but we don't want to grab a lock walking the whole queue, we could instead grab the lock as we look at each Reference (and do the "back-up" trick if we were interfered with). Of course this is slower than going lock-free, but it's not any more overhead than the ReferenceHandler thread or FinalizerThreads incur. The only benefit of this solution over the others is that it is less clever, and I'm not sure how much cleverness this problem deserves. Given that, and ranking the solutions as "lock" < (clever) "volatile" < "fence", I'd be happier with the "volatile" or "lock" solution if that is sufficient. - Derek >> >>> I also suggest the addition to the ReferenceQueue to be contained >>> (package-private) and as generic as possible. That's why I suggest >>> forEach iteration method with no concrete logic. >>> >>> It would be possible to encapsulate the entire logic into a special >>> package-private class (say java.lang.ref.DiagnosticCommands) with >>> static method(s) (printFinalizationQueue)... You could just expose a >>> package-private forEach static method from Finalizer and code the >>> rest in DiagnosticCommands. >> That's good for encapsulation. But I'm concerned that if "forEach" >> got exposed beyond careful use in DiagnosticCommands, and the >> Referents were leaked back into the heap, then we could get >> unexpected object resurrection after finalization. This isn't a bug >> on it's own - any finalizer might resurrect its object if not >> careful, but ordinarily /only/ the finalizer could resurrect the >> object. This could invalidate application invariants? > > Well, it all stays in the confines of package-private API - internal > to JDK. Any future additional use should be reviewed carefully. > Comments on the forEach() method should warn about that. > >> >> I agree that using a lock over the ReferenceQueue iteration opens up >> /another/ case of diagnostics affecting application behavior. And >> there are pathological scenarios where this gets severe. This is >> unfortunate but not uncommon. There is enough complication here that >> you should be sure that the fix for diagnostics performance doesn't >> introduce subtle bugs to the system in general. A change in this area >> should get a thorough review from both the runtime and GC sides. > > Is the webrev.02 proposed above more acceptable in that respect? It > does not introduce any logical changes to existing code. > >> >> Better yet, the reference handling code in GC and runtime should >> probably be thrown out and re-written, but that's another issue :-) > > I may have some proposals in that direction. Stay tuned. > > Regards, Peter > >> >> - Derek >> >>> Regards, Peter >>> >>> >>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>> Everybody, >>>> >>>> Updated version: >>>> >>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>> >>>> Now it iterates over queue and output result sorted by number of instances. >>>> >>>> -Dmitry >>>> >>>> On 2015-05-07 00:51, Derek White wrote: >>>>> Hi Dmitry, Staffan, >>>>> >>>>> Lots of good comments here. >>>>> >>>>> On the topic of what list should be printed out, I think we should focus >>>>> on objects waiting to be finalized - e.g. the contents of the >>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>> could add a summerizeQueue(TreeMap) method, or a >>>>> general iterator and lambda. >>>>> >>>>> A histogram of objects with finalize methods might also be interesting, >>>>> but you can get most of the same information from a heap histogram >>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>> >>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>> that runs after GC that sorts found References objects that need >>>>> processing into their respective ReferenceQueues). But locking the >>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>> >>>>> The sorting suggestion is a nice touch. >>>>> >>>>> - Derek White, GC team >>>>> >>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>> Hi Dmitry, Staffan, >>>>>> >>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>> Dmitry, >>>>>>> >>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>> well considering the changes to Finalizer. >>>>>>> >>>>>>> I?m a little worried about the potentially very large String that is >>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>> That would allow for outputting one line at a time. The output would >>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>> running out of memory. >>>>>> If the output is just a histogram of # of instances per class name, >>>>>> then it should not be too large, as there are not many different >>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>> finalize() method in the whole jdk/src tree). >>>>>> >>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>> acceptable for diagnostic output to impact performance and/or >>>>>> interfere with synchronization? >>>>>> >>>>>> It might be possible to scan the list without holding a lock for >>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>> Finalizer.next pointer to point back to itself: >>>>>> >>>>>> private void remove() { >>>>>> synchronized (lock) { >>>>>> if (unfinalized == this) { >>>>>> if (this.next != null) { >>>>>> unfinalized = this.next; >>>>>> } else { >>>>>> unfinalized = this.prev; >>>>>> } >>>>>> } >>>>>> if (this.next != null) { >>>>>> this.next.prev = this.prev; >>>>>> } >>>>>> if (this.prev != null) { >>>>>> this.prev.next = this.next; >>>>>> } >>>>>> // this.next = this; must not be set so that we can >>>>>> traverse the list unsynchronized >>>>>> this.prev = this; /* Indicates that this has been >>>>>> finalized */ >>>>>> } >>>>>> } >>>>>> >>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>> pointer could be used instead: >>>>>> >>>>>> private boolean hasBeenFinalized() { >>>>>> return (prev == this); >>>>>> } >>>>>> >>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>> >>>>>> private void add() { >>>>>> synchronized (lock) { >>>>>> if (unfinalized != null) { >>>>>> this.next = unfinalized; >>>>>> unfinalized.prev = this; >>>>>> } >>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>> // instance fully initialized >>>>>> // (in particular the 'next' pointer) >>>>>> U.storeFence(); >>>>>> unfinalized = this; >>>>>> } >>>>>> } >>>>>> >>>>>> >>>>>> By doing these modifications, I think you can remove >>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>> >>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>> out? >>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>> instances pending processing by finalizer thread because their >>>>>> referents are eligible for finalization (they are not reachable any >>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>> instances for which their referents have not been finalized yet >>>>>> (including those that are still reachable and alive). The later serves >>>>>> two purposes: >>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>> - it is a source of unfinalized instances for >>>>>> running-finalizers-on-exit if requested by >>>>>> System.runFinalizersOnExit(true); >>>>>> >>>>>> So it really depends on what one would like to see. Showing the queue >>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>> list may be interesting if one wants to know how many live + >>>>>> finalization pending instances are there on the heap that override >>>>>> finalize() method. >>>>>> >>>>>> Regards, Peter >>>>>> >>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>> (see the old code again) would also make it easier to digest. >>>>>>> >>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>> permission() and limit access: >>>>>>> >>>>>>> static const JavaPermission permission() { >>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>> "monitor", NULL}; >>>>>>> return p; >>>>>>> } >>>>>>> >>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>> the finalizer queue? Hmm. >>>>>>> >>>>>>> Thanks, >>>>>>> /Staffan >>>>>>> >>>>>>> >>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>> wrote: >>>>>>>> >>>>>>>> Everyone, >>>>>>>> >>>>>>>> Please review the fix: >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>> >>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>> >>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>> with count >>>>>>>> >>>>>>>> -Dmitry >>>>>>>> >>>>>>>> -- >>>>>>>> Dmitry Samersoff >>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>> * I would love to change the world, but they won't give me the sources. >>> >> > From derek.white at oracle.com Fri May 15 22:59:52 2015 From: derek.white at oracle.com (Derek White) Date: Fri, 15 May 2015 18:59:52 -0400 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55567748.6020304@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> Message-ID: <55567A68.9020802@oracle.com> Hi Dmitry, Peter, I should read my email more frequently - I missed Dmitry's last webrev email. My comments on a preference for volatile over Unsafe are not a strong objection to using Unsafe fences. I just don't have enough experience with Unsafe fences yet to agree that this use is correct. While looking over this Reference code I found 3-6 really simple things that need cleaning up that have been there for years, so I'm not a big cheerleader for more complicated things here :-) - Derek On 5/15/15 6:46 PM, Derek White wrote: > Hi Peter, > > Some comments below... > > On 5/14/15 3:50 AM, Peter Levart wrote: >> Hi Derek, >> >> On 05/13/2015 10:34 PM, Derek White wrote: >>> Hi Peter, >>> >>> I don't have smoking gun evidence that your change introduces a bug, >>> but I have some concerns... >> >> I did have a concern too, ... >> >>> >>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>> Hi Dmitry, >>>> >>>> You iterate the queue then, not the unfinalized list. That's more >>>> logical. >>>> >>>> Holding the queue's lock may pause reference handler and finalizer >>>> threads for the entire time of iteration. This can blow up the >>>> application. Suppose one wants to diagnose the application because >>>> he suspects that finalizer thread hardly keeps up with production >>>> of finalizable instances. This can happen if the allocation rate of >>>> finalizable objects is very high and/or finalize() methods are not >>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>> up gradually and is already holding several million objects. Now >>>> you initiate the diagnostic command to print the queue. The >>>> iteration over and grouping/counting of several millions of >>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>> reference handler thread. But does not block the threads that >>>> allocate finalizable objects. By the time the iteration is over, >>>> the JVM blows up and application slows down to a halt doing GCs >>>> most of the time, getting OOMEs, etc... >>>> >>>> It is possible to iterate the elements of the queue for diagnostic >>>> purposes without holding a lock. The modification required to do >>>> that is the following (havent tested this, but I think it should work): >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>> >>> One issue to watch out for is the garbage collectors inspect the >>> Reference.next field from C code directly (to distinguish active vs. >>> pending, iterate over oops, etc.). You can search hotspot for >>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>> >>> Your change makes "inactive" References superficially look like >>> "enqueued" References. The GC code is rather subtle and I haven't >>> yet seen a case where it would get confused by this change, but >>> there could easily be something like that lurking in the GC code. >> >> ...but then I thought that GC can in no way treat a Reference >> differently whether it is still enqueued in a ReferenceQueue or >> already dequeued (inactive) - responsibility is already on the Java >> side. Currently the definition of Reference.next is this: >> >> /* When active: NULL >> * pending: this >> * Enqueued: next reference in queue (or this if last) >> * Inactive: this >> */ >> @SuppressWarnings("rawtypes") >> Reference next; >> >> We see that, unless GC inspects all ReferenceQueue instances and >> scans their lists too, the state of a Reference that is enqueued as >> last in list is indistinguishable from the state of inactive >> Reference. So I deduced that this distinction (enqueued/inactive) >> can't be established solely on the value of .next field ( == this or >> != this)... >> >> But I should inspect the GC code too to build a better understanding >> of that part of the story... >> >> Anyway. It turns out that there is already enough state in Reference >> to destinguish between it being enqueued as last in list and already >> dequeued (inactive) - the additional state is Reference.queue that >> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >> ReferenceQueue.reallyPoll. We need to just make sure the two fields >> (r.next and r.queue) are assigned and read in correct order. This can >> be achieved either by making Reference.next a volatile field or by a >> couple of explicit fences: >> >> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >> >> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >> before linking the reference into the queue's head in >> ReferenceQueue.enqueue(): >> >> r.queue = ENQUEUED; >> r.next = (head == null) ? r : head; >> head = r; >> >> Both stores are volatile. > > This sounds a bit better. I don't have a good handle on the pros and > cons of a volatile field over explicit fences via Unsafe in this case. > Kim might jump in soon. > > I'd like to suggest an entirely less-clever solution. Since the > problem is that forEach() might see inconsistent values for the queue > and next fields of a Reference, but we don't want to grab a lock > walking the whole queue, we could instead grab the lock as we look at > each Reference (and do the "back-up" trick if we were interfered > with). Of course this is slower than going lock-free, but it's not any > more overhead than the ReferenceHandler thread or FinalizerThreads incur. > > The only benefit of this solution over the others is that it is less > clever, and I'm not sure how much cleverness this problem deserves. > Given that, and ranking the solutions as "lock" < (clever) "volatile" > < "fence", I'd be happier with the "volatile" or "lock" solution if > that is sufficient. > > - Derek >>> >>>> I also suggest the addition to the ReferenceQueue to be contained >>>> (package-private) and as generic as possible. That's why I suggest >>>> forEach iteration method with no concrete logic. >>>> >>>> It would be possible to encapsulate the entire logic into a special >>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>> static method(s) (printFinalizationQueue)... You could just expose >>>> a package-private forEach static method from Finalizer and code the >>>> rest in DiagnosticCommands. >>> That's good for encapsulation. But I'm concerned that if "forEach" >>> got exposed beyond careful use in DiagnosticCommands, and the >>> Referents were leaked back into the heap, then we could get >>> unexpected object resurrection after finalization. This isn't a bug >>> on it's own - any finalizer might resurrect its object if not >>> careful, but ordinarily /only/ the finalizer could resurrect the >>> object. This could invalidate application invariants? >> >> Well, it all stays in the confines of package-private API - internal >> to JDK. Any future additional use should be reviewed carefully. >> Comments on the forEach() method should warn about that. >> >>> >>> I agree that using a lock over the ReferenceQueue iteration opens up >>> /another/ case of diagnostics affecting application behavior. And >>> there are pathological scenarios where this gets severe. This is >>> unfortunate but not uncommon. There is enough complication here that >>> you should be sure that the fix for diagnostics performance doesn't >>> introduce subtle bugs to the system in general. A change in this >>> area should get a thorough review from both the runtime and GC sides. >> >> Is the webrev.02 proposed above more acceptable in that respect? It >> does not introduce any logical changes to existing code. >> >>> >>> Better yet, the reference handling code in GC and runtime should >>> probably be thrown out and re-written, but that's another issue :-) >> >> I may have some proposals in that direction. Stay tuned. >> >> Regards, Peter >> >>> >>> - Derek >>> >>>> Regards, Peter >>>> >>>> >>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>> Everybody, >>>>> >>>>> Updated version: >>>>> >>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>> >>>>> Now it iterates over queue and output result sorted by number of instances. >>>>> >>>>> -Dmitry >>>>> >>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>> Hi Dmitry, Staffan, >>>>>> >>>>>> Lots of good comments here. >>>>>> >>>>>> On the topic of what list should be printed out, I think we should focus >>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>> general iterator and lambda. >>>>>> >>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>> but you can get most of the same information from a heap histogram >>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>> >>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>> that runs after GC that sorts found References objects that need >>>>>> processing into their respective ReferenceQueues). But locking the >>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>> >>>>>> The sorting suggestion is a nice touch. >>>>>> >>>>>> - Derek White, GC team >>>>>> >>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>> Hi Dmitry, Staffan, >>>>>>> >>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>> Dmitry, >>>>>>>> >>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>> well considering the changes to Finalizer. >>>>>>>> >>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>> running out of memory. >>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>> then it should not be too large, as there are not many different >>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>> finalize() method in the whole jdk/src tree). >>>>>>> >>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>> interfere with synchronization? >>>>>>> >>>>>>> It might be possible to scan the list without holding a lock for >>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>> Finalizer.next pointer to point back to itself: >>>>>>> >>>>>>> private void remove() { >>>>>>> synchronized (lock) { >>>>>>> if (unfinalized == this) { >>>>>>> if (this.next != null) { >>>>>>> unfinalized = this.next; >>>>>>> } else { >>>>>>> unfinalized = this.prev; >>>>>>> } >>>>>>> } >>>>>>> if (this.next != null) { >>>>>>> this.next.prev = this.prev; >>>>>>> } >>>>>>> if (this.prev != null) { >>>>>>> this.prev.next = this.next; >>>>>>> } >>>>>>> // this.next = this; must not be set so that we can >>>>>>> traverse the list unsynchronized >>>>>>> this.prev = this; /* Indicates that this has been >>>>>>> finalized */ >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>> pointer could be used instead: >>>>>>> >>>>>>> private boolean hasBeenFinalized() { >>>>>>> return (prev == this); >>>>>>> } >>>>>>> >>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>> >>>>>>> private void add() { >>>>>>> synchronized (lock) { >>>>>>> if (unfinalized != null) { >>>>>>> this.next = unfinalized; >>>>>>> unfinalized.prev = this; >>>>>>> } >>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>> // instance fully initialized >>>>>>> // (in particular the 'next' pointer) >>>>>>> U.storeFence(); >>>>>>> unfinalized = this; >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> >>>>>>> By doing these modifications, I think you can remove >>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>> >>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>> out? >>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>> instances pending processing by finalizer thread because their >>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>> instances for which their referents have not been finalized yet >>>>>>> (including those that are still reachable and alive). The later serves >>>>>>> two purposes: >>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>> - it is a source of unfinalized instances for >>>>>>> running-finalizers-on-exit if requested by >>>>>>> System.runFinalizersOnExit(true); >>>>>>> >>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>> list may be interesting if one wants to know how many live + >>>>>>> finalization pending instances are there on the heap that override >>>>>>> finalize() method. >>>>>>> >>>>>>> Regards, Peter >>>>>>> >>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>> >>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>> permission() and limit access: >>>>>>>> >>>>>>>> static const JavaPermission permission() { >>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>> "monitor", NULL}; >>>>>>>> return p; >>>>>>>> } >>>>>>>> >>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>> the finalizer queue? Hmm. >>>>>>>> >>>>>>>> Thanks, >>>>>>>> /Staffan >>>>>>>> >>>>>>>> >>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>> Everyone, >>>>>>>>> >>>>>>>>> Please review the fix: >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>> >>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>> >>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>> with count >>>>>>>>> >>>>>>>>> -Dmitry >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dmitry Samersoff >>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>> * I would love to change the world, but they won't give me the sources. >>>> >>> >> > From ivan.gerasimov at oracle.com Fri May 15 23:01:31 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sat, 16 May 2015 02:01:31 +0300 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal Message-ID: <55567ACB.2050307@oracle.com> Hello! When constructing the map, the expected size is specified to be 256, but then 510 elements are inserted. A new whitebox test is provided, so the next time the number of entries grows, the expected size will not be forgotten. Would you please help review this fix? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8080535 WEBREV: http://cr.openjdk.java.net/~igerasim/8080535/00/webrev/ Sincerely yours, Ivan From martinrb at google.com Fri May 15 23:18:30 2015 From: martinrb at google.com (Martin Buchholz) Date: Fri, 15 May 2015 16:18:30 -0700 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: <55567ACB.2050307@oracle.com> References: <55567ACB.2050307@oracle.com> Message-ID: I don't think you're taking the load factor into account. https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/collect/Maps.java?r=f8144b4df7eec5f1c9e6942d8d5ef734a8767fd9#110 You want to check (via reflection) that the size of the backing array is unchanged if you copy the map with new HashMap(map). I wouldn't bother defining the constant. On Fri, May 15, 2015 at 4:01 PM, Ivan Gerasimov wrote: > Hello! > > When constructing the map, the expected size is specified to be 256, but > then 510 elements are inserted. > A new whitebox test is provided, so the next time the number of entries > grows, the expected size will not be forgotten. > > Would you please help review this fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8080535 > WEBREV: http://cr.openjdk.java.net/~igerasim/8080535/00/webrev/ > > Sincerely yours, > Ivan > From jeremymanson at google.com Sat May 16 00:34:57 2015 From: jeremymanson at google.com (Jeremy Manson) Date: Fri, 15 May 2015 17:34:57 -0700 Subject: JEP 254: Compact Strings In-Reply-To: <20150514230513.0363C62D05@eggemoggin.niobe.net> References: <20150514230513.0363C62D05@eggemoggin.niobe.net> Message-ID: So, I'm pretty dubious, mostly because of the risks mentioned in the JEP. If you need a flag-check and two code paths for every String method, that's going to make the String class more slow and bloated, and make it very difficult for the JIT compiler to do its job inlining and intrinsifying calls to String methods. At Google, we spent a fair bit of time last year climbing out of the performance hole that trimming substrings dropped us into - we had a fair bit of code that was based around substrings being approximately memory-neutral, and it cost us a lot of GC overhead and rewriting to make the change. The JDK itself still has exposed APIs that make tradeoffs based on cheap substrings (the URL(String) constructor does a lot of this, for example). The proposed change here has the potential of doing the opposite with most String operations - trading off less GC overhead for more mutator cost. But String operations are a pretty big chunk of CPU time, on the whole. Does anyone really have a sense of how to make this kind of decision? The JEP seems mostly to be hoping that other organizations will do the testing for you. (I agree that it is worth doing some experimentation in this area, but I wanted to say this early, because if I could reach back in time and tell you *not* to make the substring change, I would. We seriously considered simply backing it out locally, but it would have been a lot of effort for us to maintain that kind of patch, and we didn't want our performance tradeoffs to be that much different from the stock JDK's.) Jeremy On Thu, May 14, 2015 at 4:05 PM, wrote: > New JEP Candidate: http://openjdk.java.net/jeps/254 > > - Mark > From stuart.marks at oracle.com Sat May 16 00:37:01 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 15 May 2015 17:37:01 -0700 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator Message-ID: <5556912D.2020000@oracle.com> Hi all, Please review this small API enhancement to add a default method "asIterator()" to Enumeration that converts it into an Iterator. Webrev: http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ Bug: https://bugs.openjdk.java.net/browse/JDK-8072726 Thanks, s'marks From ivan.gerasimov at oracle.com Sat May 16 00:59:57 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sat, 16 May 2015 03:59:57 +0300 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: References: <55567ACB.2050307@oracle.com> Message-ID: <5556968D.9070401@oracle.com> On 16.05.2015 2:18, Martin Buchholz wrote: > I don't think you're taking the load factor into account. Hm. You're right, HashMap's constructor expects the capacity as the argument. I was confused by IdentityHashMap, whose constructor expects the maximum number of elements to be inserted. > https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/collect/Maps.java?r=f8144b4df7eec5f1c9e6942d8d5ef734a8767fd9#110 > You want to check (via reflection) that the size of the backing array > is unchanged if you copy the map with new HashMap(map). > Sorry, I didn't get it. How could we detect that the initial capacity wasn't big enough, if we hadn't stored it? > I wouldn't bother defining the constant. > I only need it in the regression test, to check whether it was sufficient. Here's the updated webrev: http://cr.openjdk.java.net/~igerasim/8080535/01/webrev/ Comments, suggestions are welcome! Sincerely yours, Ivan > On Fri, May 15, 2015 at 4:01 PM, Ivan Gerasimov > > wrote: > > Hello! > > When constructing the map, the expected size is specified to be > 256, but then 510 elements are inserted. > A new whitebox test is provided, so the next time the number of > entries grows, the expected size will not be forgotten. > > Would you please help review this fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8080535 > WEBREV: http://cr.openjdk.java.net/~igerasim/8080535/00/webrev/ > > > Sincerely yours, > Ivan > > From dmitry.samersoff at oracle.com Sat May 16 07:35:39 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Sat, 16 May 2015 10:35:39 +0300 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55567A68.9020802@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> Message-ID: <5556F34B.5050701@oracle.com> Derek, Personally, I'm for volatile over explicit fence too. So I'll change the code if Peter don't have objections. -Dmitry On 2015-05-16 01:59, Derek White wrote: > Hi Dmitry, Peter, > > I should read my email more frequently - I missed Dmitry's last webrev > email. > > My comments on a preference for volatile over Unsafe are not a strong > objection to using Unsafe fences. I just don't have enough experience > with Unsafe fences yet to agree that this use is correct. > > While looking over this Reference code I found 3-6 really simple things > that need cleaning up that have been there for years, so I'm not a big > cheerleader for more complicated things here :-) > > - Derek > > On 5/15/15 6:46 PM, Derek White wrote: >> Hi Peter, >> >> Some comments below... >> >> On 5/14/15 3:50 AM, Peter Levart wrote: >>> Hi Derek, >>> >>> On 05/13/2015 10:34 PM, Derek White wrote: >>>> Hi Peter, >>>> >>>> I don't have smoking gun evidence that your change introduces a bug, >>>> but I have some concerns... >>> >>> I did have a concern too, ... >>> >>>> >>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>> Hi Dmitry, >>>>> >>>>> You iterate the queue then, not the unfinalized list. That's more >>>>> logical. >>>>> >>>>> Holding the queue's lock may pause reference handler and finalizer >>>>> threads for the entire time of iteration. This can blow up the >>>>> application. Suppose one wants to diagnose the application because >>>>> he suspects that finalizer thread hardly keeps up with production >>>>> of finalizable instances. This can happen if the allocation rate of >>>>> finalizable objects is very high and/or finalize() methods are not >>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>>> up gradually and is already holding several million objects. Now >>>>> you initiate the diagnostic command to print the queue. The >>>>> iteration over and grouping/counting of several millions of >>>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>>> reference handler thread. But does not block the threads that >>>>> allocate finalizable objects. By the time the iteration is over, >>>>> the JVM blows up and application slows down to a halt doing GCs >>>>> most of the time, getting OOMEs, etc... >>>>> >>>>> It is possible to iterate the elements of the queue for diagnostic >>>>> purposes without holding a lock. The modification required to do >>>>> that is the following (havent tested this, but I think it should work): >>>>> >>>>> >>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>> >>>> One issue to watch out for is the garbage collectors inspect the >>>> Reference.next field from C code directly (to distinguish active vs. >>>> pending, iterate over oops, etc.). You can search hotspot for >>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>> >>>> Your change makes "inactive" References superficially look like >>>> "enqueued" References. The GC code is rather subtle and I haven't >>>> yet seen a case where it would get confused by this change, but >>>> there could easily be something like that lurking in the GC code. >>> >>> ...but then I thought that GC can in no way treat a Reference >>> differently whether it is still enqueued in a ReferenceQueue or >>> already dequeued (inactive) - responsibility is already on the Java >>> side. Currently the definition of Reference.next is this: >>> >>> /* When active: NULL >>> * pending: this >>> * Enqueued: next reference in queue (or this if last) >>> * Inactive: this >>> */ >>> @SuppressWarnings("rawtypes") >>> Reference next; >>> >>> We see that, unless GC inspects all ReferenceQueue instances and >>> scans their lists too, the state of a Reference that is enqueued as >>> last in list is indistinguishable from the state of inactive >>> Reference. So I deduced that this distinction (enqueued/inactive) >>> can't be established solely on the value of .next field ( == this or >>> != this)... >>> >>> But I should inspect the GC code too to build a better understanding >>> of that part of the story... >>> >>> Anyway. It turns out that there is already enough state in Reference >>> to destinguish between it being enqueued as last in list and already >>> dequeued (inactive) - the additional state is Reference.queue that >>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>> (r.next and r.queue) are assigned and read in correct order. This can >>> be achieved either by making Reference.next a volatile field or by a >>> couple of explicit fences: >>> >>> >>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>> >>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>> before linking the reference into the queue's head in >>> ReferenceQueue.enqueue(): >>> >>> r.queue = ENQUEUED; >>> r.next = (head == null) ? r : head; >>> head = r; >>> >>> Both stores are volatile. >> >> This sounds a bit better. I don't have a good handle on the pros and >> cons of a volatile field over explicit fences via Unsafe in this case. >> Kim might jump in soon. >> >> I'd like to suggest an entirely less-clever solution. Since the >> problem is that forEach() might see inconsistent values for the queue >> and next fields of a Reference, but we don't want to grab a lock >> walking the whole queue, we could instead grab the lock as we look at >> each Reference (and do the "back-up" trick if we were interfered >> with). Of course this is slower than going lock-free, but it's not any >> more overhead than the ReferenceHandler thread or FinalizerThreads incur. >> >> The only benefit of this solution over the others is that it is less >> clever, and I'm not sure how much cleverness this problem deserves. >> Given that, and ranking the solutions as "lock" < (clever) "volatile" >> < "fence", I'd be happier with the "volatile" or "lock" solution if >> that is sufficient. >> >> - Derek >>>> >>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>> (package-private) and as generic as possible. That's why I suggest >>>>> forEach iteration method with no concrete logic. >>>>> >>>>> It would be possible to encapsulate the entire logic into a special >>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>> static method(s) (printFinalizationQueue)... You could just expose >>>>> a package-private forEach static method from Finalizer and code the >>>>> rest in DiagnosticCommands. >>>> That's good for encapsulation. But I'm concerned that if "forEach" >>>> got exposed beyond careful use in DiagnosticCommands, and the >>>> Referents were leaked back into the heap, then we could get >>>> unexpected object resurrection after finalization. This isn't a bug >>>> on it's own - any finalizer might resurrect its object if not >>>> careful, but ordinarily /only/ the finalizer could resurrect the >>>> object. This could invalidate application invariants? >>> >>> Well, it all stays in the confines of package-private API - internal >>> to JDK. Any future additional use should be reviewed carefully. >>> Comments on the forEach() method should warn about that. >>> >>>> >>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>> /another/ case of diagnostics affecting application behavior. And >>>> there are pathological scenarios where this gets severe. This is >>>> unfortunate but not uncommon. There is enough complication here that >>>> you should be sure that the fix for diagnostics performance doesn't >>>> introduce subtle bugs to the system in general. A change in this >>>> area should get a thorough review from both the runtime and GC sides. >>> >>> Is the webrev.02 proposed above more acceptable in that respect? It >>> does not introduce any logical changes to existing code. >>> >>>> >>>> Better yet, the reference handling code in GC and runtime should >>>> probably be thrown out and re-written, but that's another issue :-) >>> >>> I may have some proposals in that direction. Stay tuned. >>> >>> Regards, Peter >>> >>>> >>>> - Derek >>>> >>>>> Regards, Peter >>>>> >>>>> >>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>> Everybody, >>>>>> >>>>>> Updated version: >>>>>> >>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>> >>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>> >>>>>> -Dmitry >>>>>> >>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>> Hi Dmitry, Staffan, >>>>>>> >>>>>>> Lots of good comments here. >>>>>>> >>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>> general iterator and lambda. >>>>>>> >>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>> but you can get most of the same information from a heap histogram >>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>> >>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>> that runs after GC that sorts found References objects that need >>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>> >>>>>>> The sorting suggestion is a nice touch. >>>>>>> >>>>>>> - Derek White, GC team >>>>>>> >>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>> Hi Dmitry, Staffan, >>>>>>>> >>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>> Dmitry, >>>>>>>>> >>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>> well considering the changes to Finalizer. >>>>>>>>> >>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>> running out of memory. >>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>> then it should not be too large, as there are not many different >>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>> >>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>> interfere with synchronization? >>>>>>>> >>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>> >>>>>>>> private void remove() { >>>>>>>> synchronized (lock) { >>>>>>>> if (unfinalized == this) { >>>>>>>> if (this.next != null) { >>>>>>>> unfinalized = this.next; >>>>>>>> } else { >>>>>>>> unfinalized = this.prev; >>>>>>>> } >>>>>>>> } >>>>>>>> if (this.next != null) { >>>>>>>> this.next.prev = this.prev; >>>>>>>> } >>>>>>>> if (this.prev != null) { >>>>>>>> this.prev.next = this.next; >>>>>>>> } >>>>>>>> // this.next = this; must not be set so that we can >>>>>>>> traverse the list unsynchronized >>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>> finalized */ >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>> pointer could be used instead: >>>>>>>> >>>>>>>> private boolean hasBeenFinalized() { >>>>>>>> return (prev == this); >>>>>>>> } >>>>>>>> >>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>> >>>>>>>> private void add() { >>>>>>>> synchronized (lock) { >>>>>>>> if (unfinalized != null) { >>>>>>>> this.next = unfinalized; >>>>>>>> unfinalized.prev = this; >>>>>>>> } >>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>> // instance fully initialized >>>>>>>> // (in particular the 'next' pointer) >>>>>>>> U.storeFence(); >>>>>>>> unfinalized = this; >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> By doing these modifications, I think you can remove >>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>> >>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>> out? >>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>> instances pending processing by finalizer thread because their >>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>> instances for which their referents have not been finalized yet >>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>> two purposes: >>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>> - it is a source of unfinalized instances for >>>>>>>> running-finalizers-on-exit if requested by >>>>>>>> System.runFinalizersOnExit(true); >>>>>>>> >>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>> finalization pending instances are there on the heap that override >>>>>>>> finalize() method. >>>>>>>> >>>>>>>> Regards, Peter >>>>>>>> >>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>> >>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>> permission() and limit access: >>>>>>>>> >>>>>>>>> static const JavaPermission permission() { >>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>> "monitor", NULL}; >>>>>>>>> return p; >>>>>>>>> } >>>>>>>>> >>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>> the finalizer queue? Hmm. >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> /Staffan >>>>>>>>> >>>>>>>>> >>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> Everyone, >>>>>>>>>> >>>>>>>>>> Please review the fix: >>>>>>>>>> >>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>> >>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>> >>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>> with count >>>>>>>>>> >>>>>>>>>> -Dmitry >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Dmitry Samersoff >>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>> * I would love to change the world, but they won't give me the sources. >>>>> >>>> >>> >> > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From peter.levart at gmail.com Sat May 16 12:38:09 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sat, 16 May 2015 14:38:09 +0200 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5556F34B.5050701@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> Message-ID: <55573A31.7050306@gmail.com> On 05/16/2015 09:35 AM, Dmitry Samersoff wrote: > Derek, > > Personally, I'm for volatile over explicit fence too. > > So I'll change the code if Peter don't have objections. There are no objections. There's one unneeded volatile store to .next field then in enqueue(), but it is followed by another volatile store, so there shouldn't be overhead on Intel and SPARC at least. Regards, Peter > -Dmitry > > On 2015-05-16 01:59, Derek White wrote: >> Hi Dmitry, Peter, >> >> I should read my email more frequently - I missed Dmitry's last webrev >> email. >> >> My comments on a preference for volatile over Unsafe are not a strong >> objection to using Unsafe fences. I just don't have enough experience >> with Unsafe fences yet to agree that this use is correct. >> >> While looking over this Reference code I found 3-6 really simple things >> that need cleaning up that have been there for years, so I'm not a big >> cheerleader for more complicated things here :-) >> >> - Derek >> >> On 5/15/15 6:46 PM, Derek White wrote: >>> Hi Peter, >>> >>> Some comments below... >>> >>> On 5/14/15 3:50 AM, Peter Levart wrote: >>>> Hi Derek, >>>> >>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>> Hi Peter, >>>>> >>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>> but I have some concerns... >>>> I did have a concern too, ... >>>> >>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>> Hi Dmitry, >>>>>> >>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>> logical. >>>>>> >>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>> threads for the entire time of iteration. This can blow up the >>>>>> application. Suppose one wants to diagnose the application because >>>>>> he suspects that finalizer thread hardly keeps up with production >>>>>> of finalizable instances. This can happen if the allocation rate of >>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>>>> up gradually and is already holding several million objects. Now >>>>>> you initiate the diagnostic command to print the queue. The >>>>>> iteration over and grouping/counting of several millions of >>>>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>>>> reference handler thread. But does not block the threads that >>>>>> allocate finalizable objects. By the time the iteration is over, >>>>>> the JVM blows up and application slows down to a halt doing GCs >>>>>> most of the time, getting OOMEs, etc... >>>>>> >>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>> purposes without holding a lock. The modification required to do >>>>>> that is the following (havent tested this, but I think it should work): >>>>>> >>>>>> >>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>> >>>>> One issue to watch out for is the garbage collectors inspect the >>>>> Reference.next field from C code directly (to distinguish active vs. >>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>> >>>>> Your change makes "inactive" References superficially look like >>>>> "enqueued" References. The GC code is rather subtle and I haven't >>>>> yet seen a case where it would get confused by this change, but >>>>> there could easily be something like that lurking in the GC code. >>>> ...but then I thought that GC can in no way treat a Reference >>>> differently whether it is still enqueued in a ReferenceQueue or >>>> already dequeued (inactive) - responsibility is already on the Java >>>> side. Currently the definition of Reference.next is this: >>>> >>>> /* When active: NULL >>>> * pending: this >>>> * Enqueued: next reference in queue (or this if last) >>>> * Inactive: this >>>> */ >>>> @SuppressWarnings("rawtypes") >>>> Reference next; >>>> >>>> We see that, unless GC inspects all ReferenceQueue instances and >>>> scans their lists too, the state of a Reference that is enqueued as >>>> last in list is indistinguishable from the state of inactive >>>> Reference. So I deduced that this distinction (enqueued/inactive) >>>> can't be established solely on the value of .next field ( == this or >>>> != this)... >>>> >>>> But I should inspect the GC code too to build a better understanding >>>> of that part of the story... >>>> >>>> Anyway. It turns out that there is already enough state in Reference >>>> to destinguish between it being enqueued as last in list and already >>>> dequeued (inactive) - the additional state is Reference.queue that >>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>> (r.next and r.queue) are assigned and read in correct order. This can >>>> be achieved either by making Reference.next a volatile field or by a >>>> couple of explicit fences: >>>> >>>> >>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>> >>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>> before linking the reference into the queue's head in >>>> ReferenceQueue.enqueue(): >>>> >>>> r.queue = ENQUEUED; >>>> r.next = (head == null) ? r : head; >>>> head = r; >>>> >>>> Both stores are volatile. >>> This sounds a bit better. I don't have a good handle on the pros and >>> cons of a volatile field over explicit fences via Unsafe in this case. >>> Kim might jump in soon. >>> >>> I'd like to suggest an entirely less-clever solution. Since the >>> problem is that forEach() might see inconsistent values for the queue >>> and next fields of a Reference, but we don't want to grab a lock >>> walking the whole queue, we could instead grab the lock as we look at >>> each Reference (and do the "back-up" trick if we were interfered >>> with). Of course this is slower than going lock-free, but it's not any >>> more overhead than the ReferenceHandler thread or FinalizerThreads incur. >>> >>> The only benefit of this solution over the others is that it is less >>> clever, and I'm not sure how much cleverness this problem deserves. >>> Given that, and ranking the solutions as "lock" < (clever) "volatile" >>> < "fence", I'd be happier with the "volatile" or "lock" solution if >>> that is sufficient. >>> >>> - Derek >>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>> forEach iteration method with no concrete logic. >>>>>> >>>>>> It would be possible to encapsulate the entire logic into a special >>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>> static method(s) (printFinalizationQueue)... You could just expose >>>>>> a package-private forEach static method from Finalizer and code the >>>>>> rest in DiagnosticCommands. >>>>> That's good for encapsulation. But I'm concerned that if "forEach" >>>>> got exposed beyond careful use in DiagnosticCommands, and the >>>>> Referents were leaked back into the heap, then we could get >>>>> unexpected object resurrection after finalization. This isn't a bug >>>>> on it's own - any finalizer might resurrect its object if not >>>>> careful, but ordinarily /only/ the finalizer could resurrect the >>>>> object. This could invalidate application invariants? >>>> Well, it all stays in the confines of package-private API - internal >>>> to JDK. Any future additional use should be reviewed carefully. >>>> Comments on the forEach() method should warn about that. >>>> >>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>> /another/ case of diagnostics affecting application behavior. And >>>>> there are pathological scenarios where this gets severe. This is >>>>> unfortunate but not uncommon. There is enough complication here that >>>>> you should be sure that the fix for diagnostics performance doesn't >>>>> introduce subtle bugs to the system in general. A change in this >>>>> area should get a thorough review from both the runtime and GC sides. >>>> Is the webrev.02 proposed above more acceptable in that respect? It >>>> does not introduce any logical changes to existing code. >>>> >>>>> Better yet, the reference handling code in GC and runtime should >>>>> probably be thrown out and re-written, but that's another issue :-) >>>> I may have some proposals in that direction. Stay tuned. >>>> >>>> Regards, Peter >>>> >>>>> - Derek >>>>> >>>>>> Regards, Peter >>>>>> >>>>>> >>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>> Everybody, >>>>>>> >>>>>>> Updated version: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>> >>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>> >>>>>>> -Dmitry >>>>>>> >>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>> Hi Dmitry, Staffan, >>>>>>>> >>>>>>>> Lots of good comments here. >>>>>>>> >>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>> general iterator and lambda. >>>>>>>> >>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>> >>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>> >>>>>>>> The sorting suggestion is a nice touch. >>>>>>>> >>>>>>>> - Derek White, GC team >>>>>>>> >>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>> >>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>> Dmitry, >>>>>>>>>> >>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>> >>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>> running out of memory. >>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>> >>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>> interfere with synchronization? >>>>>>>>> >>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>> >>>>>>>>> private void remove() { >>>>>>>>> synchronized (lock) { >>>>>>>>> if (unfinalized == this) { >>>>>>>>> if (this.next != null) { >>>>>>>>> unfinalized = this.next; >>>>>>>>> } else { >>>>>>>>> unfinalized = this.prev; >>>>>>>>> } >>>>>>>>> } >>>>>>>>> if (this.next != null) { >>>>>>>>> this.next.prev = this.prev; >>>>>>>>> } >>>>>>>>> if (this.prev != null) { >>>>>>>>> this.prev.next = this.next; >>>>>>>>> } >>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>> traverse the list unsynchronized >>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>> finalized */ >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>> pointer could be used instead: >>>>>>>>> >>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>> return (prev == this); >>>>>>>>> } >>>>>>>>> >>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>> >>>>>>>>> private void add() { >>>>>>>>> synchronized (lock) { >>>>>>>>> if (unfinalized != null) { >>>>>>>>> this.next = unfinalized; >>>>>>>>> unfinalized.prev = this; >>>>>>>>> } >>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>> // instance fully initialized >>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>> U.storeFence(); >>>>>>>>> unfinalized = this; >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> >>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>> >>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>> out? >>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>> two purposes: >>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>> >>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>> finalize() method. >>>>>>>>> >>>>>>>>> Regards, Peter >>>>>>>>> >>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>> >>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>> permission() and limit access: >>>>>>>>>> >>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>> "monitor", NULL}; >>>>>>>>>> return p; >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>> >>>>>>>>>> Thanks, >>>>>>>>>> /Staffan >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> Everyone, >>>>>>>>>>> >>>>>>>>>>> Please review the fix: >>>>>>>>>>> >>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>> >>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>> >>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>> with count >>>>>>>>>>> >>>>>>>>>>> -Dmitry >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>> * I would love to change the world, but they won't give me the sources. From peter.levart at gmail.com Sat May 16 12:48:06 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sat, 16 May 2015 14:48:06 +0200 Subject: RFR(M,v3): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55573A31.7050306@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> Message-ID: <55573C86.8030807@gmail.com> On 05/16/2015 02:38 PM, Peter Levart wrote: > > > On 05/16/2015 09:35 AM, Dmitry Samersoff wrote: >> Derek, >> >> Personally, I'm for volatile over explicit fence too. >> >> So I'll change the code if Peter don't have objections. > > There are no objections. There's one unneeded volatile store to .next > field then in enqueue(), but it is followed by another volatile store, > so there shouldn't be overhead on Intel and SPARC at least. > > Regards, Peter If you make .next field volatile, then perhaps you could also cache it's value in reallyPoll() into a local variable, so that it is not read twice. Like this: private Reference reallyPoll() { /* Must hold lock */ Reference r = head; if (r != null) { Reference rn = r.next; // HERE !!! head = (rn == r) ? null : rn; // Unchecked due to the next field having a raw type in Reference r.queue = NULL; r.next = r; queueLength--; if (r instanceof FinalReference) { sun.misc.VM.addFinalRefCount(-1); } return r; } return null; } Peter > >> -Dmitry >> >> On 2015-05-16 01:59, Derek White wrote: >>> Hi Dmitry, Peter, >>> >>> I should read my email more frequently - I missed Dmitry's last webrev >>> email. >>> >>> My comments on a preference for volatile over Unsafe are not a strong >>> objection to using Unsafe fences. I just don't have enough experience >>> with Unsafe fences yet to agree that this use is correct. >>> >>> While looking over this Reference code I found 3-6 really simple things >>> that need cleaning up that have been there for years, so I'm not a big >>> cheerleader for more complicated things here :-) >>> >>> - Derek >>> >>> On 5/15/15 6:46 PM, Derek White wrote: >>>> Hi Peter, >>>> >>>> Some comments below... >>>> >>>> On 5/14/15 3:50 AM, Peter Levart wrote: >>>>> Hi Derek, >>>>> >>>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>>> Hi Peter, >>>>>> >>>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>>> but I have some concerns... >>>>> I did have a concern too, ... >>>>> >>>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>>> Hi Dmitry, >>>>>>> >>>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>>> logical. >>>>>>> >>>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>>> threads for the entire time of iteration. This can blow up the >>>>>>> application. Suppose one wants to diagnose the application because >>>>>>> he suspects that finalizer thread hardly keeps up with production >>>>>>> of finalizable instances. This can happen if the allocation rate of >>>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>>>>> up gradually and is already holding several million objects. Now >>>>>>> you initiate the diagnostic command to print the queue. The >>>>>>> iteration over and grouping/counting of several millions of >>>>>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>>>>> reference handler thread. But does not block the threads that >>>>>>> allocate finalizable objects. By the time the iteration is over, >>>>>>> the JVM blows up and application slows down to a halt doing GCs >>>>>>> most of the time, getting OOMEs, etc... >>>>>>> >>>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>>> purposes without holding a lock. The modification required to do >>>>>>> that is the following (havent tested this, but I think it should work): >>>>>>> >>>>>>> >>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>>> >>>>>> One issue to watch out for is the garbage collectors inspect the >>>>>> Reference.next field from C code directly (to distinguish active vs. >>>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>>> >>>>>> Your change makes "inactive" References superficially look like >>>>>> "enqueued" References. The GC code is rather subtle and I haven't >>>>>> yet seen a case where it would get confused by this change, but >>>>>> there could easily be something like that lurking in the GC code. >>>>> ...but then I thought that GC can in no way treat a Reference >>>>> differently whether it is still enqueued in a ReferenceQueue or >>>>> already dequeued (inactive) - responsibility is already on the Java >>>>> side. Currently the definition of Reference.next is this: >>>>> >>>>> /* When active: NULL >>>>> * pending: this >>>>> * Enqueued: next reference in queue (or this if last) >>>>> * Inactive: this >>>>> */ >>>>> @SuppressWarnings("rawtypes") >>>>> Reference next; >>>>> >>>>> We see that, unless GC inspects all ReferenceQueue instances and >>>>> scans their lists too, the state of a Reference that is enqueued as >>>>> last in list is indistinguishable from the state of inactive >>>>> Reference. So I deduced that this distinction (enqueued/inactive) >>>>> can't be established solely on the value of .next field ( == this or >>>>> != this)... >>>>> >>>>> But I should inspect the GC code too to build a better understanding >>>>> of that part of the story... >>>>> >>>>> Anyway. It turns out that there is already enough state in Reference >>>>> to destinguish between it being enqueued as last in list and already >>>>> dequeued (inactive) - the additional state is Reference.queue that >>>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>>> (r.next and r.queue) are assigned and read in correct order. This can >>>>> be achieved either by making Reference.next a volatile field or by a >>>>> couple of explicit fences: >>>>> >>>>> >>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>>> >>>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>>> before linking the reference into the queue's head in >>>>> ReferenceQueue.enqueue(): >>>>> >>>>> r.queue = ENQUEUED; >>>>> r.next = (head == null) ? r : head; >>>>> head = r; >>>>> >>>>> Both stores are volatile. >>>> This sounds a bit better. I don't have a good handle on the pros and >>>> cons of a volatile field over explicit fences via Unsafe in this case. >>>> Kim might jump in soon. >>>> >>>> I'd like to suggest an entirely less-clever solution. Since the >>>> problem is that forEach() might see inconsistent values for the queue >>>> and next fields of a Reference, but we don't want to grab a lock >>>> walking the whole queue, we could instead grab the lock as we look at >>>> each Reference (and do the "back-up" trick if we were interfered >>>> with). Of course this is slower than going lock-free, but it's not any >>>> more overhead than the ReferenceHandler thread or FinalizerThreads incur. >>>> >>>> The only benefit of this solution over the others is that it is less >>>> clever, and I'm not sure how much cleverness this problem deserves. >>>> Given that, and ranking the solutions as "lock" < (clever) "volatile" >>>> < "fence", I'd be happier with the "volatile" or "lock" solution if >>>> that is sufficient. >>>> >>>> - Derek >>>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>>> forEach iteration method with no concrete logic. >>>>>>> >>>>>>> It would be possible to encapsulate the entire logic into a special >>>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>>> static method(s) (printFinalizationQueue)... You could just expose >>>>>>> a package-private forEach static method from Finalizer and code the >>>>>>> rest in DiagnosticCommands. >>>>>> That's good for encapsulation. But I'm concerned that if "forEach" >>>>>> got exposed beyond careful use in DiagnosticCommands, and the >>>>>> Referents were leaked back into the heap, then we could get >>>>>> unexpected object resurrection after finalization. This isn't a bug >>>>>> on it's own - any finalizer might resurrect its object if not >>>>>> careful, but ordinarily /only/ the finalizer could resurrect the >>>>>> object. This could invalidate application invariants? >>>>> Well, it all stays in the confines of package-private API - internal >>>>> to JDK. Any future additional use should be reviewed carefully. >>>>> Comments on the forEach() method should warn about that. >>>>> >>>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>>> /another/ case of diagnostics affecting application behavior. And >>>>>> there are pathological scenarios where this gets severe. This is >>>>>> unfortunate but not uncommon. There is enough complication here that >>>>>> you should be sure that the fix for diagnostics performance doesn't >>>>>> introduce subtle bugs to the system in general. A change in this >>>>>> area should get a thorough review from both the runtime and GC sides. >>>>> Is the webrev.02 proposed above more acceptable in that respect? It >>>>> does not introduce any logical changes to existing code. >>>>> >>>>>> Better yet, the reference handling code in GC and runtime should >>>>>> probably be thrown out and re-written, but that's another issue :-) >>>>> I may have some proposals in that direction. Stay tuned. >>>>> >>>>> Regards, Peter >>>>> >>>>>> - Derek >>>>>> >>>>>>> Regards, Peter >>>>>>> >>>>>>> >>>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>>> Everybody, >>>>>>>> >>>>>>>> Updated version: >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>>> >>>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>>> >>>>>>>> -Dmitry >>>>>>>> >>>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>> >>>>>>>>> Lots of good comments here. >>>>>>>>> >>>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>>> general iterator and lambda. >>>>>>>>> >>>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>>> >>>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>>> >>>>>>>>> The sorting suggestion is a nice touch. >>>>>>>>> >>>>>>>>> - Derek White, GC team >>>>>>>>> >>>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>> >>>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>>> Dmitry, >>>>>>>>>>> >>>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>>> >>>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>>> running out of memory. >>>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>>> >>>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>>> interfere with synchronization? >>>>>>>>>> >>>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>>> >>>>>>>>>> private void remove() { >>>>>>>>>> synchronized (lock) { >>>>>>>>>> if (unfinalized == this) { >>>>>>>>>> if (this.next != null) { >>>>>>>>>> unfinalized = this.next; >>>>>>>>>> } else { >>>>>>>>>> unfinalized = this.prev; >>>>>>>>>> } >>>>>>>>>> } >>>>>>>>>> if (this.next != null) { >>>>>>>>>> this.next.prev = this.prev; >>>>>>>>>> } >>>>>>>>>> if (this.prev != null) { >>>>>>>>>> this.prev.next = this.next; >>>>>>>>>> } >>>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>>> traverse the list unsynchronized >>>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>>> finalized */ >>>>>>>>>> } >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>>> pointer could be used instead: >>>>>>>>>> >>>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>>> return (prev == this); >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>>> >>>>>>>>>> private void add() { >>>>>>>>>> synchronized (lock) { >>>>>>>>>> if (unfinalized != null) { >>>>>>>>>> this.next = unfinalized; >>>>>>>>>> unfinalized.prev = this; >>>>>>>>>> } >>>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>>> // instance fully initialized >>>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>>> U.storeFence(); >>>>>>>>>> unfinalized = this; >>>>>>>>>> } >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>>> >>>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>>> out? >>>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>>> two purposes: >>>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>>> >>>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>>> finalize() method. >>>>>>>>>> >>>>>>>>>> Regards, Peter >>>>>>>>>> >>>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>>> >>>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>>> permission() and limit access: >>>>>>>>>>> >>>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>>> "monitor", NULL}; >>>>>>>>>>> return p; >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>>> >>>>>>>>>>> Thanks, >>>>>>>>>>> /Staffan >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>> Everyone, >>>>>>>>>>>> >>>>>>>>>>>> Please review the fix: >>>>>>>>>>>> >>>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>>> >>>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>>> >>>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>>> with count >>>>>>>>>>>> >>>>>>>>>>>> -Dmitry >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>>> * I would love to change the world, but they won't give me the sources. > From claes.redestad at oracle.com Sat May 16 16:21:23 2015 From: claes.redestad at oracle.com (Claes Redestad) Date: Sat, 16 May 2015 18:21:23 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5556912D.2020000@oracle.com> References: <5556912D.2020000@oracle.com> Message-ID: <55576E83.1080002@oracle.com> Hi, any reason not to just have Enumeration extend Iterable and default-implement iterator()? http://cr.openjdk.java.net/~redestad/scratch/enumerable.00/ I guess there are compatibility risks I haven't thought through completely, but I think concrete classes that already implement both Enumeration and Iterable should continue to work as expected (since the concrete class' implementation of iterator always takes precedence), no? /Claes On 2015-05-16 02:37, Stuart Marks wrote: > Hi all, > > Please review this small API enhancement to add a default method > "asIterator()" to Enumeration that converts it into an Iterator. > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8072726 > > Thanks, > > s'marks From paul.sandoz at oracle.com Sat May 16 16:50:26 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Sat, 16 May 2015 18:50:26 +0200 Subject: PriorityQueue In-Reply-To: <5555FCFC.5070609@oracle.com> References: <5555FCFC.5070609@oracle.com> Message-ID: <92BFF2DB-DDBE-4BCB-80C9-4AD81C88CFED@oracle.com> On May 15, 2015, at 4:04 PM, Chris Hegarty wrote: > And/Or should PriorityQueue override addAll and provide a more performant implementation for common Collection types ( just like the constructor )? > It should be possible to improve this case too: create a new array, appropriately sized, holding the current elements and those of the collection (via toArray or iteration), then reestablish the heap invariant. Paul. From chris.hegarty at oracle.com Sat May 16 19:25:27 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Sat, 16 May 2015 20:25:27 +0100 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5556912D.2020000@oracle.com> References: <5556912D.2020000@oracle.com> Message-ID: <8F3E0654-729E-4AF1-9C62-28294F9C6626@oracle.com> This looks very useful. The javadoc reads well, and I think it is pitched at the right level ( view the Enumeration as an Iterator ). I expected to see ?view? or ?convert? in the javadoc, but what you have reads fine too. -Chris. > On 16 May 2015, at 01:37, Stuart Marks wrote: > > Hi all, > > Please review this small API enhancement to add a default method "asIterator()" to Enumeration that converts it into an Iterator. > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8072726 > > Thanks, > > s'marks From chris.hegarty at oracle.com Sat May 16 19:52:26 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Sat, 16 May 2015 20:52:26 +0100 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: <5556968D.9070401@oracle.com> References: <55567ACB.2050307@oracle.com> <5556968D.9070401@oracle.com> Message-ID: <441886D7-EEF0-48E5-87B3-A62E32ACB3E1@oracle.com> > On 16 May 2015, at 01:59, Ivan Gerasimov wrote: > > On 16.05.2015 2:18, Martin Buchholz wrote: >> I don't think you're taking the load factor into account. > Hm. You're right, HashMap's constructor expects the capacity as the argument. > I was confused by IdentityHashMap, whose constructor expects the maximum number of elements to be inserted. > >> https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/collect/Maps.java?r=f8144b4df7eec5f1c9e6942d8d5ef734a8767fd9#110 >> You want to check (via reflection) that the size of the backing array is unchanged if you copy the map with new HashMap(map). >> > Sorry, I didn't get it. How could we detect that the initial capacity wasn't big enough, if we hadn't stored it? > >> I wouldn't bother defining the constant. >> > I only need it in the regression test, to check whether it was sufficient. > > Here's the updated webrev: > http://cr.openjdk.java.net/~igerasim/8080535/01/webrev/ This looks much better. Trivially I?d calculate the initial size like: 510 / 0.75 + 1.0f ( plus 1 ) ? but your regression test should prove that the plus one is not needed. Maybe a comment that the 0.75 is the default load factor from HashMap. The constant could be removed and the ?510? be used directly in the test. Since the test is whitebox. The test is fine, but could be a little less obscure if it looked at the table size, rather than the equality. But what you have is fine. -Chris. > > Comments, suggestions are welcome! > > Sincerely yours, > Ivan > >> On Fri, May 15, 2015 at 4:01 PM, Ivan Gerasimov > wrote: >> >> Hello! >> >> When constructing the map, the expected size is specified to be >> 256, but then 510 elements are inserted. >> A new whitebox test is provided, so the next time the number of >> entries grows, the expected size will not be forgotten. >> >> Would you please help review this fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8080535 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8080535/00/webrev/ >> >> >> Sincerely yours, >> Ivan >> >> > From forax at univ-mlv.fr Sat May 16 21:48:33 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 16 May 2015 23:48:33 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <55576E83.1080002@oracle.com> References: <5556912D.2020000@oracle.com> <55576E83.1080002@oracle.com> Message-ID: <5557BB31.5080301@univ-mlv.fr> On 05/16/2015 06:21 PM, Claes Redestad wrote: > Hi, > > any reason not to just have Enumeration extend Iterable and > default-implement iterator()? > > http://cr.openjdk.java.net/~redestad/scratch/enumerable.00/ > > I guess there are compatibility risks I haven't thought through > completely, but I > think concrete classes that already implement both Enumeration and > Iterable should > continue to work as expected (since the concrete class' implementation of > iterator always takes precedence), no? Hi Claes, yes, but there is an issue for code that uses instanceof to do something different if the object is an Enumeration or if the object is an Iterable. You can only retrofit an existing class/interface to implements/extends an interface/class in a compatible way only if the interface/class is newly introduced in the release by example retrofitting Closeable to implement AutoCloseable is Ok in 1.7 because AutoCloseable was introduced in 1.7. and remember, prefer composition to inheritance :) > > /Claes R?mi > > On 2015-05-16 02:37, Stuart Marks wrote: >> Hi all, >> >> Please review this small API enhancement to add a default method >> "asIterator()" to Enumeration that converts it into an Iterator. >> >> Webrev: >> >> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >> >> Bug: >> >> https://bugs.openjdk.java.net/browse/JDK-8072726 >> >> Thanks, >> >> s'marks > From forax at univ-mlv.fr Sat May 16 22:00:06 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sun, 17 May 2015 00:00:06 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5556912D.2020000@oracle.com> References: <5556912D.2020000@oracle.com> Message-ID: <5557BDE6.6010400@univ-mlv.fr> Hi Stuart, this change is pretty cool, In the javadoc of Iterator instead of: Iterable permsIterable = () -> pc.elements().asIterator(); one can write: Iterable permsIterable = pc.elements()::asIterator; and I wonder if an example with NetworkInterface.getNetworkInterfaces() is not better, I'm not sure a lot of people have to play with permissions outside people of this list. and for the implementation of asIterator, I think the code can be written like this: default Iterator asIterator() { return new Iterator<>() { @Override public boolean hasNext() { return hasMoreElements(); } @Override public E next() { return nextElement(); } }; } using diamond inference on inner-classes (I think the patch that allows that was integrated) and making calls to Enumeration.this implicit. regards, R?mi On 05/16/2015 02:37 AM, Stuart Marks wrote: > Hi all, > > Please review this small API enhancement to add a default method > "asIterator()" to Enumeration that converts it into an Iterator. > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8072726 > > Thanks, > > s'marks From claes.redestad at oracle.com Sat May 16 22:46:39 2015 From: claes.redestad at oracle.com (Claes Redestad) Date: Sun, 17 May 2015 00:46:39 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5557BB31.5080301@univ-mlv.fr> References: <5556912D.2020000@oracle.com> <55576E83.1080002@oracle.com> <5557BB31.5080301@univ-mlv.fr> Message-ID: <5557C8CF.6060204@oracle.com> On 2015-05-16 23:48, Remi Forax wrote: > > > On 05/16/2015 06:21 PM, Claes Redestad wrote: >> Hi, >> >> any reason not to just have Enumeration extend Iterable and >> default-implement iterator()? >> >> http://cr.openjdk.java.net/~redestad/scratch/enumerable.00/ >> >> I guess there are compatibility risks I haven't thought through >> completely, but I >> think concrete classes that already implement both Enumeration and >> Iterable should >> continue to work as expected (since the concrete class' >> implementation of >> iterator always takes precedence), no? > > Hi Claes, > > yes, but there is an issue for code that uses instanceof to do > something different if the object is an Enumeration or if the object > is an Iterable. Hi R?mi, I guess that's a possibility. > > You can only retrofit an existing class/interface to > implements/extends an interface/class in a compatible way only if the > interface/class is newly introduced in the release by example > retrofitting Closeable to implement AutoCloseable is Ok in 1.7 because > AutoCloseable was introduced in 1.7. Probably due to introducing ambiguity in overload selection, come to think of it. I also realized Iterable should typically allow multiple passes over the collection/enumeration, so this wouldn't feel right. Sorry! So... I'm happy with Stuart's proposal. I would also be happy (happier?) with a stream variant: pc.elements().stream().forEach(this::doSomethingWithPermission); > and remember, prefer composition to inheritance :) *ducks* :) /Claes > >> >> /Claes > > R?mi > >> >> On 2015-05-16 02:37, Stuart Marks wrote: >>> Hi all, >>> >>> Please review this small API enhancement to add a default method >>> "asIterator()" to Enumeration that converts it into an Iterator. >>> >>> Webrev: >>> >>> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >>> >>> Bug: >>> >>> https://bugs.openjdk.java.net/browse/JDK-8072726 >>> >>> Thanks, >>> >>> s'marks >> > From forax at univ-mlv.fr Sat May 16 23:02:23 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sun, 17 May 2015 01:02:23 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5557C8CF.6060204@oracle.com> References: <5556912D.2020000@oracle.com> <55576E83.1080002@oracle.com> <5557BB31.5080301@univ-mlv.fr> <5557C8CF.6060204@oracle.com> Message-ID: <5557CC7F.4000801@univ-mlv.fr> On 05/17/2015 12:46 AM, Claes Redestad wrote: > > On 2015-05-16 23:48, Remi Forax wrote: >> >> >> On 05/16/2015 06:21 PM, Claes Redestad wrote: >>> Hi, >>> >>> any reason not to just have Enumeration extend Iterable and >>> default-implement iterator()? >>> >>> http://cr.openjdk.java.net/~redestad/scratch/enumerable.00/ >>> >>> I guess there are compatibility risks I haven't thought through >>> completely, but I >>> think concrete classes that already implement both Enumeration and >>> Iterable should >>> continue to work as expected (since the concrete class' >>> implementation of >>> iterator always takes precedence), no? >> >> Hi Claes, >> >> yes, but there is an issue for code that uses instanceof to do >> something different if the object is an Enumeration or if the object >> is an Iterable. > > Hi R?mi, > > I guess that's a possibility. > >> >> You can only retrofit an existing class/interface to >> implements/extends an interface/class in a compatible way only if the >> interface/class is newly introduced in the release by example >> retrofitting Closeable to implement AutoCloseable is Ok in 1.7 >> because AutoCloseable was introduced in 1.7. > > Probably due to introducing ambiguity in overload selection, come to > think of it. > > I also realized Iterable should typically allow multiple passes over the > collection/enumeration, so this wouldn't feel right. Sorry! > > So... I'm happy with Stuart's proposal. > > I would also be happy (happier?) with a stream variant: > pc.elements().stream().forEach(this::doSomethingWithPermission); We are not that far : pc.elements().asIterator().forEachRemaining(this::doSomethingWithPermission); and having a method stream() on an Enumeration as the very same issue as having a method stream() on an Iterator. A Stream need to know more than just the elements but also characteristics like if the element can be null, are ordered, the number of elements if known, etc. These characteristics can be derived from List or Set but not from Iterator/Enumeration easily. That's why it's better to let the user to create a stream using StreamSupport if he really want one. > >> and remember, prefer composition to inheritance :) > > *ducks* :) > > /Claes R?mi > >> >>> >>> /Claes >> >> R?mi >> >>> >>> On 2015-05-16 02:37, Stuart Marks wrote: >>>> Hi all, >>>> >>>> Please review this small API enhancement to add a default method >>>> "asIterator()" to Enumeration that converts it into an Iterator. >>>> >>>> Webrev: >>>> >>>> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >>>> >>>> Bug: >>>> >>>> https://bugs.openjdk.java.net/browse/JDK-8072726 >>>> >>>> Thanks, >>>> >>>> s'marks >>> >> > From claes.redestad at oracle.com Sat May 16 23:23:36 2015 From: claes.redestad at oracle.com (Claes Redestad) Date: Sun, 17 May 2015 01:23:36 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5557CC7F.4000801@univ-mlv.fr> References: <5556912D.2020000@oracle.com> <55576E83.1080002@oracle.com> <5557BB31.5080301@univ-mlv.fr> <5557C8CF.6060204@oracle.com> <5557CC7F.4000801@univ-mlv.fr> Message-ID: <5557D178.1040104@oracle.com> On 2015-05-17 01:02, Remi Forax wrote: >> >> So... I'm happy with Stuart's proposal. >> >> I would also be happy (happier?) with a stream variant: >> pc.elements().stream().forEach(this::doSomethingWithPermission); > > We are not that far : > pc.elements().asIterator().forEachRemaining(this::doSomethingWithPermission); > Yes, I guess that's no worse. Thanks! > > and having a method stream() on an Enumeration as the very same issue > as having a method stream() on an Iterator. > A Stream need to know more than just the elements but also > characteristics like if the element can be null, are ordered, the > number of elements if known, etc. > These characteristics can be derived from List or Set but not from > Iterator/Enumeration easily. > > That's why it's better to let the user to create a stream using > StreamSupport if he really want one. Right. /Claes From stuart.marks at oracle.com Sun May 17 00:22:24 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Sat, 16 May 2015 17:22:24 -0700 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5557C8CF.6060204@oracle.com> References: <5556912D.2020000@oracle.com> <55576E83.1080002@oracle.com> <5557BB31.5080301@univ-mlv.fr> <5557C8CF.6060204@oracle.com> Message-ID: <5557DF40.2000107@oracle.com> Hi guys, really going at it on a Saturday, eh? On 5/16/15 3:46 PM, Claes Redestad wrote: > I also realized Iterable should typically allow multiple passes over the > collection/enumeration, so this wouldn't feel right. Sorry! > > So... I'm happy with Stuart's proposal. Yep, that's the main reason not to have Enumeration extend Iterable. Although it isn't written down explicitly, common usage expects that each call to iterator() produce a fresh instance, positioned at the beginning, independent of other instances. > I would also be happy (happier?) with a stream variant: > pc.elements().stream().forEach(this::doSomethingWithPermission); I think R?mi answered this well. >> and remember, prefer composition to inheritance :) > > *ducks* :) Yep. While we're at it, though, the "obvious" alternative is to have Enumeration extend Iterator (as opposed to Iterable). This could work, but it has a fairly big risk of incompatibility. Iterator defines a next() method returning T, and it seems pretty likely that there's code out there that has a next() method. If it returned T, it wouldn't be an error, but the resulting Iterator probably wouldn't function properly. If it returned something other than T, it'd be a big source incompatibility. Of course, in principle, the same thing could occur with "asIterator". But that seems much less likely to collide with something than "next". s'marks > > /Claes > >> >>> >>> /Claes >> >> R?mi >> >>> >>> On 2015-05-16 02:37, Stuart Marks wrote: >>>> Hi all, >>>> >>>> Please review this small API enhancement to add a default method >>>> "asIterator()" to Enumeration that converts it into an Iterator. >>>> >>>> Webrev: >>>> >>>> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >>>> >>>> Bug: >>>> >>>> https://bugs.openjdk.java.net/browse/JDK-8072726 >>>> >>>> Thanks, >>>> >>>> s'marks >>> >> > From stuart.marks at oracle.com Sun May 17 00:26:58 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Sat, 16 May 2015 17:26:58 -0700 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <8F3E0654-729E-4AF1-9C62-28294F9C6626@oracle.com> References: <5556912D.2020000@oracle.com> <8F3E0654-729E-4AF1-9C62-28294F9C6626@oracle.com> Message-ID: <5557E052.6080308@oracle.com> Yeah, interesting. I think "convert" has too much of an implication of the resulting Iterator being independent of the underlying Enumeration, which it isn't. "View" is a good word, but it has to be understood with a specific meaning, e.g., List.subList creates a view of an underlying list. Perhaps "wrapper" would be good because it explains exactly what's going on. I'll mull this over a bit and see if I can come up with something better. s'marks On 5/16/15 12:25 PM, Chris Hegarty wrote: > This looks very useful. The javadoc reads well, and I think it is pitched at the right level ( view the Enumeration as an Iterator ). I expected to see ?view? or ?convert? in the javadoc, but what you have reads fine too. > > -Chris. > >> On 16 May 2015, at 01:37, Stuart Marks wrote: >> >> Hi all, >> >> Please review this small API enhancement to add a default method "asIterator()" to Enumeration that converts it into an Iterator. >> >> Webrev: >> >> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >> >> Bug: >> >> https://bugs.openjdk.java.net/browse/JDK-8072726 >> >> Thanks, >> >> s'marks > From stuart.marks at oracle.com Sun May 17 00:53:41 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Sat, 16 May 2015 17:53:41 -0700 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5557BDE6.6010400@univ-mlv.fr> References: <5556912D.2020000@oracle.com> <5557BDE6.6010400@univ-mlv.fr> Message-ID: <5557E695.8020109@oracle.com> On 5/16/15 3:00 PM, Remi Forax wrote: > Hi Stuart, > this change is pretty cool, Hi R?mi, thanks for looking at this. > In the javadoc of Iterator instead of: > Iterable permsIterable = () -> pc.elements().asIterator(); > one can write: > Iterable permsIterable = pc.elements()::asIterator; Ah, I carefully tailored that example to capture "pc" instead of the result of calling pc.elements(). With the latter, if iterator() is called a second time, the two Iterator instances will share the same underlying Enumeration and probably interfere with each other. (Maybe I'll add a note to the example explaining that.) > and I wonder if an example with NetworkInterface.getNetworkInterfaces() is not > better, > I'm not sure a lot of people have to play with permissions outside people of > this list. Yeah I had to look for a long time to find a good example of Enumeration in the JDK libraries. One problem with NetworkInterface.getNetworkInterfaces() is that it's declared to throw SocketException, which is checked, making it clumsy to use within a lambda. There are other possibilities (e.g., getSubInterfaces()) but that's pretty obscure too. Although the permissions stuff is pretty obscure too, they're pretty easy to get, either by getting one from a class' ProtectionDomain, or creating one yourself. > and for the implementation of asIterator, I think the code can be written like > this: > default Iterator asIterator() { > return new Iterator<>() { > @Override public boolean hasNext() { > return hasMoreElements(); > } > @Override public E next() { > return nextElement(); > } > }; > } > > using diamond inference on inner-classes (I think the patch that allows that was > integrated) and making calls to Enumeration.this implicit. Right, I think I wrote my initial prototype before this compiler change went in! Good catch on the Enumeration.this too; I'll make these updates. s'marks > > regards, > R?mi > > On 05/16/2015 02:37 AM, Stuart Marks wrote: >> Hi all, >> >> Please review this small API enhancement to add a default method >> "asIterator()" to Enumeration that converts it into an Iterator. >> >> Webrev: >> >> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >> >> Bug: >> >> https://bugs.openjdk.java.net/browse/JDK-8072726 >> >> Thanks, >> >> s'marks > From peterhansson_se at yahoo.com Sun May 17 07:55:49 2015 From: peterhansson_se at yahoo.com (Peter Hansson) Date: Sun, 17 May 2015 07:55:49 +0000 (UTC) Subject: Naming of thread pools (Executors) Message-ID: <644298286.508634.1431849349018.JavaMail.yahoo@mail.yahoo.com> Hi, I would like create a patch for https://bugs.openjdk.java.net/browse/JDK-8016248. MOTIVATION: Today thread pools created by the Executors method are always prefixed with "pool". The developer can work around this by providing his own ThreadFactory but if he wants to have the default JDK behaviour then it means he has to replicate code in the JDK. The string "pool" is hardcoded in the JDK. The fact that threads cannot be identified by their purpose is annoying especially when working with JEE servers. SUGGESTION: The idea is to amend private classes Executors.DefaultThreadFactory and Executors.PrivilegedThreadFactory to optionally accept a name prefix in their constructor.Then methods Executors.defaultThreadFactory() and Executors.privilegedThreadFactory() will be overloaded to optionally accept a name prefix. With this change the developer can now use a custom thread name prefix. If he wanted to do: ?? Executors.newFixedThreadPool(3);? // standard, results in "pool" prefix He could instead use a developer supplied ThreadFactory yet still using JDK's ThreadFactory: ?? Executors.newFixedThreadPool(3, Executors.defaultThreadFactory("snmpworker")); Good idea ?? Bad idea?? Any negative side effects ? Thanks Peter From peter.levart at gmail.com Sun May 17 09:05:18 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 17 May 2015 11:05:18 +0200 Subject: RFR: 8077846: improve locking strategy for readConfiguration(), reset(), and initializeGlobalHandlers() In-Reply-To: <55560B39.5080601@oracle.com> References: <553A7835.80209@oracle.com> <553D8F0B.4070102@oracle.com> <553DE503.2060608@oracle.com> <553E29C7.8030800@oracle.com> <553E9685.1030809@oracle.com> <553F3DC4.4010104@gmail.com> <553F4136.5010500@oracle.com> <553F940C.4050105@gmail.com> <553F9FC7.4020806@oracle.com> <553FAB5B.3060605@gmail.com> <55423F39.6060304@oracle.com> <5542C2ED.1090100@gmail.com> <5547736A.4060805@gmail.com> <55477838.6020200@oracle.com> <55477D95.1010202@gmail.com> <55478658.4090700@gmail.com> <5547C000.9040005@oracle.com> <554860F3.6030909@oracle.com> <55560B39.5080601@oracle.com> Message-ID: <555859CE.30300@gmail.com> On 05/15/2015 05:05 PM, Daniel Fuchs wrote: >>> Looks good for me Peter :-) >>> Hopefully Mandy will like it too! >>> >> >> Yes it looks good to me. Thanks to both of you for imprpving the >> synchronization. This is the comment on the test I sent last round: >> >> TestConfigurationLock.java >> >> Copyright year should be 2015 >> >> TestConfigurationLock.properties >> >> It would be good to delete all commented lines except the lines >> relevant to the setting to make it obvious what the configuration >> is. > > Right. Sorry I forgot about that. Here is an updated webrev > containing Peter's webrev.04 in which I have updated the test: > > http://cr.openjdk.java.net/~dfuchs/webrev_8077846/webrev.05 > > Peter, are you still willing to push that? > > best regards, > > -- daniel Right. I went over code changes once again and I was happy with the final shape. I re-ran the java/util/logging tests an all 60 passed. So I pushed this change. Thanks to David, Alan and Mandy for reviewing and of course to Daniel for cooperation and the majority of the code in this changeset. Regards, Peter > >> >> Mandy >> From joe.darcy at oracle.com Sun May 17 16:53:17 2015 From: joe.darcy at oracle.com (joe darcy) Date: Sun, 17 May 2015 09:53:17 -0700 Subject: JDK 9 RFR of JDK-8078136: Incorrect figure number in reference to Hacker's Delight book in Long.bitCount() method Message-ID: <5558C77D.5080101@oracle.com> Hello, Please review this typo fix for JDK-8078136: Incorrect figure number in reference to Hacker's Delight book in Long.bitCount() method diff -r d40f1245a1f1 src/java.base/share/classes/java/lang/Long.java --- a/src/java.base/share/classes/java/lang/Long.java Wed May 13 14:16:46 2015 -0700 +++ b/src/java.base/share/classes/java/lang/Long.java Sun May 17 09:51:48 2015 -0700 @@ -1708,7 +1708,7 @@ * @since 1.5 */ public static int bitCount(long i) { - // HD, Figure 5-14 + // HD, Figure 5-2 i = i - ((i >>> 1) & 0x5555555555555555L); i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L); i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL; I verified all the other figure references between java.lang.Integer and java.lang.Long were consistent. Thanks, -Joe From lance.andersen at oracle.com Sun May 17 17:42:38 2015 From: lance.andersen at oracle.com (Lance @ Oracle) Date: Sun, 17 May 2015 13:42:38 -0400 Subject: JDK 9 RFR of JDK-8078136: Incorrect figure number in reference to Hacker's Delight book in Long.bitCount() method In-Reply-To: <5558C77D.5080101@oracle.com> References: <5558C77D.5080101@oracle.com> Message-ID: <8001C3C9-7326-40A0-877F-94CC6D1735F8@oracle.com> Go for it 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 Sent from my iPad > On May 17, 2015, at 12:53 PM, joe darcy wrote: > > Hello, > > Please review this typo fix for > > JDK-8078136: Incorrect figure number in reference to Hacker's Delight book in Long.bitCount() method > > diff -r d40f1245a1f1 src/java.base/share/classes/java/lang/Long.java > --- a/src/java.base/share/classes/java/lang/Long.java Wed May 13 14:16:46 2015 -0700 > +++ b/src/java.base/share/classes/java/lang/Long.java Sun May 17 09:51:48 2015 -0700 > @@ -1708,7 +1708,7 @@ > * @since 1.5 > */ > public static int bitCount(long i) { > - // HD, Figure 5-14 > + // HD, Figure 5-2 > i = i - ((i >>> 1) & 0x5555555555555555L); > i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L); > i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL; > > I verified all the other figure references between java.lang.Integer and java.lang.Long were consistent. > > Thanks, > > -Joe From david.holmes at oracle.com Mon May 18 01:47:52 2015 From: david.holmes at oracle.com (David Holmes) Date: Mon, 18 May 2015 11:47:52 +1000 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55564473.3010704@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> <55526FF5.9000509@gmail.com> <55564473.3010704@oracle.com> Message-ID: <555944C8.5000600@oracle.com> On 16/05/2015 5:09 AM, Brent Christian wrote: > On 5/13/15 8:53 AM, Mandy Chung wrote: >>> On May 12, 2015, at 2:26 PM, Peter Levart >>> wrote: >>> On 05/12/2015 10:49 PM, Mandy Chung wrote: >>>>> But I think it should be pretty safe to make the >>>>> java.util.Properties object override all Hashtable methods and >>>>> delegate to internal CMH so that: >>>>> - all modification methods + all bulk read methods such as >>>>> (keySet().toArray, values.toArray) are made synchronized again >>>>> - individual entry read methods (get, containsKey, ...) are not >>>>> synchronized. >>>>> >>>>> This way we get the benefits of non-synchronized read access >>>>> but the change is hardly observable. In particular since >>>>> external synchronization on the Properties object makes guarded >>>>> code atomic like it is now and individual entry read accesses >>>>> are almost equivalent whether they are synchronized or not and >>>>> I would be surprised if any code using Properties for the >>>>> purpose they were designed for worked any differently. >>>> >>>> I agree that making read-only methods not synchronized while >>>> keeping any method with write-access with synchronized is pretty >>>> safe change and low compatibility risk. On the other hand, would >>>> most of the overrridden methods be synchronized then? >>> >>> Yes, and that doesn't seem to be a problem. Setting properties is >>> not very frequent operation and is usually quite localized. Reading >>> properties is, on the other hand, a very frequent operation >>> dispersed throughout the code (almost like logging) and therefore >>> very prone to deadlocks like the one in this issue. I think that by >>> having an unsynchronized get(Property), most problems with >>> Properties will be solved - deadlock and performance (scalability) >>> related. >> >> I?m keen on cleaning up the system properties but it is a bigger >> scope as it should take other related enhancement requests into >> account that should be something for future. I think what you >> propose seems a good solution to fix JDK-8029891 while it doesn?t >> completely get us off the deadlock due to user code locking the >> Properties object. > > Updated webrev: > > http://cr.openjdk.java.net/~bchristi/8029891/webrev.1/ This approach seems reasonable to me. I don't have any specific concerns. Thanks, David ----- > I have restored synchronization to modification methods, and to my > interpretation of "bulk read" operations: > > * forEach > * replaceAll > * store: (synchronized(this) in store0; also, entrySet() returns a > synchronizedSet) > * storeToXML: PropertiesDefaultsHandler.store() synchronizes on the > Properties instance > * propertyNames(): returns an Enumeration not backed by the > Properies; calls (still synchronized) enumerate() > * stringPropertyNames returns a Set not backed by the Properties; > calls (still synchronized) enumerateStringProperties > > These continue to return a synchronized[Set|Collection]: > * keySet > * entrySet > * values > > These methods should operate on a coherent snapshot: > * clone > * equals > * hashCode > > I expect these two are only used for debugging. I wonder if we could > get away with removing synchronization: > * list > * toString > > I'm still looking through the serialization code, though I suspect some > synchronization should be added. > > The new webrev also has the updated test case from Peter. > > Thanks, > -Brent > From aleksey.shipilev at oracle.com Mon May 18 07:32:12 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 18 May 2015 10:32:12 +0300 Subject: Naming of thread pools (Executors) In-Reply-To: <644298286.508634.1431849349018.JavaMail.yahoo@mail.yahoo.com> References: <644298286.508634.1431849349018.JavaMail.yahoo@mail.yahoo.com> Message-ID: <5559957C.6070400@oracle.com> On 05/17/2015 10:55 AM, Peter Hansson wrote: > Hi, > > I would like create a patch for https://bugs.openjdk.java.net/browse/JDK-8016248. > MOTIVATION: Today thread pools created by the Executors method are always prefixed with "pool". The developer can work around this by providing his own ThreadFactory but if he wants to have the default JDK behaviour then it means he has to replicate code in the JDK. The string "pool" is hardcoded in the JDK. The fact that threads cannot be identified by their purpose is annoying especially when working with JEE servers. > > SUGGESTION: > The idea is to amend private classes Executors.DefaultThreadFactory and Executors.PrivilegedThreadFactory to optionally accept a name prefix in their constructor.Then methods Executors.defaultThreadFactory() and Executors.privilegedThreadFactory() will be overloaded to optionally accept a name prefix. > With this change the developer can now use a custom thread name prefix. If he wanted to do: > > Executors.newFixedThreadPool(3); // standard, results in "pool" prefix > > He could instead use a developer supplied ThreadFactory yet still using JDK's ThreadFactory: > Executors.newFixedThreadPool(3, Executors.defaultThreadFactory("snmpworker")); > > Good idea ? Bad idea? Any negative side effects ? I think that's a sane improvement. But the next thing you'd want are shortcuts for thread daemon status, priority, and maybe even the context classloader. Having that in mind, it might be worthwhile to explore making Executors.simpleThreadFactory(String prefix, boolean isDaemon, int priority) and/or overloads and/or some builder variant of it? Thanks, -Aleksey From daniel.fuchs at oracle.com Mon May 18 08:56:16 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Mon, 18 May 2015 10:56:16 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5556912D.2020000@oracle.com> References: <5556912D.2020000@oracle.com> Message-ID: <5559A930.60104@oracle.com> Hi Stuart, That's an RFE I have often wished for :-) I've been wondering whether a static method in the class java.util.Collections would be better, since there already are some conversion methods there - like: public static Enumeration emptyEnumeration(); public static Enumeration enumeration(final Collection c); public static ArrayList list(Enumeration e); but I see that Brian already commented in the bug that he preferred the default method on Iterator... I like the examples in the API documentation of the new method. Looks good to me! best regards, -- daniel On 16/05/15 02:37, Stuart Marks wrote: > Hi all, > > Please review this small API enhancement to add a default method > "asIterator()" to Enumeration that converts it into an Iterator. > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8072726 > > Thanks, > > s'marks From forax at univ-mlv.fr Mon May 18 09:19:06 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 18 May 2015 11:19:06 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5559A930.60104@oracle.com> References: <5556912D.2020000@oracle.com> <5559A930.60104@oracle.com> Message-ID: <5559AE8A.90605@univ-mlv.fr> On 05/18/2015 10:56 AM, Daniel Fuchs wrote: > Hi Stuart, > > That's an RFE I have often wished for :-) > > I've been wondering whether a static method > in the class java.util.Collections would be better, since there > already are some conversion methods there - like: > > public static Enumeration emptyEnumeration(); > public static Enumeration enumeration(final Collection c); > public static ArrayList list(Enumeration e); > > but I see that Brian already commented in the bug that he > preferred the default method on Iterator... Hi Daniel, I think we should do the opposite move, move the frequently used static methods from j.u.Collections to the interface their belong to. We have started this by moving Collections.sort() into List.sort() and we will soon add methods like of() to support 'collections literal' inside the collection interfaces. As Brian said, it's easier to find a method related to Enumeration inside Enumeration and j.u.Collections is already to big. so it's like we should move the code of Collections.emptyEnumeration() into Enumeration.empty() and let's Collections.emptyEnumeration() to call Enumeration.empty(). > > I like the examples in the API documentation of the new method. > Looks good to me! > > best regards, > > -- daniel cheers, R?mi > > On 16/05/15 02:37, Stuart Marks wrote: >> Hi all, >> >> Please review this small API enhancement to add a default method >> "asIterator()" to Enumeration that converts it into an Iterator. >> >> Webrev: >> >> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >> >> Bug: >> >> https://bugs.openjdk.java.net/browse/JDK-8072726 >> >> Thanks, >> >> s'marks > From paul.sandoz at oracle.com Mon May 18 10:20:39 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 18 May 2015 12:20:39 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <5556912D.2020000@oracle.com> References: <5556912D.2020000@oracle.com> Message-ID: <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> Hi Stuart, I would like to suggest some tweaks to the specification to get across this method is transitioning control of traversal from enumeration to iterator. How about: Returns an iterator that traverses the remaining elements covered by this enumeration. Traversal is undefined if this enumeration is operated on after the call to {@code asIterator}. I suspect the use of PermissionCollection in the apiNote is a little too obscure and highlighting an area that i don't think deserves so much attention :-) In your example i am not sure the source is IMMUTABLE, it's possible to add permissions if the collection is not marked read-only. It's not even clear whether ORDERED is relevant here, some implementations are backed by a HashMap (see BasicPermissionCollection) and the enumeration is derived from the map's values. Hence I am ambivalent about exposing such a Stream example, it exposes too many details that are tricky to get right. ClassLoader.getResources would be better if it were not for IOException. I would be inclined to go for Zip/JarFile.entries, and that would also give us the opportunity to highlight the stream returning method that could be used instead, therefore we can avoid mentioning about constructing a stream from an enumeration/iterator and move developers away from Enumeration altogether in this case. A good stream-ification task would be to identify cases in the JDK where only an Enumeration is returned and additionally provide stream-returning methods, so perhaps PermissionCollection and ClassLoader are good candidates. Paul. On May 16, 2015, at 2:37 AM, Stuart Marks wrote: > Hi all, > > Please review this small API enhancement to add a default method "asIterator()" to Enumeration that converts it into an Iterator. > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8072726 > > Thanks, > > s'marks From sundararajan.athijegannathan at oracle.com Mon May 18 10:44:36 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 18 May 2015 16:14:36 +0530 Subject: RFR 8072853: SimpleScriptContext used by NashornScriptEngine doesn't completely complies to the spec regarding exception throwing Message-ID: <5559C294.8070401@oracle.com> Please review http://cr.openjdk.java.net/~sundar/8072853/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8072853 Thanks, -Sundar From paul.sandoz at oracle.com Mon May 18 11:58:21 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 18 May 2015 13:58:21 +0200 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <5550CFA1.9010606@Oracle.com> References: <5550CFA1.9010606@Oracle.com> Message-ID: <68D6442A-D329-45CF-BE11-43D110918811@oracle.com> Ho Roger, I mostly focused on the specification. Paul. Process -- 35 * {@code Process} provides control of native processes started by 36 * ProcessBuilder.start and Runtime.exec. Link to those methods? 92 /** 93 * Default constructor for Process. 94 */ 95 public Process() {} Is that redundant? 251 /** 252 * Kills the subprocess forcibly. The subprocess represented by this 253 * {@code Process} object is forcibly terminated. 254 * Forcible process destruction is defined as the immediate termination of a 255 * process, whereas normal termination allows a process to shut down cleanly. 256 * If the process is not alive, no action is taken. 257 *

258 * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is 259 * {@link java.util.concurrent.CompletableFuture#complete completed} 260 * when the process has terminated. 261 * 262 *

The default implementation of this method invokes {@link #destroy} 263 * and so may not forcibly terminate the process. 264 * Concrete implementations of this class are strongly encouraged to override 265 * this method with a compliant implementation. 266 * Invoking this method on {@code Process} objects returned by 267 * {@link ProcessBuilder#start} and {@link Runtime#exec} forcibly terminate 268 * the process. 269 * Use @ImplNote? 270 *

Note: The subprocess may not terminate immediately. 271 * i.e. {@code isAlive()} may return true for a brief period 272 * after {@code destroyForcibly()} is called. This method 273 * may be chained to {@code waitFor()} if needed. 274 * Use @apiNote? 361 * If the process is {@link #isAlive not alive} the {@link CompletableFuture} 362 * is immediately {@link java.util.concurrent.CompletableFuture#complete completed}. s/is immediately/is returned/ ? 390 * When the {@link #waitFor()} returns successfully the CompletableFuture is 391 * {@link java.util.concurrent.CompletableFuture#complete completed} regardless 392 * of the exit status of the process. s/When the/When / 406 * @return a {@code CompletableFuture} for the Process; 407 * a unique instance is returned for each call to {@code onExit}. 408 * Any need to mention about unique instances? 429 /** 430 * Returns a ProcessHandle for the Process. 431 * Some methods talk about "the subprocess" where as others talk about "the Process" and others "the process". 437 * @implSpec 438 * This implementation throws an instance of 439 * {@link java.lang.UnsupportedOperationException} and performs no other action. 440 * Sub-types should override this method to provide a ProcessHandle for the 441 * process. The methods {@link #getPid}, {@link #info}, {@link #children}, 442 * and {@link #allChildren}, unless overridden, operate on the ProcessHandle. IIRC i incorrectly suggested Sub-types rather than Subclasses. There are other places with similar requirements where we can use the same language (e.g. destroyForcibly and onExit) "Subclasses should override this method...." 456 /** 457 * Returns a snapshot of information about the process. 458 * 459 *

An {@link ProcessHandle.Info} instance has various accessor methods 460 * that return information about the process, if the process is alive and 461 * the information is available, otherwise {@code null} is returned. 462 * 463 * @implSpec 464 * This implementation returns information about the process as: 465 * {@link #toHandle toHandle().info()}. 466 * 467 * @return a snapshot of information about the process; non-null Dangling "non-null". Do you mean it's can never be null or ", otherwise null if the process is not alive or such information is not available"? I suspect the former now all Info methods return Optional. 480 * Note that processes are created and terminate asynchronously. 481 * There is no guarantee that a process is {@link #isAlive alive}. 482 * s/terminate/terminated/ ProcessHandle -- 79 * For example, EPERM on Linux. I presume you are referring to native process-related operations that return an error code of EPERM? 86 /** 87 * Returns the native process ID of the process. The native process ID is an 88 * identification number that the operating system assigns to the process. 89 * 90 * @return the native process ID of the process 91 * @throws UnsupportedOperationException if the implementation 92 * does not support this operation 93 */ 94 long getPid(); In what cases could this throw a USO if the static "of "method did not? 167 /** 168 * Returns a snapshot of all processes visible to the current process. 169 *

170 * Note that processes are created and terminate asynchronously. There 171 * is no guarantee that a process in the list is alive or that no other 172 * processes may have been created since the inception of the snapshot. 173 * Talks about "list". 192 * @return a snapshot of information about the process; non-null As for Process.info. 196 /** 197 * Information snapshot about a process. 198 * The attributes of a process vary by operating system and not available 199 * in all implementations. Information about processes is limited s/and not/and are not/ 260 * If the process is {@link #isAlive not alive} the {@link CompletableFuture} 261 * is immediately {@link java.util.concurrent.CompletableFuture#complete completed}. As for Process.onExit. 326 * @return an {@code Optional} for the process to be 327 * forcibly destroyed; 328 * the {@code Optional} has the value of the ProcessHandle 329 * if the request to terminate was successful, otherwise it is empty 330 * @throws IllegalStateException if the process is the current process 331 */ 332 Optional destroyForcibly(); Under what cases would an empty optional be returned? e.g. if native permissions are not granted? 345 * Compares this ProcessHandle with the specified object for order. s/with the specification object for order./with another process handle./ ? ProcessHandleImpl -- 317 @Override 318 public Optional destroyForcibly() { 319 if (this.equals(current)) { 320 throw new IllegalStateException("destroy of current process not allowed"); 321 } 322 return (destroy0(getPid(), false)) 323 ? Optional.of(this) : Optional.empty(); 324 } Should pass "true" to destroy0? Paul. On May 11, 2015, at 5:49 PM, Roger Riggs wrote: > Please review clarifications and updates to the proposed Precess API. > > A few loose ends in the ProcessHandle API were identified. > > 1) The ProcessHandle.parent() method currently returns null if the parent cannot > be determined and the ProcessHandle.of(PID) method returns null if the PID does not exist. > It has been suggested to return an Optional to make > these methods more flexible and allow a fluent style and work better with streams. > > 2) The behavior of Processhandle.destroy and destroyForcibly are different > than Process.destroy and destroyForcibly. Those functions always succeed because > they are children of the spawning process. > > In contrast, ProcessHandle.destroy and destroyForcible are requests to > destroy the process and may not succeed due to operating system restrictions such > as the process not being a child or not having enough privilege. > The description of the methods needs to be clarified that it is a request to destroy > and it may not succeed, In that case the destroy and destroyForcibly methods > should indicate that the request was not successful. In particular, the caller > may not want to wait for the process to terminate (its not going to). > > The proposed update is to return an Optional . > It can be streamed and can take advantage of the conditional operations on the Optional. > > 3) Using Optional is also attractive for the return values of the information > about a ProcessHandles, since not all values are available from every OS. > The returns values of Info.command, arguments, startInstant, totalDuration, and user > are proposed to be updated to return Optional. > It allows for more compact code and fewer explicit checks for null. > > Please review and comment: > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-ph/ > > javadoc: > http://cr.openjdk.java.net/~rriggs/ph-apidraft/ > > Diffs of the spec/javadoc from previous draft: > http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-11/overview-summary.html > > Thanks, Roger > > > From paul.sandoz at oracle.com Mon May 18 12:07:20 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 18 May 2015 14:07:20 +0200 Subject: RFR 8072853: SimpleScriptContext used by NashornScriptEngine doesn't completely complies to the spec regarding exception throwing In-Reply-To: <5559C294.8070401@oracle.com> References: <5559C294.8070401@oracle.com> Message-ID: <86210FE7-2265-4D1C-94A9-EBC6E01D23A9@oracle.com> On May 18, 2015, at 12:44 PM, A. Sundararajan wrote: > Please review http://cr.openjdk.java.net/~sundar/8072853/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8072853 > Changes to SimpleScriptContext look good. Test-wise you could reduce the duplication with a method accepting Consumer. e.g. @Test public void getAttributeEmptyName() { test(sc -> sc.getAttribute("", ScriptContext.GLOBAL_SCOPE)); } void test(Consumer c) { for (ScriptEngineFactory fac : getFactories()) { ScriptContext sc = fac.getScriptEngine().getContext(); String name = fac.getEngineName(); try { c.accept(sc); throw new RuntimeException("no exception for " + name); } catch (IllegalArgumentException iae) { System.out.println("got " + iae + " as expected for " + name); } } } Paul. From dmitry.samersoff at oracle.com Mon May 18 12:17:31 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Mon, 18 May 2015 15:17:31 +0300 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55573C86.8030807@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> Message-ID: <5559D85B.2050500@oracle.com> Everyone, Please review updated version of the fix: http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ Most important part of the fix provided by Peter Levart, so all credentials belongs to him. -Dmitry On 2015-05-16 15:48, Peter Levart wrote: > > > On 05/16/2015 02:38 PM, Peter Levart wrote: >> >> >> On 05/16/2015 09:35 AM, Dmitry Samersoff wrote: >>> Derek, >>> >>> Personally, I'm for volatile over explicit fence too. >>> >>> So I'll change the code if Peter don't have objections. >> >> There are no objections. There's one unneeded volatile store to .next >> field then in enqueue(), but it is followed by another volatile store, >> so there shouldn't be overhead on Intel and SPARC at least. >> >> Regards, Peter > > If you make .next field volatile, then perhaps you could also cache it's > value in reallyPoll() into a local variable, so that it is not read > twice. Like this: > > private Reference reallyPoll() { /* Must hold lock */ > Reference r = head; > if (r != null) { > Reference rn = r.next; // HERE !!! > head = (rn == r) ? > null : > rn; // Unchecked due to the next field having a raw type > in Reference > r.queue = NULL; > r.next = r; > queueLength--; > if (r instanceof FinalReference) { > sun.misc.VM.addFinalRefCount(-1); > } > return r; > } > return null; > } > > > > Peter > > >> >>> -Dmitry >>> >>> On 2015-05-16 01:59, Derek White wrote: >>>> Hi Dmitry, Peter, >>>> >>>> I should read my email more frequently - I missed Dmitry's last webrev >>>> email. >>>> >>>> My comments on a preference for volatile over Unsafe are not a strong >>>> objection to using Unsafe fences. I just don't have enough experience >>>> with Unsafe fences yet to agree that this use is correct. >>>> >>>> While looking over this Reference code I found 3-6 really simple things >>>> that need cleaning up that have been there for years, so I'm not a big >>>> cheerleader for more complicated things here :-) >>>> >>>> - Derek >>>> >>>> On 5/15/15 6:46 PM, Derek White wrote: >>>>> Hi Peter, >>>>> >>>>> Some comments below... >>>>> >>>>> On 5/14/15 3:50 AM, Peter Levart wrote: >>>>>> Hi Derek, >>>>>> >>>>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>>>> Hi Peter, >>>>>>> >>>>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>>>> but I have some concerns... >>>>>> I did have a concern too, ... >>>>>> >>>>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>>>> Hi Dmitry, >>>>>>>> >>>>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>>>> logical. >>>>>>>> >>>>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>>>> threads for the entire time of iteration. This can blow up the >>>>>>>> application. Suppose one wants to diagnose the application because >>>>>>>> he suspects that finalizer thread hardly keeps up with production >>>>>>>> of finalizable instances. This can happen if the allocation rate of >>>>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>>>>>> up gradually and is already holding several million objects. Now >>>>>>>> you initiate the diagnostic command to print the queue. The >>>>>>>> iteration over and grouping/counting of several millions of >>>>>>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>>>>>> reference handler thread. But does not block the threads that >>>>>>>> allocate finalizable objects. By the time the iteration is over, >>>>>>>> the JVM blows up and application slows down to a halt doing GCs >>>>>>>> most of the time, getting OOMEs, etc... >>>>>>>> >>>>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>>>> purposes without holding a lock. The modification required to do >>>>>>>> that is the following (havent tested this, but I think it should work): >>>>>>>> >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>>>> >>>>>>> One issue to watch out for is the garbage collectors inspect the >>>>>>> Reference.next field from C code directly (to distinguish active vs. >>>>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>>>> >>>>>>> Your change makes "inactive" References superficially look like >>>>>>> "enqueued" References. The GC code is rather subtle and I haven't >>>>>>> yet seen a case where it would get confused by this change, but >>>>>>> there could easily be something like that lurking in the GC code. >>>>>> ...but then I thought that GC can in no way treat a Reference >>>>>> differently whether it is still enqueued in a ReferenceQueue or >>>>>> already dequeued (inactive) - responsibility is already on the Java >>>>>> side. Currently the definition of Reference.next is this: >>>>>> >>>>>> /* When active: NULL >>>>>> * pending: this >>>>>> * Enqueued: next reference in queue (or this if last) >>>>>> * Inactive: this >>>>>> */ >>>>>> @SuppressWarnings("rawtypes") >>>>>> Reference next; >>>>>> >>>>>> We see that, unless GC inspects all ReferenceQueue instances and >>>>>> scans their lists too, the state of a Reference that is enqueued as >>>>>> last in list is indistinguishable from the state of inactive >>>>>> Reference. So I deduced that this distinction (enqueued/inactive) >>>>>> can't be established solely on the value of .next field ( == this or >>>>>> != this)... >>>>>> >>>>>> But I should inspect the GC code too to build a better understanding >>>>>> of that part of the story... >>>>>> >>>>>> Anyway. It turns out that there is already enough state in Reference >>>>>> to destinguish between it being enqueued as last in list and already >>>>>> dequeued (inactive) - the additional state is Reference.queue that >>>>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>>>> (r.next and r.queue) are assigned and read in correct order. This can >>>>>> be achieved either by making Reference.next a volatile field or by a >>>>>> couple of explicit fences: >>>>>> >>>>>> >>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>>>> >>>>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>>>> before linking the reference into the queue's head in >>>>>> ReferenceQueue.enqueue(): >>>>>> >>>>>> r.queue = ENQUEUED; >>>>>> r.next = (head == null) ? r : head; >>>>>> head = r; >>>>>> >>>>>> Both stores are volatile. >>>>> This sounds a bit better. I don't have a good handle on the pros and >>>>> cons of a volatile field over explicit fences via Unsafe in this case. >>>>> Kim might jump in soon. >>>>> >>>>> I'd like to suggest an entirely less-clever solution. Since the >>>>> problem is that forEach() might see inconsistent values for the queue >>>>> and next fields of a Reference, but we don't want to grab a lock >>>>> walking the whole queue, we could instead grab the lock as we look at >>>>> each Reference (and do the "back-up" trick if we were interfered >>>>> with). Of course this is slower than going lock-free, but it's not any >>>>> more overhead than the ReferenceHandler thread or FinalizerThreads incur. >>>>> >>>>> The only benefit of this solution over the others is that it is less >>>>> clever, and I'm not sure how much cleverness this problem deserves. >>>>> Given that, and ranking the solutions as "lock" < (clever) "volatile" >>>>> < "fence", I'd be happier with the "volatile" or "lock" solution if >>>>> that is sufficient. >>>>> >>>>> - Derek >>>>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>>>> forEach iteration method with no concrete logic. >>>>>>>> >>>>>>>> It would be possible to encapsulate the entire logic into a special >>>>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>>>> static method(s) (printFinalizationQueue)... You could just expose >>>>>>>> a package-private forEach static method from Finalizer and code the >>>>>>>> rest in DiagnosticCommands. >>>>>>> That's good for encapsulation. But I'm concerned that if "forEach" >>>>>>> got exposed beyond careful use in DiagnosticCommands, and the >>>>>>> Referents were leaked back into the heap, then we could get >>>>>>> unexpected object resurrection after finalization. This isn't a bug >>>>>>> on it's own - any finalizer might resurrect its object if not >>>>>>> careful, but ordinarily /only/ the finalizer could resurrect the >>>>>>> object. This could invalidate application invariants? >>>>>> Well, it all stays in the confines of package-private API - internal >>>>>> to JDK. Any future additional use should be reviewed carefully. >>>>>> Comments on the forEach() method should warn about that. >>>>>> >>>>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>>>> /another/ case of diagnostics affecting application behavior. And >>>>>>> there are pathological scenarios where this gets severe. This is >>>>>>> unfortunate but not uncommon. There is enough complication here that >>>>>>> you should be sure that the fix for diagnostics performance doesn't >>>>>>> introduce subtle bugs to the system in general. A change in this >>>>>>> area should get a thorough review from both the runtime and GC sides. >>>>>> Is the webrev.02 proposed above more acceptable in that respect? It >>>>>> does not introduce any logical changes to existing code. >>>>>> >>>>>>> Better yet, the reference handling code in GC and runtime should >>>>>>> probably be thrown out and re-written, but that's another issue :-) >>>>>> I may have some proposals in that direction. Stay tuned. >>>>>> >>>>>> Regards, Peter >>>>>> >>>>>>> - Derek >>>>>>> >>>>>>>> Regards, Peter >>>>>>>> >>>>>>>> >>>>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>>>> Everybody, >>>>>>>>> >>>>>>>>> Updated version: >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>>>> >>>>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>>>> >>>>>>>>> -Dmitry >>>>>>>>> >>>>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>> >>>>>>>>>> Lots of good comments here. >>>>>>>>>> >>>>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>>>> general iterator and lambda. >>>>>>>>>> >>>>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>>>> >>>>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>>>> >>>>>>>>>> The sorting suggestion is a nice touch. >>>>>>>>>> >>>>>>>>>> - Derek White, GC team >>>>>>>>>> >>>>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>> >>>>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>>>> Dmitry, >>>>>>>>>>>> >>>>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>>>> >>>>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>>>> running out of memory. >>>>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>>>> >>>>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>>>> interfere with synchronization? >>>>>>>>>>> >>>>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>>>> >>>>>>>>>>> private void remove() { >>>>>>>>>>> synchronized (lock) { >>>>>>>>>>> if (unfinalized == this) { >>>>>>>>>>> if (this.next != null) { >>>>>>>>>>> unfinalized = this.next; >>>>>>>>>>> } else { >>>>>>>>>>> unfinalized = this.prev; >>>>>>>>>>> } >>>>>>>>>>> } >>>>>>>>>>> if (this.next != null) { >>>>>>>>>>> this.next.prev = this.prev; >>>>>>>>>>> } >>>>>>>>>>> if (this.prev != null) { >>>>>>>>>>> this.prev.next = this.next; >>>>>>>>>>> } >>>>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>>>> traverse the list unsynchronized >>>>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>>>> finalized */ >>>>>>>>>>> } >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>>>> pointer could be used instead: >>>>>>>>>>> >>>>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>>>> return (prev == this); >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>>>> >>>>>>>>>>> private void add() { >>>>>>>>>>> synchronized (lock) { >>>>>>>>>>> if (unfinalized != null) { >>>>>>>>>>> this.next = unfinalized; >>>>>>>>>>> unfinalized.prev = this; >>>>>>>>>>> } >>>>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>>>> // instance fully initialized >>>>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>>>> U.storeFence(); >>>>>>>>>>> unfinalized = this; >>>>>>>>>>> } >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>>>> >>>>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>>>> out? >>>>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>>>> two purposes: >>>>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>>>> >>>>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>>>> finalize() method. >>>>>>>>>>> >>>>>>>>>>> Regards, Peter >>>>>>>>>>> >>>>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>>>> >>>>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>>>> permission() and limit access: >>>>>>>>>>>> >>>>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>>>> "monitor", NULL}; >>>>>>>>>>>> return p; >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>>>> >>>>>>>>>>>> Thanks, >>>>>>>>>>>> /Staffan >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> Everyone, >>>>>>>>>>>>> >>>>>>>>>>>>> Please review the fix: >>>>>>>>>>>>> >>>>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>>>> >>>>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>>>> >>>>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>>>> with count >>>>>>>>>>>>> >>>>>>>>>>>>> -Dmitry >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>>>> * I would love to change the world, but they won't give me the sources. >> > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From marcus.lagergren at oracle.com Mon May 18 12:27:28 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Mon, 18 May 2015 14:27:28 +0200 Subject: RFR 8072853: SimpleScriptContext used by NashornScriptEngine doesn't completely complies to the spec regarding exception throwing In-Reply-To: <5559C294.8070401@oracle.com> References: <5559C294.8070401@oracle.com> Message-ID: +1 /M > On 18 May 2015, at 12:44, A. Sundararajan wrote: > > Please review http://cr.openjdk.java.net/~sundar/8072853/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8072853 > > Thanks, > -Sundar From sundararajan.athijegannathan at oracle.com Mon May 18 12:59:56 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 18 May 2015 18:29:56 +0530 Subject: RFR 8072853: SimpleScriptContext used by NashornScriptEngine doesn't completely complies to the spec regarding exception throwing In-Reply-To: <86210FE7-2265-4D1C-94A9-EBC6E01D23A9@oracle.com> References: <5559C294.8070401@oracle.com> <86210FE7-2265-4D1C-94A9-EBC6E01D23A9@oracle.com> Message-ID: <5559E24C.1000006@oracle.com> Thanks for the review. Updated test as per your suggestion. Uploaded fresh review @ http://cr.openjdk.java.net/~sundar/8072853/webrev.01/ Thanks -Sundar Paul Sandoz wrote: > On May 18, 2015, at 12:44 PM, A. Sundararajan wrote: > > >> Please review http://cr.openjdk.java.net/~sundar/8072853/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8072853 >> >> > > Changes to SimpleScriptContext look good. > > Test-wise you could reduce the duplication with a method accepting Consumer. > > e.g. > > @Test > public void getAttributeEmptyName() { > test(sc -> sc.getAttribute("", ScriptContext.GLOBAL_SCOPE)); > } > > void test(Consumer c) { > for (ScriptEngineFactory fac : getFactories()) { > ScriptContext sc = fac.getScriptEngine().getContext(); > String name = fac.getEngineName(); > try { > c.accept(sc); > throw new RuntimeException("no exception for " + name); > } catch (IllegalArgumentException iae) { > System.out.println("got " + iae + " as expected for " + name); > } > } > } > > Paul. > From denis.kononenko at oracle.com Mon May 18 13:03:45 2015 From: denis.kononenko at oracle.com (denis kononenko) Date: Mon, 18 May 2015 16:03:45 +0300 Subject: RFR(XS): JDK-8077866: [TESTBUG] Some of java.lang tests cannot be run on compact profiles 1, 2 Message-ID: <5559E331.70208@oracle.com> Hi All, Please review the very small change in TEST.groups file. Webrev link: http://cr.openjdk.java.net/~skovalev/dkononen/8077866/webrev.00/ Bug id: JDK-8077866 Testing: automated Description: The following tests cannot be run on compact profiles 1 and 2: java/lang/invoke/lambda/LambdaStackTrace.java: requires javax.tools.StandardJavaFileManager (JEP-161, available in Compact Profile 3); java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java: inherits from the LambdaFormTestCase class which, in turn, has dependency on java.lang.management package (JEP-161, available in Compact Profile 3); java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java: the same as above; java/lang/invoke/LFCaching/LFGarbageCollectedTest.java the same as above; The fix simply adds these tests into the :needs_compact3 group. Thank you, Denis. From vladimir.x.ivanov at oracle.com Mon May 18 13:05:41 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Mon, 18 May 2015 16:05:41 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> <55533CAE.3050201@oracle.com> <55549297.5020002@oracle.com> <5555E343.5050600@oracle.com> Message-ID: <5559E3A5.8030108@oracle.com> Thanks, John. What do you think about the following version: http://cr.openjdk.java.net/~vlivanov/8079205/webrev.04 Best regards, Vladimir Ivanov On 5/15/15 8:06 PM, John Rose wrote: > I know injected fields are somewhat hacky, but there are a couple of conditions here which would motivate their use: > > 1. The field is of a type not known to Java. Usually, and in this case, it is a C pointer to some metadata. > > We can make space for it with a Java long, but that is a size mismatch on 32-bit systems. Such mismatches have occasionally caused bugs on big-endian systems, although we try to defend against them by using long-wise reads followed by casts. > > 2. The field is useless to Java code, and would be a vulnerability if somebody found a way to touch it from Java. > > In both these ways the 'dependencies' field is like the MemberName.vmtarget field. (Suggestion: s/dependencies/vmdependencies/ to follow that pattern.) > > ? John > > On May 15, 2015, at 5:14 AM, Vladimir Ivanov wrote: >> >> After private discussion with Paul, here's an update: >> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.03 >> >> Renamed CallSite$Context to MethodHandleNatives$Context. >> >> Best regards, >> Vladimir Ivanov >> >> On 5/14/15 3:18 PM, Vladimir Ivanov wrote: >>> Small update in JDK code (webrev updated in place): >>> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 >>> >>> Changes: >>> - hid Context.dependencies field from Reflection >>> - new test case: CallSiteDepContextTest.testHiddenDepField() >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> On 5/13/15 5:56 PM, Paul Sandoz wrote: >>>> >>>> On May 13, 2015, at 1:59 PM, Vladimir Ivanov >>>> wrote: >>>> >>>>> Peter, Paul, thanks for the feedback! >>>>> >>>>> Updated the webrev in place: >>>>> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.02 >>>>> >>>> >>>> +1 >>>> >>>> >>>>>> I am not an export in the HS area but the code mostly made sense to >>>>>> me. I also like Peter's suggestion of Context implementing Runnable. >>>>> I agree. Integrated. >>>>> >>>>>> Some minor comments. >>>>>> >>>>>> CallSite.java: >>>>>> >>>>>> 145 private final long dependencies = 0; // Used by JVM to >>>>>> store JVM_nmethodBucket* >>>>>> >>>>>> It's a little odd to see this field be final, but i think i >>>>>> understand the motivation as it's essentially acting as a memory >>>>>> address pointing to the head of the nbucket list, so in Java code >>>>>> you don't want to assign it to anything other than 0. >>>>> Yes, my motivation was to forbid reads & writes of the field from >>>>> Java code. I was experimenting with injecting the field by VM, but >>>>> it's less attractive. >>>>> >>>> >>>> I was wondering if that were possible. >>>> >>>> >>>>>> Is VM access, via java_lang_invoke_CallSite_Context, affected by >>>>>> treating final fields as really final in the j.l.i package? >>>>> No, field modifiers aren't respected. oopDesc::*_field_[get|put] does >>>>> a raw read/write using field offset. >>>>> >>>> >>>> Ok. >>>> >>>> Paul. >>>> > From marcus.lagergren at oracle.com Mon May 18 13:07:50 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Mon, 18 May 2015 15:07:50 +0200 Subject: RFR 8072853: SimpleScriptContext used by NashornScriptEngine doesn't completely complies to the spec regarding exception throwing In-Reply-To: <5559E24C.1000006@oracle.com> References: <5559C294.8070401@oracle.com> <86210FE7-2265-4D1C-94A9-EBC6E01D23A9@oracle.com> <5559E24C.1000006@oracle.com> Message-ID: Also +1 > On 18 May 2015, at 14:59, A. Sundararajan wrote: > > Thanks for the review. Updated test as per your suggestion. Uploaded fresh review @ http://cr.openjdk.java.net/~sundar/8072853/webrev.01/ > > Thanks > -Sundar > > Paul Sandoz wrote: >> On May 18, 2015, at 12:44 PM, A. Sundararajan wrote: >> >> >>> Please review http://cr.openjdk.java.net/~sundar/8072853/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8072853 >>> >>> >> >> Changes to SimpleScriptContext look good. >> >> Test-wise you could reduce the duplication with a method accepting Consumer. >> >> e.g. >> >> @Test >> public void getAttributeEmptyName() { >> test(sc -> sc.getAttribute("", ScriptContext.GLOBAL_SCOPE)); >> } >> >> void test(Consumer c) { >> for (ScriptEngineFactory fac : getFactories()) { >> ScriptContext sc = fac.getScriptEngine().getContext(); >> String name = fac.getEngineName(); >> try { >> c.accept(sc); >> throw new RuntimeException("no exception for " + name); >> } catch (IllegalArgumentException iae) { >> System.out.println("got " + iae + " as expected for " + name); >> } >> } >> } >> >> Paul. >> > From paul.sandoz at oracle.com Mon May 18 13:20:13 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 18 May 2015 15:20:13 +0200 Subject: RFR 8072853: SimpleScriptContext used by NashornScriptEngine doesn't completely complies to the spec regarding exception throwing In-Reply-To: <5559E24C.1000006@oracle.com> References: <5559C294.8070401@oracle.com> <86210FE7-2265-4D1C-94A9-EBC6E01D23A9@oracle.com> <5559E24C.1000006@oracle.com> Message-ID: <6EF84EA2-2EE4-4256-92F4-97C9166D9D85@oracle.com> On May 18, 2015, at 2:59 PM, A. Sundararajan wrote: > Thanks for the review. Updated test as per your suggestion. Uploaded fresh review @ http://cr.openjdk.java.net/~sundar/8072853/webrev.01/ > +1 Paul. From alexander.v.stepanov at oracle.com Mon May 18 14:08:18 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Mon, 18 May 2015 17:08:18 +0300 Subject: RFR [9] 8080422: some docs cleanup for core libs In-Reply-To: <55562A02.3000009@oracle.com> References: <55562A02.3000009@oracle.com> Message-ID: <5559F252.1020906@oracle.com> Please see the updated webrev http://cr.openjdk.java.net/~avstepan/8080422/webrev.01/ - some misprints were fixed as well (not 100% sure if "comparision" should be replaced with "comparison", but the latter looks more suitable). Thanks, Alexander On 15.05.2015 20:16, alexander stepanov wrote: > Hello, > > Could you please review the following fix > http://cr.openjdk.java.net/~avstepan/8080422/webrev.00/ > for > https://bugs.openjdk.java.net/browse/JDK-8080422 > > Just some HTML markup fix. > > The affected packages should (probably) not be visible in the new > modular system, but nevertheless... > > Thanks, > Alexander > From Mohammad.Rezaei at gs.com Mon May 18 14:24:18 2015 From: Mohammad.Rezaei at gs.com (Rezaei, Mohammad A.) Date: Mon, 18 May 2015 10:24:18 -0400 Subject: JEP 254: Compact Strings In-Reply-To: <20150514230513.0363C62D05@eggemoggin.niobe.net> References: <20150514230513.0363C62D05@eggemoggin.niobe.net> Message-ID: <6882C9A35DFB9B4FA2779F7BF5B9757D20761165B8@GSCMAMP06EX.firmwide.corp.gs.com> For what it's worth, we would welcome this change. We took a large memory hit and a small performance hit when we upgraded from 1.6 to 1.7 in some of our memory-bound applications. >From a purely performance perspective, the most expensive CPU operations are memory access these days. Anything that halves memory reads will likely produce better performance. >From an implementation perspective, having used 1.6's compressed strings feature in production, we are comfortable that none of our code, nor any of our dependencies rely on String internal representation in such a way as to cause a significant backward compatibility issue. Thanks Moh >-----Original Message----- >From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] On Behalf >Of mark.reinhold at oracle.com >Sent: Thursday, May 14, 2015 7:05 PM >To: xueming.shen at oracle.com >Cc: core-libs-dev at openjdk.java.net >Subject: JEP 254: Compact Strings > >New JEP Candidate: http://openjdk.java.net/jeps/254 > >- Mark From vitalyd at gmail.com Mon May 18 14:35:40 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Mon, 18 May 2015 10:35:40 -0400 Subject: JEP 254: Compact Strings In-Reply-To: <6882C9A35DFB9B4FA2779F7BF5B9757D20761165B8@GSCMAMP06EX.firmwide.corp.gs.com> References: <20150514230513.0363C62D05@eggemoggin.niobe.net> <6882C9A35DFB9B4FA2779F7BF5B9757D20761165B8@GSCMAMP06EX.firmwide.corp.gs.com> Message-ID: > > From a purely performance perspective, the most expensive CPU operations > are memory access these days. Very true ... for random accesses. Anything that halves memory reads will likely produce better performance. This part is a bit unclear for the proposed changes. While it's true that single byte encoding will be denser than two byte, most string ops end up walking the backing store linearly; prefetch (either implicit h/w or software-assisted) could hide the memory access latency. Personally, what I'd like to see is fusing storage of String with its backing data, irrespective of encoding (i.e. removing the indirection to fetch the char[] or byte[]). On Mon, May 18, 2015 at 10:24 AM, Rezaei, Mohammad A. < Mohammad.Rezaei at gs.com> wrote: > For what it's worth, we would welcome this change. We took a large memory > hit and a small performance hit when we upgraded from 1.6 to 1.7 in some of > our memory-bound applications. > > From a purely performance perspective, the most expensive CPU operations > are memory access these days. Anything that halves memory reads will likely > produce better performance. > > From an implementation perspective, having used 1.6's compressed strings > feature in production, we are comfortable that none of our code, nor any of > our dependencies rely on String internal representation in such a way as to > cause a significant backward compatibility issue. > > Thanks > Moh > > >-----Original Message----- > >From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] On > Behalf > >Of mark.reinhold at oracle.com > >Sent: Thursday, May 14, 2015 7:05 PM > >To: xueming.shen at oracle.com > >Cc: core-libs-dev at openjdk.java.net > >Subject: JEP 254: Compact Strings > > > >New JEP Candidate: http://openjdk.java.net/jeps/254 > > > >- Mark > From Roger.Riggs at Oracle.com Mon May 18 14:43:46 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 18 May 2015 10:43:46 -0400 Subject: RFR [9] 8080422: some docs cleanup for core libs In-Reply-To: <5559F252.1020906@oracle.com> References: <55562A02.3000009@oracle.com> <5559F252.1020906@oracle.com> Message-ID: <5559FAA2.5090801@Oracle.com> Hi Alexander, Thanks for these needed cleanups; a few corrections below. 1) src/java.base/share/classes/jdk/internal/util/xml/impl/Parser.java: "The grammar *which *this method can read is" can remove the 'which' 2) src/java.base/share/classes/sun/misc/CharacterEncoder.java: 107 The {@code } is confusing, typically @code marks a literal but in this case it is a symbol for the new line character. Perhaps use only "newline" without any special chars, as is used in PrintStream. src/java.base/share/classes/sun/misc/ExtensionDependency.java: 106 Correct the spelling of attriutes: - * @param jarFile containing the *attriutes *declaring the dependencies + * @param jar containing the *attributes *declaring the dependencies 3) src/java.base/share/classes/sun/misc/resources/Messages_de.java: 26 Please use {@code instead of ... - *

This class represents the ResourceBundle + * This class represents the ResourceBundle 4) Ditto all of the files in: src/java.base/share/classes/sun/misc/resources/Messages_* files: Thanks, Roger On 5/18/2015 10:08 AM, alexander stepanov wrote: > Please see the updated webrev > http://cr.openjdk.java.net/~avstepan/8080422/webrev.01/ > - some misprints were fixed as well > (not 100% sure if "comparision" should be replaced with "comparison", > but the latter looks more suitable). > > Thanks, > Alexander > > On 15.05.2015 20:16, alexander stepanov wrote: >> Hello, >> >> Could you please review the following fix >> http://cr.openjdk.java.net/~avstepan/8080422/webrev.00/ >> for >> https://bugs.openjdk.java.net/browse/JDK-8080422 >> >> Just some HTML markup fix. >> >> The affected packages should (probably) not be visible in the new >> modular system, but nevertheless... >> >> Thanks, >> Alexander >> > From ivan.gerasimov at oracle.com Mon May 18 15:16:57 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 18 May 2015 18:16:57 +0300 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: <441886D7-EEF0-48E5-87B3-A62E32ACB3E1@oracle.com> References: <55567ACB.2050307@oracle.com> <5556968D.9070401@oracle.com> <441886D7-EEF0-48E5-87B3-A62E32ACB3E1@oracle.com> Message-ID: <555A0269.3020805@oracle.com> Thanks Chris for your review! > This looks much better. Trivially I?d calculate the initial size like: > 510 / 0.75 + 1.0f ( plus 1 ) > I'll all +1 for extra accuracy. > ? but your regression test should prove that the plus one is not > needed. > > Maybe a comment that the 0.75 is the default load factor from HashMap. > Sure, I'll a comment too. > The constant could be removed and the ?510? be used directly in the > test. Since the test is whitebox. > > The test is fine, but could be a little less obscure if it looked at > the table size, rather than the equality. But what you have is fine. > I'd rather leave the named constant, as it seems just a bit less error-prone to me. I guess, this new test should not bring attention too often. Sincerely yours, Ivan > -Chris. > >> >> Comments, suggestions are welcome! >> >> Sincerely yours, >> Ivan >> >>> On Fri, May 15, 2015 at 4:01 PM, Ivan Gerasimov >>> >>> > wrote: >>> >>> Hello! >>> >>> When constructing the map, the expected size is specified to be >>> 256, but then 510 elements are inserted. >>> A new whitebox test is provided, so the next time the number of >>> entries grows, the expected size will not be forgotten. >>> >>> Would you please help review this fix? >>> >>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8080535 >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8080535/00/webrev/ >>> >>> >>> >>> Sincerely yours, >>> Ivan >>> >>> >> > From alexander.v.stepanov at oracle.com Mon May 18 15:36:38 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Mon, 18 May 2015 18:36:38 +0300 Subject: RFR [9] 8080422: some docs cleanup for core libs In-Reply-To: <5559FAA2.5090801@Oracle.com> References: <55562A02.3000009@oracle.com> <5559F252.1020906@oracle.com> <5559FAA2.5090801@Oracle.com> Message-ID: <555A0706.4010803@oracle.com> Hello Roger, Fixed; please see http://cr.openjdk.java.net/~avstepan/8080422/webrev.02/index.html Regards, Alexander On 18.05.2015 17:43, Roger Riggs wrote: > Hi Alexander, > > Thanks for these needed cleanups; a few corrections below. > > > > 1) src/java.base/share/classes/jdk/internal/util/xml/impl/Parser.java: > > "The grammar *which *this method can read is" can remove the 'which' > > > > 2) src/java.base/share/classes/sun/misc/CharacterEncoder.java: 107 > > The {@code } is confusing, typically @code marks a literal > but in this case it is a symbol for the new line character. > Perhaps use only "newline" without any special chars, as is used in > PrintStream. > > src/java.base/share/classes/sun/misc/ExtensionDependency.java: 106 > Correct the spelling of attriutes: > - * @param jarFile containing the *attriutes *declaring the > dependencies > + * @param jar containing the *attributes *declaring the dependencies > > > 3) src/java.base/share/classes/sun/misc/resources/Messages_de.java: 26 > Please use {@code instead of ... > - *

This class represents the ResourceBundle > + * This class represents the ResourceBundle > > 4) Ditto all of the files in: > src/java.base/share/classes/sun/misc/resources/Messages_* files: > > Thanks, Roger > > > > On 5/18/2015 10:08 AM, alexander stepanov wrote: >> Please see the updated webrev >> http://cr.openjdk.java.net/~avstepan/8080422/webrev.01/ >> - some misprints were fixed as well >> (not 100% sure if "comparision" should be replaced with "comparison", >> but the latter looks more suitable). >> >> Thanks, >> Alexander >> >> On 15.05.2015 20:16, alexander stepanov wrote: >>> Hello, >>> >>> Could you please review the following fix >>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.00/ >>> for >>> https://bugs.openjdk.java.net/browse/JDK-8080422 >>> >>> Just some HTML markup fix. >>> >>> The affected packages should (probably) not be visible in the new >>> modular system, but nevertheless... >>> >>> Thanks, >>> Alexander >>> >> > From lance.andersen at oracle.com Mon May 18 15:54:29 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Mon, 18 May 2015 11:54:29 -0400 Subject: RFR [9] 8080422: some docs cleanup for core libs In-Reply-To: <555A0706.4010803@oracle.com> References: <55562A02.3000009@oracle.com> <5559F252.1020906@oracle.com> <5559FAA2.5090801@Oracle.com> <555A0706.4010803@oracle.com> Message-ID: The revised changes seem OK in addition to the previous webrev Best Lance On May 18, 2015, at 11:36 AM, alexander stepanov wrote: > Hello Roger, > > Fixed; please see > http://cr.openjdk.java.net/~avstepan/8080422/webrev.02/index.html > > Regards, > Alexander > > On 18.05.2015 17:43, Roger Riggs wrote: >> Hi Alexander, >> >> Thanks for these needed cleanups; a few corrections below. >> >> >> >> 1) src/java.base/share/classes/jdk/internal/util/xml/impl/Parser.java: >> >> "The grammar *which *this method can read is" can remove the 'which' >> >> >> >> 2) src/java.base/share/classes/sun/misc/CharacterEncoder.java: 107 >> >> The {@code } is confusing, typically @code marks a literal >> but in this case it is a symbol for the new line character. >> Perhaps use only "newline" without any special chars, as is used in PrintStream. >> >> src/java.base/share/classes/sun/misc/ExtensionDependency.java: 106 >> Correct the spelling of attriutes: >> - * @param jarFile containing the *attriutes *declaring the dependencies >> + * @param jar containing the *attributes *declaring the dependencies >> >> >> 3) src/java.base/share/classes/sun/misc/resources/Messages_de.java: 26 >> Please use {@code instead of ... >> - *

This class represents the ResourceBundle >> + * This class represents the ResourceBundle >> >> 4) Ditto all of the files in: >> src/java.base/share/classes/sun/misc/resources/Messages_* files: >> >> Thanks, Roger >> >> >> >> On 5/18/2015 10:08 AM, alexander stepanov wrote: >>> Please see the updated webrev >>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.01/ >>> - some misprints were fixed as well >>> (not 100% sure if "comparision" should be replaced with "comparison", but the latter looks more suitable). >>> >>> Thanks, >>> Alexander >>> >>> On 15.05.2015 20:16, alexander stepanov wrote: >>>> Hello, >>>> >>>> Could you please review the following fix >>>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.00/ >>>> for >>>> https://bugs.openjdk.java.net/browse/JDK-8080422 >>>> >>>> Just some HTML markup fix. >>>> >>>> The affected packages should (probably) not be visible in the new modular system, but nevertheless... >>>> >>>> Thanks, >>>> Alexander >>>> >>> >> > 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 Mon May 18 16:01:10 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 18 May 2015 12:01:10 -0400 Subject: RFR [9] 8080422: some docs cleanup for core libs In-Reply-To: <555A0706.4010803@oracle.com> References: <55562A02.3000009@oracle.com> <5559F252.1020906@oracle.com> <5559FAA2.5090801@Oracle.com> <555A0706.4010803@oracle.com> Message-ID: <555A0CC6.6030100@Oracle.com> Hi Alexander, Thanks, Looks good to go to me. Roger On 5/18/2015 11:36 AM, alexander stepanov wrote: > Hello Roger, > > Fixed; please see > http://cr.openjdk.java.net/~avstepan/8080422/webrev.02/index.html > > Regards, > Alexander > > On 18.05.2015 17:43, Roger Riggs wrote: >> Hi Alexander, >> >> Thanks for these needed cleanups; a few corrections below. >> >> >> >> 1) src/java.base/share/classes/jdk/internal/util/xml/impl/Parser.java: >> >> "The grammar *which *this method can read is" can remove the 'which' >> >> >> >> 2) src/java.base/share/classes/sun/misc/CharacterEncoder.java: 107 >> >> The {@code } is confusing, typically @code marks a literal >> but in this case it is a symbol for the new line character. >> Perhaps use only "newline" without any special chars, as is used in >> PrintStream. >> >> src/java.base/share/classes/sun/misc/ExtensionDependency.java: 106 >> Correct the spelling of attriutes: >> - * @param jarFile containing the *attriutes *declaring the >> dependencies >> + * @param jar containing the *attributes *declaring the >> dependencies >> >> >> 3) src/java.base/share/classes/sun/misc/resources/Messages_de.java: 26 >> Please use {@code instead of ... >> - *

This class represents the ResourceBundle >> + * This class represents the ResourceBundle >> >> 4) Ditto all of the files in: >> src/java.base/share/classes/sun/misc/resources/Messages_* files: >> >> Thanks, Roger >> >> >> >> On 5/18/2015 10:08 AM, alexander stepanov wrote: >>> Please see the updated webrev >>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.01/ >>> - some misprints were fixed as well >>> (not 100% sure if "comparision" should be replaced with >>> "comparison", but the latter looks more suitable). >>> >>> Thanks, >>> Alexander >>> >>> On 15.05.2015 20:16, alexander stepanov wrote: >>>> Hello, >>>> >>>> Could you please review the following fix >>>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.00/ >>>> for >>>> https://bugs.openjdk.java.net/browse/JDK-8080422 >>>> >>>> Just some HTML markup fix. >>>> >>>> The affected packages should (probably) not be visible in the new >>>> modular system, but nevertheless... >>>> >>>> Thanks, >>>> Alexander >>>> >>> >> > From alexander.v.stepanov at oracle.com Mon May 18 16:02:32 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Mon, 18 May 2015 19:02:32 +0300 Subject: RFR [9] 8080422: some docs cleanup for core libs In-Reply-To: References: <55562A02.3000009@oracle.com> <5559F252.1020906@oracle.com> <5559FAA2.5090801@Oracle.com> <555A0706.4010803@oracle.com> Message-ID: <555A0D18.3060803@oracle.com> Hello, Lance, Roger, Thanks! P.S. sorry - one minor change after the review - a list was added in ExtensionDependency.java: http://cr.openjdk.java.net/~avstepan/8080422/webrev.02/src/java.base/share/classes/sun/misc/ExtensionDependency.java.udiff.html (please update the page). Regards, Alexander On 18.05.2015 18:54, Lance Andersen wrote: > The revised changes seem OK in addition to the previous webrev > > Best > Lance > On May 18, 2015, at 11:36 AM, alexander stepanov > > wrote: > >> Hello Roger, >> >> Fixed; please see >> http://cr.openjdk.java.net/~avstepan/8080422/webrev.02/index.html >> >> >> Regards, >> Alexander >> >> On 18.05.2015 17:43, Roger Riggs wrote: >>> Hi Alexander, >>> >>> Thanks for these needed cleanups; a few corrections below. >>> >>> >>> >>> 1) src/java.base/share/classes/jdk/internal/util/xml/impl/Parser.java: >>> >>> "The grammar *which *this method can read is" can remove the 'which' >>> >>> >>> >>> 2) src/java.base/share/classes/sun/misc/CharacterEncoder.java: 107 >>> >>> The {@code } is confusing, typically @code marks a literal >>> but in this case it is a symbol for the new line character. >>> Perhaps use only "newline" without any special chars, as is used in >>> PrintStream. >>> >>> src/java.base/share/classes/sun/misc/ExtensionDependency.java: 106 >>> Correct the spelling of attriutes: >>> - * @param jarFile containing the *attriutes *declaring the >>> dependencies >>> + * @param jar containing the *attributes *declaring the >>> dependencies >>> >>> >>> 3) src/java.base/share/classes/sun/misc/resources/Messages_de.java: 26 >>> Please use {@code instead of ... >>> - *

This class represents the ResourceBundle >>> + * This class represents the ResourceBundle >>> >>> 4) Ditto all of the files in: >>> src/java.base/share/classes/sun/misc/resources/Messages_* files: >>> >>> Thanks, Roger >>> >>> >>> >>> On 5/18/2015 10:08 AM, alexander stepanov wrote: >>>> Please see the updated webrev >>>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.01/ >>>> - some misprints were fixed as well >>>> (not 100% sure if "comparision" should be replaced with >>>> "comparison", but the latter looks more suitable). >>>> >>>> Thanks, >>>> Alexander >>>> >>>> On 15.05.2015 20:16, alexander stepanov wrote: >>>>> Hello, >>>>> >>>>> Could you please review the following fix >>>>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.00/ >>>>> for >>>>> https://bugs.openjdk.java.net/browse/JDK-8080422 >>>>> >>>>> Just some HTML markup fix. >>>>> >>>>> The affected packages should (probably) not be visible in the new >>>>> modular system, but nevertheless... >>>>> >>>>> Thanks, >>>>> Alexander >>>>> >>>> >>> >> > > > > 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 brett.bernstein at gmail.com Thu May 14 06:17:24 2015 From: brett.bernstein at gmail.com (Brett Bernstein) Date: Thu, 14 May 2015 02:17:24 -0400 Subject: PriorityQueue In-Reply-To: References: Message-ID: I believe the linked sequence of messages refer to the addition of a PriorityQueue constructor only taking a Comparator which was does appear in Java 1.8. Did you have a link to something regarding the a constructor taking a Collection and a Comparator (2 arguments)? On Thu, May 14, 2015 at 2:08 AM, Martin Buchholz wrote: > Software is hard. > We tried and got stuck, although the former effort can be revived. > RFR : 6799426 : (xs) Add constructor PriorityQueue(Comparator) > http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-July/019124.html > > > > On Wed, May 13, 2015 at 10:17 PM, Brett Bernstein < > brett.bernstein at gmail.com> wrote: > >> To whom this may concern: >> I believe the list of PriorityQueue constructors has a glaring omission >> that could be easily rectified. That is, there is no constructor that >> takes a Collection and a Comparator. What steps should I go through to >> get >> this suggested to be added to the class? >> >> Thanks, >> Brett Bernstein >> > > From lance.andersen at oracle.com Mon May 18 16:42:21 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Mon, 18 May 2015 12:42:21 -0400 Subject: RFR [9] 8080422: some docs cleanup for core libs In-Reply-To: <555A0D18.3060803@oracle.com> References: <55562A02.3000009@oracle.com> <5559F252.1020906@oracle.com> <5559FAA2.5090801@Oracle.com> <555A0706.4010803@oracle.com> <555A0D18.3060803@oracle.com> Message-ID: <2B8A12B7-175B-4472-BB8A-6F44C143F20A@oracle.com> Hi Alexander, seems ok as well? On May 18, 2015, at 12:02 PM, alexander stepanov wrote: > Hello, Lance, Roger, > > Thanks! > > P.S. sorry - one minor change after the review - a list was added in ExtensionDependency.java: > http://cr.openjdk.java.net/~avstepan/8080422/webrev.02/src/java.base/share/classes/sun/misc/ExtensionDependency.java.udiff.html > (please update the page). > > Regards, > Alexander > > On 18.05.2015 18:54, Lance Andersen wrote: >> The revised changes seem OK in addition to the previous webrev >> >> Best >> Lance >> On May 18, 2015, at 11:36 AM, alexander stepanov > wrote: >> >>> Hello Roger, >>> >>> Fixed; please see >>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.02/index.html >>> >>> Regards, >>> Alexander >>> >>> On 18.05.2015 17:43, Roger Riggs wrote: >>>> Hi Alexander, >>>> >>>> Thanks for these needed cleanups; a few corrections below. >>>> >>>> >>>> >>>> 1) src/java.base/share/classes/jdk/internal/util/xml/impl/Parser.java: >>>> >>>> "The grammar *which *this method can read is" can remove the 'which' >>>> >>>> >>>> >>>> 2) src/java.base/share/classes/sun/misc/CharacterEncoder.java: 107 >>>> >>>> The {@code } is confusing, typically @code marks a literal >>>> but in this case it is a symbol for the new line character. >>>> Perhaps use only "newline" without any special chars, as is used in PrintStream. >>>> >>>> src/java.base/share/classes/sun/misc/ExtensionDependency.java: 106 >>>> Correct the spelling of attriutes: >>>> - * @param jarFile containing the *attriutes *declaring the dependencies >>>> + * @param jar containing the *attributes *declaring the dependencies >>>> >>>> >>>> 3) src/java.base/share/classes/sun/misc/resources/Messages_de.java: 26 >>>> Please use {@code instead of ... >>>> - *

This class represents the ResourceBundle >>>> + * This class represents the ResourceBundle >>>> >>>> 4) Ditto all of the files in: >>>> src/java.base/share/classes/sun/misc/resources/Messages_* files: >>>> >>>> Thanks, Roger >>>> >>>> >>>> >>>> On 5/18/2015 10:08 AM, alexander stepanov wrote: >>>>> Please see the updated webrev >>>>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.01/ >>>>> - some misprints were fixed as well >>>>> (not 100% sure if "comparision" should be replaced with "comparison", but the latter looks more suitable). >>>>> >>>>> Thanks, >>>>> Alexander >>>>> >>>>> On 15.05.2015 20:16, alexander stepanov wrote: >>>>>> Hello, >>>>>> >>>>>> Could you please review the following fix >>>>>> http://cr.openjdk.java.net/~avstepan/8080422/webrev.00/ >>>>>> for >>>>>> https://bugs.openjdk.java.net/browse/JDK-8080422 >>>>>> >>>>>> Just some HTML markup fix. >>>>>> >>>>>> The affected packages should (probably) not be visible in the new modular system, but nevertheless... >>>>>> >>>>>> Thanks, >>>>>> Alexander >>>>>> >>>>> >>>> >>> >> >> >> >> 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 stevenschlansker at gmail.com Mon May 18 16:53:21 2015 From: stevenschlansker at gmail.com (Steven Schlansker) Date: Mon, 18 May 2015 06:53:21 -1000 Subject: Naming of thread pools (Executors) In-Reply-To: <5559957C.6070400@oracle.com> References: <644298286.508634.1431849349018.JavaMail.yahoo@mail.yahoo.com> <5559957C.6070400@oracle.com> Message-ID: <0681BCFA-2AE1-4197-ADEB-C8D21CAE54B9@gmail.com> > On May 17, 2015, at 9:32 PM, Aleksey Shipilev wrote: > > On 05/17/2015 10:55 AM, Peter Hansson wrote: >> Hi, >> >> I would like create a patch for https://bugs.openjdk.java.net/browse/JDK-8016248. >> MOTIVATION: Today thread pools created by the Executors method are always prefixed with "pool". The developer can work around this by providing his own ThreadFactory but if he wants to have the default JDK behaviour then it means he has to replicate code in the JDK. The string "pool" is hardcoded in the JDK. The fact that threads cannot be identified by their purpose is annoying especially when working with JEE servers. >> >> SUGGESTION: >> The idea is to amend private classes Executors.DefaultThreadFactory and Executors.PrivilegedThreadFactory to optionally accept a name prefix in their constructor.Then methods Executors.defaultThreadFactory() and Executors.privilegedThreadFactory() will be overloaded to optionally accept a name prefix. >> With this change the developer can now use a custom thread name prefix. If he wanted to do: >> >> Executors.newFixedThreadPool(3); // standard, results in "pool" prefix >> >> He could instead use a developer supplied ThreadFactory yet still using JDK's ThreadFactory: >> Executors.newFixedThreadPool(3, Executors.defaultThreadFactory("snmpworker")); >> >> Good idea ? Bad idea? Any negative side effects ? > > I think that's a sane improvement. > > But the next thing you'd want are shortcuts for thread daemon status, > priority, and maybe even the context classloader. Having that in mind, > it might be worthwhile to explore making > Executors.simpleThreadFactory(String prefix, boolean isDaemon, int > priority) and/or overloads and/or some builder variant of it? I'm sure everyone has seen this, but in case not, I use this all the time: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/ThreadFactoryBuilder.html From igor.ignatyev at oracle.com Mon May 18 17:51:10 2015 From: igor.ignatyev at oracle.com (Igor Ignatyev) Date: Mon, 18 May 2015 20:51:10 +0300 Subject: RFR(XS) : 8055269 : java/lang/invoke/MethodHandles/CatchExceptionTest.java fails intermittently Message-ID: <555A268E.8090206@oracle.com> http://cr.openjdk.java.net/~iignatyev/8055269/webrev.00/ 23 lines changed: 8 ins; 9 del; 6 mod Hi all, please review the tiny fix for CatchExceptionTest test. problem: the tests generates a target w/ 255 parameters, so a corresponding handler should have 256 parameters. that violates restrictions. fix: limit target's arity by 254 side changes: - cover a handler w/o dropped arguments case - fix a typo in a comment - always print maxArg, maxDrop and generated parameters' classes - print test properties in runTest method instead of ctor. testing: locally, w/ and w/o -Dthorough JBS: https://jbs.oracle.com/bugs/browse/JDK-8055269 -- Igor From vladimir.x.ivanov at oracle.com Mon May 18 17:58:13 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Mon, 18 May 2015 20:58:13 +0300 Subject: RFR(XS) : 8055269 : java/lang/invoke/MethodHandles/CatchExceptionTest.java fails intermittently In-Reply-To: <555A268E.8090206@oracle.com> References: <555A268E.8090206@oracle.com> Message-ID: <555A2835.4030004@oracle.com> Igor, Looks good. You don't need to bother computing slot size for a signature since you use only 1-slot types, do you? test/java/lang/invoke/MethodHandles/CatchExceptionTest.java: Class classes[] = { Object.class, long.class, int.class, byte.class, Integer[].class, double[].class, String.class, Best regards, Vladimir Ivanov On 5/18/15 8:51 PM, Igor Ignatyev wrote: > http://cr.openjdk.java.net/~iignatyev/8055269/webrev.00/ > 23 lines changed: 8 ins; 9 del; 6 mod > > Hi all, > > please review the tiny fix for CatchExceptionTest test. > > problem: the tests generates a target w/ 255 parameters, so a > corresponding handler should have 256 parameters. that violates > restrictions. > > fix: limit target's arity by 254 > > side changes: > - cover a handler w/o dropped arguments case > - fix a typo in a comment > - always print maxArg, maxDrop and generated parameters' classes > - print test properties in runTest method instead of ctor. > > testing: locally, w/ and w/o -Dthorough > JBS: https://jbs.oracle.com/bugs/browse/JDK-8055269 > From vladimir.x.ivanov at oracle.com Mon May 18 18:03:41 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Mon, 18 May 2015 21:03:41 +0300 Subject: RFR(XS) : 8055269 : java/lang/invoke/MethodHandles/CatchExceptionTest.java fails intermittently In-Reply-To: <555A2835.4030004@oracle.com> References: <555A268E.8090206@oracle.com> <555A2835.4030004@oracle.com> Message-ID: <555A297D.3050805@oracle.com> Ok, now I see long.class in the list :-) Does the test checks 255 limit on slots or logical arguments? It should check slot size, but I don't see logic for computing slot consumption for generated signatures. Best regards, Vladimir Ivanov On 5/18/15 8:58 PM, Vladimir Ivanov wrote: > Igor, > > Looks good. > > You don't need to bother computing slot size for a signature since you > use only 1-slot types, do you? > > test/java/lang/invoke/MethodHandles/CatchExceptionTest.java: > Class classes[] = { > Object.class, > long.class, > int.class, > byte.class, > Integer[].class, > double[].class, > String.class, > > Best regards, > Vladimir Ivanov > > On 5/18/15 8:51 PM, Igor Ignatyev wrote: >> http://cr.openjdk.java.net/~iignatyev/8055269/webrev.00/ >> 23 lines changed: 8 ins; 9 del; 6 mod >> >> Hi all, >> >> please review the tiny fix for CatchExceptionTest test. >> >> problem: the tests generates a target w/ 255 parameters, so a >> corresponding handler should have 256 parameters. that violates >> restrictions. >> >> fix: limit target's arity by 254 >> >> side changes: >> - cover a handler w/o dropped arguments case >> - fix a typo in a comment >> - always print maxArg, maxDrop and generated parameters' classes >> - print test properties in runTest method instead of ctor. >> >> testing: locally, w/ and w/o -Dthorough >> JBS: https://jbs.oracle.com/bugs/browse/JDK-8055269 >> From martinrb at google.com Mon May 18 18:52:15 2015 From: martinrb at google.com (Martin Buchholz) Date: Mon, 18 May 2015 11:52:15 -0700 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: <5556968D.9070401@oracle.com> References: <55567ACB.2050307@oracle.com> <5556968D.9070401@oracle.com> Message-ID: On Fri, May 15, 2015 at 5:59 PM, Ivan Gerasimov wrote: > > > On 16.05.2015 2:18, Martin Buchholz wrote: > > I wouldn't bother defining the constant. > > > I only need it in the regression test, to check whether it was > sufficient. > The problem you're trying to solve is (a small amount of) startup overhead. Don't introduce __more__ startup overhead (another constant in the class file) just to make your change more testable. If you're serious about reducing overhead for static maps, you could: - write a java agent that verifies that all maps stored in static fields are never resized or oversized, and run all jtreg tests with that agent - use a true immutable static compact map implementation, perhaps optimized for String keys, in the spirit of jdk/src/share/classes/sun/util/PreHashedMap.java - initialize the static maps from a binary blob stored in a resource instead of from java code but any of those is a lot of work. I would just check in the fix to s/256/BETTER_SIZE/ From Roger.Riggs at Oracle.com Mon May 18 20:49:10 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 18 May 2015 16:49:10 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <68D6442A-D329-45CF-BE11-43D110918811@oracle.com> References: <5550CFA1.9010606@Oracle.com> <68D6442A-D329-45CF-BE11-43D110918811@oracle.com> Message-ID: <555A5046.1020401@Oracle.com> Hi Paul, Thanks for the comments. On 5/18/2015 7:58 AM, Paul Sandoz wrote: > Ho Roger, > > I mostly focused on the specification. > > Paul. > > > Process > -- > > 35 * {@code Process} provides control of native processes started by > 36 * ProcessBuilder.start and Runtime.exec. > > Link to those methods? Links are not preferred in the first sentence used in the class summary. They are linked in the paragraph that follows > > > 92 /** > 93 * Default constructor for Process. > 94 */ > 95 public Process() {} > > Is that redundant? It seemed good form to document the constructor exists. The implicit public zero-arg constructor can't have javadoc. > > > 251 /** > 252 * Kills the subprocess forcibly. The subprocess represented by this > 253 * {@code Process} object is forcibly terminated. > 254 * Forcible process destruction is defined as the immediate termination of a > 255 * process, whereas normal termination allows a process to shut down cleanly. > 256 * If the process is not alive, no action is taken. > 257 *

> 258 * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is > 259 * {@link java.util.concurrent.CompletableFuture#complete completed} > 260 * when the process has terminated. > 261 * insert @implSpec > 262 *

The default implementation of this method invokes {@link #destroy} > 263 * and so may not forcibly terminate the process. insert @implNote > 264 * Concrete implementations of this class are strongly encouraged to override > 265 * this method with a compliant implementation. legacy spec - move up before other @ tags > 266 * Invoking this method on {@code Process} objects returned by > 267 * {@link ProcessBuilder#start} and {@link Runtime#exec} forcibly terminate > 268 * the process. > 269 * > > Use @ImplNote? Most of this is spec, not informational. > > > 270 *

Note: The subprocess may not terminate immediately. > 271 * i.e. {@code isAlive()} may return true for a brief period > 272 * after {@code destroyForcibly()} is called. This method > 273 * may be chained to {@code waitFor()} if needed. > 274 * > > Use @apiNote? seems reasonable But the resulting javadoc breaks up the flow of information. the API note that a developer would want to know about is far from the rest of the method description. > > > 361 * If the process is {@link #isAlive not alive} the {@link CompletableFuture} > 362 * is immediately {@link java.util.concurrent.CompletableFuture#complete completed}. > > s/is immediately/is returned/ ? The important action to be specified is that the CF is completed() immediately. Potentially it could say it is completed before the CF is returned from onExit(). > > > 390 * When the {@link #waitFor()} returns successfully the CompletableFuture is > 391 * {@link java.util.concurrent.CompletableFuture#complete completed} regardless > 392 * of the exit status of the process. > > s/When the/When / fixed > > > 406 * @return a {@code CompletableFuture} for the Process; > 407 * a unique instance is returned for each call to {@code onExit}. > 408 * > > Any need to mention about unique instances? yes, since the hierarchy of the CF instances is visible to the app and it makes a difference whether a unique CF is returned for each call or whether the same CF is returned from each call. > > > 429 /** > 430 * Returns a ProcessHandle for the Process. > 431 * > > Some methods talk about "the subprocess" where as others talk about "the Process" and others "the process". That variation of terminology predates this update. > > > 437 * @implSpec > 438 * This implementation throws an instance of > 439 * {@link java.lang.UnsupportedOperationException} and performs no other action. > 440 * Sub-types should override this method to provide a ProcessHandle for the > 441 * process. The methods {@link #getPid}, {@link #info}, {@link #children}, > 442 * and {@link #allChildren}, unless overridden, operate on the ProcessHandle. > > IIRC i incorrectly suggested Sub-types rather than Subclasses. There are other places with similar requirements where we can use the same language (e.g. destroyForcibly and onExit) "Subclasses should override this method...." Fixed > > > 456 /** > 457 * Returns a snapshot of information about the process. > 458 * > 459 *

An {@link ProcessHandle.Info} instance has various accessor methods > 460 * that return information about the process, if the process is alive and > 461 * the information is available, otherwise {@code null} is returned. > 462 * > 463 * @implSpec > 464 * This implementation returns information about the process as: > 465 * {@link #toHandle toHandle().info()}. > 466 * > 467 * @return a snapshot of information about the process; non-null > > Dangling "non-null". Do you mean it's can never be null or ", otherwise null if the process is not alive or such information is not available"? I suspect the former now all Info methods return Optional. It is always non-null. > > > 480 * Note that processes are created and terminate asynchronously. > 481 * There is no guarantee that a process is {@link #isAlive alive}. > 482 * > > s/terminate/terminated/ Well sometimes the terminate themselves, 'terminated' sounds like it is an external actor performing the termination. > > > ProcessHandle > -- > > 79 * For example, EPERM on Linux. > > I presume you are referring to native process-related operations that return an error code of EPERM? Yes, but the example does not add much and I'll remove it. > > > 86 /** > 87 * Returns the native process ID of the process. The native process ID is an > 88 * identification number that the operating system assigns to the process. > 89 * > 90 * @return the native process ID of the process > 91 * @throws UnsupportedOperationException if the implementation > 92 * does not support this operation > 93 */ > 94 long getPid(); > > In what cases could this throw a USO if the static "of "method did not? Its in an interface that might have arbitrary implementations. In a theoretical Process implementation for remote processes their might not be a viable pid or the access controls might be such that the PID is meaningless or restricted. > > > 167 /** > 168 * Returns a snapshot of all processes visible to the current process. > 169 *

> 170 * Note that processes are created and terminate asynchronously. There > 171 * is no guarantee that a process in the list is alive or that no other > 172 * processes may have been created since the inception of the snapshot. > 173 * > > Talks about "list". thx, will fix. > > > 192 * @return a snapshot of information about the process; non-null > > As for Process.info. fixed > > > 196 /** > 197 * Information snapshot about a process. > 198 * The attributes of a process vary by operating system and not available > 199 * in all implementations. Information about processes is limited > > s/and not/and are not/ fixed > > > 260 * If the process is {@link #isAlive not alive} the {@link CompletableFuture} > 261 * is immediately {@link java.util.concurrent.CompletableFuture#complete completed}. > > As for Process.onExit. same answer > > > 326 * @return an {@code Optional} for the process to be > 327 * forcibly destroyed; > 328 * the {@code Optional} has the value of the ProcessHandle > 329 * if the request to terminate was successful, otherwise it is empty > 330 * @throws IllegalStateException if the process is the current process > 331 */ > 332 Optional destroyForcibly(); > > Under what cases would an empty optional be returned? e.g. if native permissions are not granted? yes, but Alan's and other remarks recommend changing the return type. boolean will cover case to reflect that it was not possible to request the process to be destroyed without creating a confusing state of an Optional. Unless there is sufficient need for information about why the request was denied. That would suggest an exception be thrown with a os specific message. > > > 345 * Compares this ProcessHandle with the specified object for order. > > s/with the specification object for order./with another process handle./ ? > > > ProcessHandleImpl > -- > > 317 @Override > 318 public Optional destroyForcibly() { > 319 if (this.equals(current)) { > 320 throw new IllegalStateException("destroy of current process not allowed"); > 321 } > 322 return (destroy0(getPid(), false)) > 323 ? Optional.of(this) : Optional.empty(); > 324 } > > Should pass "true" to destroy0? fixed. Thanks, Roger > > Paul. > > > On May 11, 2015, at 5:49 PM, Roger Riggs wrote: > >> Please review clarifications and updates to the proposed Precess API. >> >> A few loose ends in the ProcessHandle API were identified. >> >> 1) The ProcessHandle.parent() method currently returns null if the parent cannot >> be determined and the ProcessHandle.of(PID) method returns null if the PID does not exist. >> It has been suggested to return an Optional to make >> these methods more flexible and allow a fluent style and work better with streams. >> >> 2) The behavior of Processhandle.destroy and destroyForcibly are different >> than Process.destroy and destroyForcibly. Those functions always succeed because >> they are children of the spawning process. >> >> In contrast, ProcessHandle.destroy and destroyForcible are requests to >> destroy the process and may not succeed due to operating system restrictions such >> as the process not being a child or not having enough privilege. >> The description of the methods needs to be clarified that it is a request to destroy >> and it may not succeed, In that case the destroy and destroyForcibly methods >> should indicate that the request was not successful. In particular, the caller >> may not want to wait for the process to terminate (its not going to). >> >> The proposed update is to return an Optional . >> It can be streamed and can take advantage of the conditional operations on the Optional. >> >> 3) Using Optional is also attractive for the return values of the information >> about a ProcessHandles, since not all values are available from every OS. >> The returns values of Info.command, arguments, startInstant, totalDuration, and user >> are proposed to be updated to return Optional. >> It allows for more compact code and fewer explicit checks for null. >> >> Please review and comment: >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-ph/ >> >> javadoc: >> http://cr.openjdk.java.net/~rriggs/ph-apidraft/ >> >> Diffs of the spec/javadoc from previous draft: >> http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-11/overview-summary.html >> >> Thanks, Roger >> >> >> From paul.sandoz at oracle.com Mon May 18 21:16:00 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 18 May 2015 23:16:00 +0200 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555A5046.1020401@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <68D6442A-D329-45CF-BE11-43D110918811@oracle.com> <555A5046.1020401@Oracle.com> Message-ID: <40097F7F-38B4-42FB-8A84-4070C6F9C7E4@oracle.com> On May 18, 2015, at 10:49 PM, Roger Riggs wrote: > Hi Paul, > > Thanks for the comments. > > On 5/18/2015 7:58 AM, Paul Sandoz wrote: >> Ho Roger, >> >> I mostly focused on the specification. >> >> Paul. >> >> >> Process >> -- >> >> 35 * {@code Process} provides control of native processes started by >> 36 * ProcessBuilder.start and Runtime.exec. >> >> Link to those methods? > Links are not preferred in the first sentence used in the class summary. > They are linked in the paragraph that follows Ok, seems odd to me but oh well.. >> >> >> 92 /** >> 93 * Default constructor for Process. >> 94 */ >> 95 public Process() {} >> >> Is that redundant? > It seemed good form to document the constructor exists. > The implicit public zero-arg constructor can't have javadoc. But there is nothing to say :-) >> >> >> 251 /** >> 252 * Kills the subprocess forcibly. The subprocess represented by this >> 253 * {@code Process} object is forcibly terminated. >> 254 * Forcible process destruction is defined as the immediate termination of a >> 255 * process, whereas normal termination allows a process to shut down cleanly. >> 256 * If the process is not alive, no action is taken. >> 257 *

>> 258 * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is >> 259 * {@link java.util.concurrent.CompletableFuture#complete completed} >> 260 * when the process has terminated. >> 261 * > insert @implSpec >> 262 *

The default implementation of this method invokes {@link #destroy} >> 263 * and so may not forcibly terminate the process. > insert @implNote >> 264 * Concrete implementations of this class are strongly encouraged to override >> 265 * this method with a compliant implementation. > legacy spec - move up before other @ tags >> 266 * Invoking this method on {@code Process} objects returned by >> 267 * {@link ProcessBuilder#start} and {@link Runtime#exec} forcibly terminate >> 268 * the process. >> 269 * >> >> Use @ImplNote? > Most of this is spec, not informational. Sorry i meant @implSpec, including for the "Concrete impls..." bit. >> >> >> 270 *

Note: The subprocess may not terminate immediately. >> 271 * i.e. {@code isAlive()} may return true for a brief period >> 272 * after {@code destroyForcibly()} is called. This method >> 273 * may be chained to {@code waitFor()} if needed. >> 274 * >> >> Use @apiNote? > seems reasonable > But the resulting javadoc breaks up the flow of information. the API note that a developer > would want to know about is far from the rest of the method description. Ok. >> >> >> 361 * If the process is {@link #isAlive not alive} the {@link CompletableFuture} >> 362 * is immediately {@link java.util.concurrent.CompletableFuture#complete completed}. >> >> s/is immediately/is returned/ ? > The important action to be specified is that the CF is completed() immediately. > Potentially it could say it is completed before the CF is returned from onExit(). > Yeah, that is what i was trying to get across, it returns with an already completed CF. >> >> >> 406 * @return a {@code CompletableFuture} for the Process; >> 407 * a unique instance is returned for each call to {@code onExit}. >> 408 * >> >> Any need to mention about unique instances? > yes, since the hierarchy of the CF instances is visible to the app and it makes > a difference whether a unique CF is returned for each call or whether > the same CF is returned from each call. Perhaps say "Returns a new CF..." and "@return a new {@code ..." ? >> >> >> 429 /** >> 430 * Returns a ProcessHandle for the Process. >> 431 * >> >> Some methods talk about "the subprocess" where as others talk about "the Process" and others "the process". > That variation of terminology predates this update. I think it's best to try and be consistent throughout the class e.g. keep with the existing term or change to consistently use a new term. >> >> >> 456 /** >> 457 * Returns a snapshot of information about the process. >> 458 * >> 459 *

An {@link ProcessHandle.Info} instance has various accessor methods >> 460 * that return information about the process, if the process is alive and >> 461 * the information is available, otherwise {@code null} is returned. >> 462 * >> 463 * @implSpec >> 464 * This implementation returns information about the process as: >> 465 * {@link #toHandle toHandle().info()}. >> 466 * >> 467 * @return a snapshot of information about the process; non-null >> >> Dangling "non-null". Do you mean it's can never be null or ", otherwise null if the process is not alive or such information is not available"? I suspect the former now all Info methods return Optional. > It is always non-null. Ok, so the first paragraph needs tweaking. >> >> >> 480 * Note that processes are created and terminate asynchronously. >> 481 * There is no guarantee that a process is {@link #isAlive alive}. >> 482 * >> >> s/terminate/terminated/ > Well sometimes the terminate themselves, 'terminated' sounds like it is an > external actor performing the termination. Ok. >> >> >> ProcessHandle >> -- >> >> 79 * For example, EPERM on Linux. >> >> I presume you are referring to native process-related operations that return an error code of EPERM? > Yes, but the example does not add much and I'll remove it. Ok. >> >> >> 86 /** >> 87 * Returns the native process ID of the process. The native process ID is an >> 88 * identification number that the operating system assigns to the process. >> 89 * >> 90 * @return the native process ID of the process >> 91 * @throws UnsupportedOperationException if the implementation >> 92 * does not support this operation >> 93 */ >> 94 long getPid(); >> >> In what cases could this throw a USO if the static "of "method did not? > Its in an interface that might have arbitrary implementations. In a theoretical > Process implementation for remote processes their might not be a viable pid > or the access controls might be such that the PID is meaningless or restricted. > Ok, i think i get it: a call ProcessHandle.getPid obtained from ProcessHandle.of will never from a USO but other implementations of ProcessHandle might. >> >> >> 326 * @return an {@code Optional} for the process to be >> 327 * forcibly destroyed; >> 328 * the {@code Optional} has the value of the ProcessHandle >> 329 * if the request to terminate was successful, otherwise it is empty >> 330 * @throws IllegalStateException if the process is the current process >> 331 */ >> 332 Optional destroyForcibly(); >> >> Under what cases would an empty optional be returned? e.g. if native permissions are not granted? > yes, but Alan's and other remarks recommend changing the return type. > boolean will cover case to reflect that it was not possible to request the process > to be destroyed without creating a confusing state of an Optional. Yes, that seems a better signal. What could the caller do if false is returned? not much i guess except log something. Paul. > Unless there is sufficient need for information about why the request was > denied. That would suggest an exception be thrown with a os specific message. From Roger.Riggs at Oracle.com Mon May 18 21:49:53 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 18 May 2015 17:49:53 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <5555CC06.4020507@gmail.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> <5555CC06.4020507@gmail.com> Message-ID: <555A5E81.8050804@Oracle.com> Hi Peter, On 5/15/2015 6:35 AM, Peter Levart wrote: > Hi Roger, > > On 05/14/2015 03:44 PM, Roger Riggs wrote: >> Hi Peter, >> >> On 5/14/15 8:19 AM, Peter Levart wrote: >>> Hi Roger, >>> >>> The new API using Optional(s) looks fine. In particular for the >>> ProcessHandle returning methods. They now either return >>> Stream or Optional. >>> >>> At some point in the development of this API, the implementation >>> introduced the AsyncExecutor to execute synchronous continuations of >>> the onExit() returned CompletableFuture(s). What was the main >>> motivation for this given that: >>> - previously, ForkJoinPoll.commonPool() was used instead that by >>> default possesses some similar characteristics (Innocuous threads >>> when SecurityManager is active) >> The AsyncExecutor also uses InnocuousThreads. > > So that's not what is lost or gained by AsyncExecutor when comparing > it with commonPool(). Are there other good attributes of commonPool that would be missed by using a separate pool? > >> >>> - this AsyncExecutor is only effective for 1st "wave" of synchronous >>> continuations. Asynchronous continuations and synchronous >>> continuations following them will still use ForkJoinPoll.commonPool() >> Unfortunately, the common ForkJoinPool assumes that tasks queued to >> it complete relatively >> quickly and free the thread. It does not grow the number of threads >> and is not appropriate >> for tasks that block for indefinite periods as might be need to wait >> for a Process to exit. > > Ok, AsyncExecutor might be required for default implementation of > Process.onExit(). But waiting on process exit in ProcessImpl and > ProcessHandle is performed by internal 32K stack-sized reaper threads > and what we did in ProcessImpl.onExit() was this (before the > AsyncExecutor): > > @Override > public CompletableFuture onExit() { > return ProcessHandleImpl.completion(pid, false) > .handleAsync((exitStatus, unusedThrowable) -> this); > } > > Which means that FJP.commonPool() thread is employed after > ProcessHandleImpl.completion() is completed. Meaning that just user > code is run by commonPool() and that code does not wait for process to > exit because it already did exit. User code might run for extended > period of time, but any use of CompletableFuture is susceptible to > that abuse. Are you afraid that users of Process API are not common > CompletableFuture users and are not aware of commonPool() constraints? The earlier spec specifically used the common pool but from a specification point of view it allows more flexibility in the implementation not to bind onExit to the commonPool. Its not clear that the attributes of threads used to handle output or managing Processes are the same as those attributed to the commonPool. The default sizing of the commonPool is based on the number of processors and does not grow (except via the ManagedBlockers) mechanism. The number of threads waiting for processes is unrelated to the number of CPUs. It is simpler to maintain to use a separate pool and not depend on consistent assumptions between Process handling and the commonPool. > >>> >>> Would an alternative be to define two overloaded onExit() methods in >>> the style of CompletableFuture itself? >>> >>> CompletableFuture onExit(); >>> CompletableFuture onExit(Executor executor); >>> >>> ...and give the user a chance to supply it's own Executor if the >>> default ForkJoinPoll.commonPool() does not fit? >> It is only one more method in PH and Process but that function is >> available from CompletableFuture >> though perhaps not as conveniently. >> The onExit method returns a CompletableFuture that has the entire >> complement of >> synchronous and async methods available to it. The application can >> control >> where subsequent computations are performed. > > That's true for xxxxAsync methods. Synchronous continuations are > executed by whichever thread executed the previous stage. We insert an > asynchronous stage to shield the internal 32K threads from user code. > What we do by executing that stage in AsyncExecutor might be desirable > when the user attaches a synchronous continuation. But when he > attaches an asynchronous one, the thread from AsyncExecutor is used > just for mapping the result into Process instance and triggering the > execution of next stage. Can we eliminate this unnecessary > asynchronous stage? One alternative is for onExit to return a CF subclass that maps synchronous methods to the corresponding async methods. Each call to onExit would return a new proxy that would delegate to a new CF created from the ExitCompletion.handle(...). For all requests that involved calling app code it would delegate to the corresponding async method. For example, CompletableFuture cf = ProcessHandleImpl.completion(getPid(), false) .handle((exitStatus, unusedThrowable) -> this); return new CompletionProxy(cf); The CompletionProxy can ensure that all CFs that call application code are Async. It would override the syncronous methods and redirect to the corresponding Async method. public CompletableFuture thenApply(Function fn) { return thenApplyAsync(fn); } The CompletionProxy can also supply the Executor as needed unless supplied by the application It adds a simple delegation but removed the extra task dispatch except where needed. Does that work as you would expect? Thanks, Roger > > What would be if we stoped pretending that user can execute a > synchronous onExit() continuation when in fact that continuation is > always attached to an asynchronous stage so it is actually > asynchronous? What if CompletableFuture had a public superclass called > AsyncCompletableFuture that only exposed .xxxxAsync() continuation > methods which returned normal CompletableFuture(s)? Such class would > by definition shield the thread that completes an > AsyncCompletableFuture from user code that attaches continuations. And > user code would have exclusive control on what type of thread executes > it. Isn't this a desirable property that jsr166 could provide? It > could be useful in other scenarios too. > > The only problem with that approach is that we need a mapping stage > that "attaches" the Proses[Handle] instance to > AsyncCompletableFuture (which is generic and returns an exit > status) to get AsyncCompletableFuture. Such operation > could be provided by AsyncCompletableFuture as an "immediate" > operation - not taking any lambda function which needs a thread to be > executed, but a replacement object instead: > > public class AsyncCompletableFuture ... { > > /** > * Returns a new CompletionStage that, when this stage completes > * normally, completes with the given replacementResult. > * > * @param replacementResult the successful completion value of the > returned > * CompletionStage > * @param the value's type > * @return the new CompletionStage > */ > public AsyncCompletableFuture thenReplace(U > replacementResult) { ... > > I can ask on the concurrency-interest list about the feasibility of > such [Async]CompletableFuture split. Would you be interested in using > AsyncCompletableFuture if it was available? > >> >> That convenience method could be added later when the use case and >> frequency is clearer. > > I saw it only as a workaround for needing AsyncExecutor. I don't like > it either. > > Regards, Peter > From brent.christian at oracle.com Mon May 18 22:44:56 2015 From: brent.christian at oracle.com (Brent Christian) Date: Mon, 18 May 2015 15:44:56 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55564FF8.3010802@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> <55526FF5.9000509@gmail.com> <55564473.3010704@oracle.com> <55564FF8.3010802@oracle.com> Message-ID: <555A6B68.5000505@oracle.com> Hi, Daniel You're right, thanks. The situation is the same for elements(). I've updated these in my local repo. I checked through the methods that return a Set/Enumeration/etc, and I believe there's also an issue with entrySet(). The returned Set should be backed by the map, and support remove operations, but not add/addAll. However the Set returned from ConcurrentHashMap.entrySet() *does* provide add/addAll. Sadly, there is no "unaddableSet()" in java.util.Collections. AFAICT, I'll need to add a new inner wrapper class for this. :\ Thanks, -Brent On 5/15/15 12:58 PM, Daniel Fuchs wrote: > Hi Brent, > > 1163 @Override > 1164 public Enumeration keys() { > 1165 return map.keys(); > 1166 } > > I wonder if you should use: > > public Enumeration keys() { > return Collections.enumeration(map.keySet()); > } > > instead. > > ConcurrentHashMap.keys() returns an Enumeration which is also an > Iterator which supports removal of elements, that might have > unintended side effects WRT to concurrency & subclassing. > > best regards, > > -- daniel > > On 15/05/15 21:09, Brent Christian wrote: >> On 5/13/15 8:53 AM, Mandy Chung wrote: >>>> On May 12, 2015, at 2:26 PM, Peter Levart >>>> wrote: >>>> On 05/12/2015 10:49 PM, Mandy Chung wrote: >>>>>> But I think it should be pretty safe to make the >>>>>> java.util.Properties object override all Hashtable methods and >>>>>> delegate to internal CMH so that: >>>>>> - all modification methods + all bulk read methods such as >>>>>> (keySet().toArray, values.toArray) are made synchronized again >>>>>> - individual entry read methods (get, containsKey, ...) are not >>>>>> synchronized. >>>>>> >>>>>> This way we get the benefits of non-synchronized read access >>>>>> but the change is hardly observable. In particular since >>>>>> external synchronization on the Properties object makes guarded >>>>>> code atomic like it is now and individual entry read accesses >>>>>> are almost equivalent whether they are synchronized or not and >>>>>> I would be surprised if any code using Properties for the >>>>>> purpose they were designed for worked any differently. >>>>> >>>>> I agree that making read-only methods not synchronized while >>>>> keeping any method with write-access with synchronized is pretty >>>>> safe change and low compatibility risk. On the other hand, would >>>>> most of the overrridden methods be synchronized then? >>>> >>>> Yes, and that doesn't seem to be a problem. Setting properties is >>>> not very frequent operation and is usually quite localized. Reading >>>> properties is, on the other hand, a very frequent operation >>>> dispersed throughout the code (almost like logging) and therefore >>>> very prone to deadlocks like the one in this issue. I think that by >>>> having an unsynchronized get(Property), most problems with >>>> Properties will be solved - deadlock and performance (scalability) >>>> related. >>> >>> I?m keen on cleaning up the system properties but it is a bigger >>> scope as it should take other related enhancement requests into >>> account that should be something for future. I think what you >>> propose seems a good solution to fix JDK-8029891 while it doesn?t >>> completely get us off the deadlock due to user code locking the >>> Properties object. >> >> Updated webrev: >> >> http://cr.openjdk.java.net/~bchristi/8029891/webrev.1/ >> >> I have restored synchronization to modification methods, and to my >> interpretation of "bulk read" operations: >> >> * forEach >> * replaceAll >> * store: (synchronized(this) in store0; also, entrySet() returns a >> synchronizedSet) >> * storeToXML: PropertiesDefaultsHandler.store() synchronizes on the >> Properties instance >> * propertyNames(): returns an Enumeration not backed by the >> Properies; calls (still synchronized) enumerate() >> * stringPropertyNames returns a Set not backed by the Properties; >> calls (still synchronized) enumerateStringProperties >> >> These continue to return a synchronized[Set|Collection]: >> * keySet >> * entrySet >> * values >> >> These methods should operate on a coherent snapshot: >> * clone >> * equals >> * hashCode >> >> I expect these two are only used for debugging. I wonder if we could >> get away with removing synchronization: >> * list >> * toString >> >> I'm still looking through the serialization code, though I suspect some >> synchronization should be added. >> >> The new webrev also has the updated test case from Peter. >> >> Thanks, >> -Brent >> > From stuart.marks at oracle.com Mon May 18 22:45:29 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Mon, 18 May 2015 15:45:29 -0700 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> Message-ID: <555A6B89.7060801@oracle.com> On 5/18/15 3:20 AM, Paul Sandoz wrote: > I would like to suggest some tweaks to the specification to get across this method is transitioning control of traversal from enumeration to iterator. How about: > > Returns an iterator that traverses the remaining elements covered by this enumeration. > Traversal is undefined if this enumeration is operated on after the call to {@code asIterator}. OK, good. I tweaked it somewhat to say "if any method is called" instead of "operated on" to make it absolutely clear that the underlying Enumeration shouldn't be touched after the call to asIterator(). (Yes, that includes hasMoreElements.) > I suspect the use of PermissionCollection in the apiNote is a little too obscure and highlighting an area that i don't think deserves so much attention :-) Boy people really hate the java.security APIs. But perhaps not as much as they hate CORBA. :-) > In your example i am not sure the source is IMMUTABLE, it's possible to add permissions if the collection is not marked read-only. It's not even clear whether ORDERED is relevant here, some implementations are backed by a HashMap (see BasicPermissionCollection) and the enumeration is derived from the map's values. Hence I am ambivalent about exposing such a Stream example, it exposes too many details that are tricky to get right. > > ClassLoader.getResources would be better if it were not for IOException. > > I would be inclined to go for Zip/JarFile.entries, and that would also give us the opportunity to highlight the stream returning method that could be used instead, therefore we can avoid mentioning about constructing a stream from an enumeration/iterator and move developers away from Enumeration altogether in this case. OK, I went with JarFile, since the wildcard in ZipFile.entries() seems to cause some trouble. I also deleted the stream example. It's fairly complex and as you note it's hard to get the details right. I've posted an updated webrev here: http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.1/ Changes include: - updates to spec & examples per above - converted NOTE in class doc to @apiNote - R?mi's suggested simplifications - additional tests for remove() s'marks > A good stream-ification task would be to identify cases in the JDK where only an Enumeration is returned and additionally provide stream-returning methods, so perhaps PermissionCollection and ClassLoader are good candidates. > > Paul. > > > > On May 16, 2015, at 2:37 AM, Stuart Marks wrote: > >> Hi all, >> >> Please review this small API enhancement to add a default method "asIterator()" to Enumeration that converts it into an Iterator. >> >> Webrev: >> >> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >> >> Bug: >> >> https://bugs.openjdk.java.net/browse/JDK-8072726 >> >> Thanks, >> >> s'marks > From mandy.chung at oracle.com Mon May 18 22:45:17 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 18 May 2015 15:45:17 -0700 Subject: Review Request for 8074431: Remove native2ascii tool Message-ID: <555A6B7D.6060809@oracle.com> This patch removes native2ascii command-line tool from JDK 9 as proposed in March [1]. Webrev at: http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074431/webrev.00/ Jon - A langtools test is updated to use a new Native2Ascii.java helper class instead. Existing code that calls sun.tools.native2ascii.Main can copy the implementation or Native2Ascii.java. thanks Mandy [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-March/032634.html From jonathan.gibbons at oracle.com Mon May 18 23:02:29 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 18 May 2015 16:02:29 -0700 Subject: Review Request for 8074431: Remove native2ascii tool In-Reply-To: <555A6B7D.6060809@oracle.com> References: <555A6B7D.6060809@oracle.com> Message-ID: <555A6F85.9090409@oracle.com> On 05/18/2015 03:45 PM, Mandy Chung wrote: > This patch removes native2ascii command-line tool from JDK 9 as > proposed in March [1]. > > Webrev at: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074431/webrev.00/ > > Jon - A langtools test is updated to use a new Native2Ascii.java > helper class instead. > > Existing code that calls sun.tools.native2ascii.Main can copy the > implementation or Native2Ascii.java. > > thanks > Mandy > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-March/032634.html > LangTools changes OK by me. -- Jon From staffan.friberg at oracle.com Tue May 19 01:44:31 2015 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Mon, 18 May 2015 18:44:31 -0700 Subject: RFR 8080640: Reduce copying when reading JAR/ZIP entries Message-ID: <555A957F.5010102@oracle.com> Hi, Wanted to get reviews and feedback on this performance improvement for reading from JAR/ZIP files during classloading by reducing unnecessary copying and reading the entry in one go instead of in small portions. This shows a significant improvement when reading a single entry and for a large application with 10k classes and 500+ JAR files it improved the startup time by 4%. For more details on the background and performance results please see the RFE entry. RFE - https://bugs.openjdk.java.net/browse/JDK-8080640 WEBREV - http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.0 Cheers, Staffan From mandy.chung at oracle.com Tue May 19 05:46:01 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 18 May 2015 22:46:01 -0700 Subject: RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java In-Reply-To: <55564473.3010704@oracle.com> References: <55479A4F.4060806@oracle.com> <5550FE5A.4070607@oracle.com> <55513EA7.1050700@oracle.com> <555192A4.3080305@gmail.com> <5551A0AA.6050800@gmail.com> <5552674E.4030009@oracle.com> <55526FF5.9000509@gmail.com> <55564473.3010704@oracle.com> Message-ID: <8DD50D66-D2C1-43E4-B7C5-992FE785958B@oracle.com> > On May 15, 2015, at 12:09 PM, Brent Christian wrote: > > Updated webrev: > > http://cr.openjdk.java.net/~bchristi/8029891/webrev.1/ > > I have restored synchronization to modification methods, and to my interpretation of "bulk read" operations: > > * forEach > * replaceAll > * store: (synchronized(this) in store0; also, entrySet() returns a synchronizedSet) > * storeToXML: PropertiesDefaultsHandler.store() synchronizes on the Properties instance > * propertyNames(): returns an Enumeration not backed by the Properies; calls (still synchronized) enumerate() > * stringPropertyNames returns a Set not backed by the Properties; calls (still synchronized) enumerateStringProperties > > These continue to return a synchronized[Set|Collection]: > * keySet > * entrySet > * values The enumerate and enumerateStringProperties methods calls entrySet() to enumerate all entries adding to the given map. The methods are synchronized and it can call map.entrySet directly to avoid the unnecessary synchronization. > > These methods should operate on a coherent snapshot: > * clone > * equals > * hashCode > > I expect these two are only used for debugging. I wonder if we could get away with removing synchronization: > * list > * toString > list() method calls enumerate() that is synchronized to take a snapshot and it doesn?t need synchronize. It may be useful to leave toString with synchronize that we know the string is a snapshot. Otherwise, looks good. Mandy From Alan.Bateman at oracle.com Tue May 19 07:02:48 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 19 May 2015 08:02:48 +0100 Subject: Review Request for 8074431: Remove native2ascii tool In-Reply-To: <555A6B7D.6060809@oracle.com> References: <555A6B7D.6060809@oracle.com> Message-ID: <555AE018.5050109@oracle.com> On 18/05/2015 23:45, Mandy Chung wrote: > This patch removes native2ascii command-line tool from JDK 9 as > proposed in March [1]. Looks good. -Alan From forax at univ-mlv.fr Tue May 19 07:05:26 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 19 May 2015 09:05:26 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <555A6B89.7060801@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555A6B89.7060801@oracle.com> Message-ID: <555AE0B6.70307@univ-mlv.fr> Thumb up for me :) R?mi On 05/19/2015 12:45 AM, Stuart Marks wrote: > > > > > On 5/18/15 3:20 AM, Paul Sandoz wrote: >> I would like to suggest some tweaks to the specification to get >> across this method is transitioning control of traversal from >> enumeration to iterator. How about: >> >> Returns an iterator that traverses the remaining elements covered >> by this enumeration. >> Traversal is undefined if this enumeration is operated on after >> the call to {@code asIterator}. > > OK, good. I tweaked it somewhat to say "if any method is called" > instead of "operated on" to make it absolutely clear that the > underlying Enumeration shouldn't be touched after the call to > asIterator(). (Yes, that includes hasMoreElements.) > >> I suspect the use of PermissionCollection in the apiNote is a little >> too obscure and highlighting an area that i don't think deserves so >> much attention :-) > > Boy people really hate the java.security APIs. But perhaps not as much > as they hate CORBA. :-) > >> In your example i am not sure the source is IMMUTABLE, it's possible >> to add permissions if the collection is not marked read-only. It's >> not even clear whether ORDERED is relevant here, some implementations >> are backed by a HashMap (see BasicPermissionCollection) and the >> enumeration is derived from the map's values. Hence I am ambivalent >> about exposing such a Stream example, it exposes too many details >> that are tricky to get right. >> >> ClassLoader.getResources would be better if it were not for IOException. >> >> I would be inclined to go for Zip/JarFile.entries, and that would >> also give us the opportunity to highlight the stream returning method >> that could be used instead, therefore we can avoid mentioning about >> constructing a stream from an enumeration/iterator and move >> developers away from Enumeration altogether in this case. > > OK, I went with JarFile, since the wildcard in ZipFile.entries() seems > to cause some trouble. > > I also deleted the stream example. It's fairly complex and as you note > it's hard to get the details right. > > I've posted an updated webrev here: > > http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.1/ > > Changes include: > > - updates to spec & examples per above > - converted NOTE in class doc to @apiNote > - R?mi's suggested simplifications > - additional tests for remove() > > s'marks > > >> A good stream-ification task would be to identify cases in the JDK >> where only an Enumeration is returned and additionally provide >> stream-returning methods, so perhaps PermissionCollection and >> ClassLoader are good candidates. >> >> Paul. >> >> >> >> On May 16, 2015, at 2:37 AM, Stuart Marks >> wrote: >> >>> Hi all, >>> >>> Please review this small API enhancement to add a default method >>> "asIterator()" to Enumeration that converts it into an Iterator. >>> >>> Webrev: >>> >>> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >>> >>> Bug: >>> >>> https://bugs.openjdk.java.net/browse/JDK-8072726 >>> >>> Thanks, >>> >>> s'marks >> From david.holmes at oracle.com Tue May 19 07:53:05 2015 From: david.holmes at oracle.com (David Holmes) Date: Tue, 19 May 2015 17:53:05 +1000 Subject: RFR(XS): JDK-8077866: [TESTBUG] Some of java.lang tests cannot be run on compact profiles 1, 2 In-Reply-To: <5559E331.70208@oracle.com> References: <5559E331.70208@oracle.com> Message-ID: <555AEBE1.2080609@oracle.com> Hi Denis, Looks okay to me. Thanks, David On 18/05/2015 11:03 PM, denis kononenko wrote: > Hi All, > > Please review the very small change in TEST.groups file. > > Webrev link: > http://cr.openjdk.java.net/~skovalev/dkononen/8077866/webrev.00/ > Bug id: JDK-8077866 > Testing: automated > Description: > > The following tests cannot be run on compact profiles 1 and 2: > > java/lang/invoke/lambda/LambdaStackTrace.java: requires > javax.tools.StandardJavaFileManager (JEP-161, available in Compact > Profile 3); > java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java: inherits from > the LambdaFormTestCase class which, in turn, has dependency on > java.lang.management package (JEP-161, available in Compact Profile 3); > java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java: the same as > above; > java/lang/invoke/LFCaching/LFGarbageCollectedTest.java the same as above; > > The fix simply adds these tests into the :needs_compact3 group. > > Thank you, > Denis. > From paul.sandoz at oracle.com Tue May 19 08:04:50 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 19 May 2015 10:04:50 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <555A6B89.7060801@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555A6B89.7060801@oracle.com> Message-ID: <1B161A9D-6AD7-4AE9-83D3-74F6167ED643@oracle.com> On May 19, 2015, at 12:45 AM, Stuart Marks wrote: > On 5/18/15 3:20 AM, Paul Sandoz wrote: >> I would like to suggest some tweaks to the specification to get across this method is transitioning control of traversal from enumeration to iterator. How about: >> >> Returns an iterator that traverses the remaining elements covered by this enumeration. >> Traversal is undefined if this enumeration is operated on after the call to {@code asIterator}. > > OK, good. I tweaked it somewhat to say "if any method is called" instead of "operated on" to make it absolutely clear that the underlying Enumeration shouldn't be touched after the call to asIterator(). (Yes, that includes hasMoreElements.) > Ok. FWIW "operated on" is a term we have used in Stream and Spliterator. e.g.: *

Traversal of elements should be accomplished through the spliterator. * The behaviour of splitting and traversal is undefined if the iterator is * operated on after the spliterator is returned. >> I suspect the use of PermissionCollection in the apiNote is a little too obscure and highlighting an area that i don't think deserves so much attention :-) > > Boy people really hate the java.security APIs. But perhaps not as much as they hate CORBA. :-) > I suppose i have to tolerate both :-) each nowadays is not on the radar of most developers. >> In your example i am not sure the source is IMMUTABLE, it's possible to add permissions if the collection is not marked read-only. It's not even clear whether ORDERED is relevant here, some implementations are backed by a HashMap (see BasicPermissionCollection) and the enumeration is derived from the map's values. Hence I am ambivalent about exposing such a Stream example, it exposes too many details that are tricky to get right. >> >> ClassLoader.getResources would be better if it were not for IOException. >> >> I would be inclined to go for Zip/JarFile.entries, and that would also give us the opportunity to highlight the stream returning method that could be used instead, therefore we can avoid mentioning about constructing a stream from an enumeration/iterator and move developers away from Enumeration altogether in this case. > > OK, I went with JarFile, since the wildcard in ZipFile.entries() seems to cause some trouble. > Ok. I am still rooting for a mention of the Stream returning methods in JarFile but i won't push it, up to you and no need for another review in that case. > I also deleted the stream example. It's fairly complex and as you note it's hard to get the details right. > > I've posted an updated webrev here: > > http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.1/ > +1 Paul. > Changes include: > > - updates to spec & examples per above > - converted NOTE in class doc to @apiNote > - R?mi's suggested simplifications > - additional tests for remove() > > s'marks From Alan.Bateman at oracle.com Tue May 19 08:14:14 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 19 May 2015 09:14:14 +0100 Subject: RFR(XS): JDK-8077866: [TESTBUG] Some of java.lang tests cannot be run on compact profiles 1, 2 In-Reply-To: <555AEBE1.2080609@oracle.com> References: <5559E331.70208@oracle.com> <555AEBE1.2080609@oracle.com> Message-ID: <555AF0D6.20201@oracle.com> On 19/05/2015 08:53, David Holmes wrote: > Hi Denis, > > Looks okay to me. > For now this is okay but I hope we can completely remove this unmaintainable section of the TEST.groups file once jtreg has support for selecting tests based on the run-time under test. -Alan From erik.joelsson at oracle.com Tue May 19 08:18:49 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Tue, 19 May 2015 10:18:49 +0200 Subject: Review Request for 8074431: Remove native2ascii tool In-Reply-To: <555A6B7D.6060809@oracle.com> References: <555A6B7D.6060809@oracle.com> Message-ID: <555AF1E9.9040302@oracle.com> Looks good to me. /Erik On 2015-05-19 00:45, Mandy Chung wrote: > This patch removes native2ascii command-line tool from JDK 9 as > proposed in March [1]. > > Webrev at: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074431/webrev.00/ > > Jon - A langtools test is updated to use a new Native2Ascii.java > helper class instead. > > Existing code that calls sun.tools.native2ascii.Main can copy the > implementation or Native2Ascii.java. > > thanks > Mandy > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-March/032634.html > From chris.hegarty at oracle.com Tue May 19 08:29:50 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 19 May 2015 09:29:50 +0100 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <555A6B89.7060801@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555A6B89.7060801@oracle.com> Message-ID: <9CAD47F5-9653-4A99-A36D-CA31B3D4B3EC@oracle.com> On 18 May 2015, at 23:45, Stuart Marks wrote: > ?. > > http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.1/ This update looks better. -Chris. > Changes include: > > - updates to spec & examples per above > - converted NOTE in class doc to @apiNote > - R?mi's suggested simplifications > - additional tests for remove() > > s'marks > > >> A good stream-ification task would be to identify cases in the JDK where only an Enumeration is returned and additionally provide stream-returning methods, so perhaps PermissionCollection and ClassLoader are good candidates. >> >> Paul. >> >> >> >> On May 16, 2015, at 2:37 AM, Stuart Marks wrote: >> >>> Hi all, >>> >>> Please review this small API enhancement to add a default method "asIterator()" to Enumeration that converts it into an Iterator. >>> >>> Webrev: >>> >>> http://cr.openjdk.java.net/~smarks/reviews/8072726/webrev.0/ >>> >>> Bug: >>> >>> https://bugs.openjdk.java.net/browse/JDK-8072726 >>> >>> Thanks, >>> >>> s'marks >> From peter.levart at gmail.com Tue May 19 08:34:42 2015 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 19 May 2015 10:34:42 +0200 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555A5E81.8050804@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> <5555CC06.4020507@gmail.com> <555A5E81.8050804@Oracle.com> Message-ID: <555AF5A2.5060205@gmail.com> Hi Roger, On 05/18/2015 11:49 PM, Roger Riggs wrote: > The earlier spec specifically used the common pool but from a > specification point of view > it allows more flexibility in the implementation not to bind onExit to > the commonPool. > Its not clear that the attributes of threads used to handle output or > managing Processes > are the same as those attributed to the commonPool. > > The default sizing of the commonPool is based on the number of processors > and does not grow (except via the ManagedBlockers) mechanism. > The number of threads waiting for processes is unrelated to the number > of CPUs. > It is simpler to maintain to use a separate pool and not depend on > consistent > assumptions between Process handling and the commonPool. I'm not advocating to use commonPool for waiting on the process exit(s). We have special low-stack-size reaper threads for this purpose and in future there could be just one thread maybe. I'm also not advocating to use commonPool in default Process.onExit() implementation where the thread must wait for process to exit. I'm just questiong the use of commonPool vs. AsyncExecutor in ProcessImpl.onExit() and ProcessHandleImpl.onExit() where there is an async CompletableFuture stage inserted to shield from exposing internal low-stack-size threads. The code that is executed by commonPool (or AsyncExecutor) by onExit() continuations doesn't wait for process to exit. The number of processes spawned does not matter directly. Only the rate of process exits does. The code executed will be a cleanup-type / post-exit-actions-type of code which seems to be typical code for commonPool. Code dealing with process input/output will typically be executed concurrently with the Process while the process is still running and not by onExit() continuations. On 05/18/2015 11:49 PM, Roger Riggs wrote: > One alternative is for onExit to return a CF subclass that maps > synchronous methods > to the corresponding async methods. Each call to onExit would return > a new proxy > that would delegate to a new CF created from the > ExitCompletion.handle(...). > For all requests that involved calling app code it would delegate to > the corresponding > async method. For example, > > CompletableFuture cf = > ProcessHandleImpl.completion(getPid(), false) > .handle((exitStatus, unusedThrowable) -> this); > return new CompletionProxy(cf); > > The CompletionProxy can ensure that all CFs that call application code > are Async. > It would override the syncronous methods and redirect to the > corresponding Async method. > > public CompletableFuture thenApply(Function ProcessHandle, ? extends U> fn) { > return thenApplyAsync(fn); > } > > The CompletionProxy can also supply the Executor as needed unless > supplied by the application > > It adds a simple delegation but removed the extra task dispatch except > where needed. > > Does that work as you would expect? > > Thanks, Roger I thought about that too. Unfortunately, there are also xxxAsync(..., Executor) methods that appear to attach asynchronous continuations. And they do, if passed-in Executor dispatches to separate threads. But users can pass in a "SynchronousExecutor" like the following: public class SynchronousExecutor implements Executor { @Override public void execute(Runnable command) { command.run(); } } ...which makes xxxAsync(..., Executor) methods equivalent to synchronous-continuation-attaching methods. It would be nice to have an API that guaranteed division of threads between internal-code and user-code threads, but such API would have to be constructed around something different than Executor interface. I think what we have with insertion of an async stage is the best we can do with CompletableFuture API. The only question remaining is whether to use AsyncExecutor in ProcessImpl and ProcessHandleImpl .onExit() methods for executing the inserted async stage (and any synchronous continuation of it), or only in default implementation of Process.onExit() for waiting on process exit. The AsyncExecutor properties are such that it doesn't pre-start any threads and if not used, doesn't represent any system overhead. This is good if it is normally not used and would make it a good candidate for default Process.onExit() implementation which is used only in uncommon custom Process implementations. Using it in ProcessImpl and ProcessHandleImpl .onExit() methods makes it being used after each onExit() call, albeit potentially only briefly, so there's a chance that only one thread will ever be started and will die after every 60s of inactivity. commonPool() is no different from that perspective, but there is a chance, being a common pool, that it is used for other purposes too, so potentially less thread starts and stops can be achieved. There's also the lack of uniformity if AsyncExecutor is used which can have surprising effects. For example, a user switches from using synchronous onExit() continuation to asynchronous one and as a result the executor changes which can results in different behavior. I would be *for* using the AsyncExecutor in Process[Handle]Impl if it could be set as default Executor for any continuation born from returned CompletableFuture transitively. There were some changes announced from jsr166 team that would allow that (subclassing CF so that the methods returned a subclass of CF), so this could perhaps be the way to go... Regards, Peter From Sunny.Chan at gs.com Tue May 19 08:48:56 2015 From: Sunny.Chan at gs.com (Chan, Sunny) Date: Tue, 19 May 2015 16:48:56 +0800 Subject: Patch to improve primitives Array.sort() In-Reply-To: <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> Message-ID: <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> An updated patch has been published to cr.openjdk via Paul: http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.2/ Updates: The testcase has been updated to clone the array The redundant constant MAX_RUN_LENGTH has been removed. From: Paul Sandoz [mailto:paul.sandoz at oracle.com] Sent: 16 May 2015 00:13 To: Chan, Sunny [Tech] Cc: O'Leary, Kristen [Tech]; 'Alan Bateman'; 'core-libs-dev at openjdk.java.net'; Rezaei, Mohammad A. [Tech] Subject: Re: Patch to improve primitives Array.sort() On May 15, 2015, at 11:48 AM, "Chan, Sunny" > wrote: I have provided Paul with an updated patch: Here it is: http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.1/ In DualPivotQuicksort 63 /** 64 * The maximum length of run in merge sort. 65 */ 66 private static final int MAX_RUN_LENGTH = 33; You can remove this constant. * The test has been updated using data provider and reduce as much repetition as possible. Looking much better. Convention-wise if you don't have to deal with any check exceptions using a Supplier is more preferable to Callable. Up to you. 56 @Test(dataProvider = "arrays") 57 public void runTests(String testName, Callable dataMethod) throws Exception 58 { 59 int[] array = dataMethod.call(); 60 this.sortAndAssert(array); 61 this.sortAndAssert(this.floatCopyFromInt(array)); 62 this.sortAndAssert(this.doubleCopyFromInt(array)); 63 this.sortAndAssert(this.longCopyFromInt(array)); 64 this.sortAndAssert(this.shortCopyFromInt(array)); 65 this.sortAndAssert(this.charCopyFromInt(array)); At line 60 should you clone the array? otherwise, if i have looked correctly, that sorted result will be tested for other values. * The GS copyright notice from the main JDK patch. However we retain it on our test cases as we developed ourselves. In our previous contributions where we provided new tests we have put our copyright along with oracle copyright and it was accepted (see: http://hg.openjdk.java.net/jdk9/dev/jdk/file/ed94f3e7ba6b/test/java/lang/instrument/DaemonThread/TestDaemonThread.java) Ok. It was more query on my part. I believe it's ok for you to add copyright on both files if you wish. * Alan has commented that there were older benchmark but searching through the archive I can see it mention "BentleyBasher" I cannot find the actual code that Vladimir used (thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2009-September/002633.html). Is there anywhere I can get hold of it? I tried looking, but i cannot find any. Paul. From paul.sandoz at oracle.com Tue May 19 09:08:00 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 19 May 2015 11:08:00 +0200 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: References: <55567ACB.2050307@oracle.com> <5556968D.9070401@oracle.com> Message-ID: <9271D4A6-3A5A-4B4E-8FFD-0C2C5F21F7E9@oracle.com> On May 18, 2015, at 8:52 PM, Martin Buchholz wrote: > On Fri, May 15, 2015 at 5:59 PM, Ivan Gerasimov > wrote: > >> >> >> On 16.05.2015 2:18, Martin Buchholz wrote: >> >> I wouldn't bother defining the constant. >> >> >> I only need it in the regression test, to check whether it was >> sufficient. >> > > The problem you're trying to solve is (a small amount of) startup overhead. > Don't introduce __more__ startup overhead (another constant in the class > file) just to make your change more testable. > I agree, the use of the constant just for test purposes made me uncomfortable. Although the startup up cost for a constant would be far less than an additional resize of the map. Still i would prefer another way. For now i would just bump up the initial capacity to 512, since that is what the table size will be and the number entries should be between 193 and 384 (256 * 0.75 + 1 and 512 * 0.75 respectively), state that in a comment. IMO the test for HashMap resizes should be a general test (perhaps it exists already?). Paul. > If you're serious about reducing overhead for static maps, you could: > - write a java agent that verifies that all maps stored in static fields > are never resized or oversized, and run all jtreg tests with that agent > - use a true immutable static compact map implementation, perhaps optimized > for String keys, in the spirit of > jdk/src/share/classes/sun/util/PreHashedMap.java > - initialize the static maps from a binary blob stored in a resource > instead of from java code > > but any of those is a lot of work. I would just check in the fix to > s/256/BETTER_SIZE/ From peter.levart at gmail.com Tue May 19 09:17:16 2015 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 19 May 2015 11:17:16 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> Message-ID: <555AFF9C.3080309@gmail.com> Hi, On 05/18/2015 12:20 PM, Paul Sandoz wrote: > Hi Stuart, > > I would like to suggest some tweaks to the specification to get across this method is transitioning control of traversal from enumeration to iterator. How about: > > Returns an iterator that traverses the remaining elements covered by this enumeration. > Traversal is undefined if this enumeration is operated on after the call to {@code asIterator}. I suppose this part of specification allows alternative overridden implementations of asIterator() method that return Iterator implementation that is more optimal in sense of not delegating to the Enumeration, but using it's own state, right? Should anything be said also about default remove() method inherited from Iterator interface? Are custom asIterator() implementations allowed to return an Iterator that implements remove() in a way that actually removes elements? Regards, Peter From igor.ignatyev at oracle.com Tue May 19 09:35:28 2015 From: igor.ignatyev at oracle.com (Igor Ignatyev) Date: Tue, 19 May 2015 12:35:28 +0300 Subject: RFR(XS) : 8055269 : java/lang/invoke/MethodHandles/CatchExceptionTest.java fails intermittently In-Reply-To: <555A297D.3050805@oracle.com> References: <555A268E.8090206@oracle.com> <555A2835.4030004@oracle.com> <555A297D.3050805@oracle.com> Message-ID: <555B03E0.6040709@oracle.com> Vladimir, thank you for review. regarding slot consumption calculation, to get parameters limited by slot number, the test uses Helper.getParams method which implements this calculation (test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java:133-148) -- Igor On 05/18/2015 09:03 PM, Vladimir Ivanov wrote: > Ok, now I see long.class in the list :-) > > Does the test checks 255 limit on slots or logical arguments? It should > check slot size, but I don't see logic for computing slot consumption > for generated signatures. > > Best regards, > Vladimir Ivanov > > On 5/18/15 8:58 PM, Vladimir Ivanov wrote: >> Igor, >> >> Looks good. >> >> You don't need to bother computing slot size for a signature since you >> use only 1-slot types, do you? >> >> test/java/lang/invoke/MethodHandles/CatchExceptionTest.java: >> Class classes[] = { >> Object.class, >> long.class, >> int.class, >> byte.class, >> Integer[].class, >> double[].class, >> String.class, >> >> Best regards, >> Vladimir Ivanov >> >> On 5/18/15 8:51 PM, Igor Ignatyev wrote: >>> http://cr.openjdk.java.net/~iignatyev/8055269/webrev.00/ >>> 23 lines changed: 8 ins; 9 del; 6 mod >>> >>> Hi all, >>> >>> please review the tiny fix for CatchExceptionTest test. >>> >>> problem: the tests generates a target w/ 255 parameters, so a >>> corresponding handler should have 256 parameters. that violates >>> restrictions. >>> >>> fix: limit target's arity by 254 >>> >>> side changes: >>> - cover a handler w/o dropped arguments case >>> - fix a typo in a comment >>> - always print maxArg, maxDrop and generated parameters' classes >>> - print test properties in runTest method instead of ctor. >>> >>> testing: locally, w/ and w/o -Dthorough >>> JBS: https://jbs.oracle.com/bugs/browse/JDK-8055269 >>> From miroslav.kos at oracle.com Tue May 19 09:38:54 2015 From: miroslav.kos at oracle.com (Miroslav Kos) Date: Tue, 19 May 2015 11:38:54 +0200 Subject: RFR [9] 8080502: Changing accessing module resources Message-ID: <555B04AE.8040009@oracle.com> Hi everybody, this is a review request for 8080502: Changing accessing module resources. This change adapts to Jigsaw JDK runtime - it isn't possible to access module resource using Class::getResource() any more. JBS: https://bugs.openjdk.java.net/browse/JDK-8080502 webrev: http://cr.openjdk.java.net/~mkos/8080502/jaxws.01/index.html testing: JAX-WS unit test; basically it is fix for existing tests (JCK, ...) Thanks Miran From peter.levart at gmail.com Tue May 19 09:52:38 2015 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 19 May 2015 11:52:38 +0200 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5559D85B.2050500@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> Message-ID: <555B07E6.4040500@gmail.com> Hi Dmitry, This looks good. Just alignment of new code in Finalizer seems a little wobbly. Regards, Peter On 05/18/2015 02:17 PM, Dmitry Samersoff wrote: > Everyone, > > Please review updated version of the fix: > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ > > Most important part of the fix provided by Peter Levart, so all > credentials belongs to him. > > -Dmitry > > On 2015-05-16 15:48, Peter Levart wrote: >> >> On 05/16/2015 02:38 PM, Peter Levart wrote: >>> >>> On 05/16/2015 09:35 AM, Dmitry Samersoff wrote: >>>> Derek, >>>> >>>> Personally, I'm for volatile over explicit fence too. >>>> >>>> So I'll change the code if Peter don't have objections. >>> There are no objections. There's one unneeded volatile store to .next >>> field then in enqueue(), but it is followed by another volatile store, >>> so there shouldn't be overhead on Intel and SPARC at least. >>> >>> Regards, Peter >> If you make .next field volatile, then perhaps you could also cache it's >> value in reallyPoll() into a local variable, so that it is not read >> twice. Like this: >> >> private Reference reallyPoll() { /* Must hold lock */ >> Reference r = head; >> if (r != null) { >> Reference rn = r.next; // HERE !!! >> head = (rn == r) ? >> null : >> rn; // Unchecked due to the next field having a raw type >> in Reference >> r.queue = NULL; >> r.next = r; >> queueLength--; >> if (r instanceof FinalReference) { >> sun.misc.VM.addFinalRefCount(-1); >> } >> return r; >> } >> return null; >> } >> >> >> >> Peter >> >> >>>> -Dmitry >>>> >>>> On 2015-05-16 01:59, Derek White wrote: >>>>> Hi Dmitry, Peter, >>>>> >>>>> I should read my email more frequently - I missed Dmitry's last webrev >>>>> email. >>>>> >>>>> My comments on a preference for volatile over Unsafe are not a strong >>>>> objection to using Unsafe fences. I just don't have enough experience >>>>> with Unsafe fences yet to agree that this use is correct. >>>>> >>>>> While looking over this Reference code I found 3-6 really simple things >>>>> that need cleaning up that have been there for years, so I'm not a big >>>>> cheerleader for more complicated things here :-) >>>>> >>>>> - Derek >>>>> >>>>> On 5/15/15 6:46 PM, Derek White wrote: >>>>>> Hi Peter, >>>>>> >>>>>> Some comments below... >>>>>> >>>>>> On 5/14/15 3:50 AM, Peter Levart wrote: >>>>>>> Hi Derek, >>>>>>> >>>>>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>>>>> Hi Peter, >>>>>>>> >>>>>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>>>>> but I have some concerns... >>>>>>> I did have a concern too, ... >>>>>>> >>>>>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>>>>> Hi Dmitry, >>>>>>>>> >>>>>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>>>>> logical. >>>>>>>>> >>>>>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>>>>> threads for the entire time of iteration. This can blow up the >>>>>>>>> application. Suppose one wants to diagnose the application because >>>>>>>>> he suspects that finalizer thread hardly keeps up with production >>>>>>>>> of finalizable instances. This can happen if the allocation rate of >>>>>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>>>>>>> up gradually and is already holding several million objects. Now >>>>>>>>> you initiate the diagnostic command to print the queue. The >>>>>>>>> iteration over and grouping/counting of several millions of >>>>>>>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>>>>>>> reference handler thread. But does not block the threads that >>>>>>>>> allocate finalizable objects. By the time the iteration is over, >>>>>>>>> the JVM blows up and application slows down to a halt doing GCs >>>>>>>>> most of the time, getting OOMEs, etc... >>>>>>>>> >>>>>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>>>>> purposes without holding a lock. The modification required to do >>>>>>>>> that is the following (havent tested this, but I think it should work): >>>>>>>>> >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>>>>> >>>>>>>> One issue to watch out for is the garbage collectors inspect the >>>>>>>> Reference.next field from C code directly (to distinguish active vs. >>>>>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>>>>> >>>>>>>> Your change makes "inactive" References superficially look like >>>>>>>> "enqueued" References. The GC code is rather subtle and I haven't >>>>>>>> yet seen a case where it would get confused by this change, but >>>>>>>> there could easily be something like that lurking in the GC code. >>>>>>> ...but then I thought that GC can in no way treat a Reference >>>>>>> differently whether it is still enqueued in a ReferenceQueue or >>>>>>> already dequeued (inactive) - responsibility is already on the Java >>>>>>> side. Currently the definition of Reference.next is this: >>>>>>> >>>>>>> /* When active: NULL >>>>>>> * pending: this >>>>>>> * Enqueued: next reference in queue (or this if last) >>>>>>> * Inactive: this >>>>>>> */ >>>>>>> @SuppressWarnings("rawtypes") >>>>>>> Reference next; >>>>>>> >>>>>>> We see that, unless GC inspects all ReferenceQueue instances and >>>>>>> scans their lists too, the state of a Reference that is enqueued as >>>>>>> last in list is indistinguishable from the state of inactive >>>>>>> Reference. So I deduced that this distinction (enqueued/inactive) >>>>>>> can't be established solely on the value of .next field ( == this or >>>>>>> != this)... >>>>>>> >>>>>>> But I should inspect the GC code too to build a better understanding >>>>>>> of that part of the story... >>>>>>> >>>>>>> Anyway. It turns out that there is already enough state in Reference >>>>>>> to destinguish between it being enqueued as last in list and already >>>>>>> dequeued (inactive) - the additional state is Reference.queue that >>>>>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>>>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>>>>> (r.next and r.queue) are assigned and read in correct order. This can >>>>>>> be achieved either by making Reference.next a volatile field or by a >>>>>>> couple of explicit fences: >>>>>>> >>>>>>> >>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>>>>> >>>>>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>>>>> before linking the reference into the queue's head in >>>>>>> ReferenceQueue.enqueue(): >>>>>>> >>>>>>> r.queue = ENQUEUED; >>>>>>> r.next = (head == null) ? r : head; >>>>>>> head = r; >>>>>>> >>>>>>> Both stores are volatile. >>>>>> This sounds a bit better. I don't have a good handle on the pros and >>>>>> cons of a volatile field over explicit fences via Unsafe in this case. >>>>>> Kim might jump in soon. >>>>>> >>>>>> I'd like to suggest an entirely less-clever solution. Since the >>>>>> problem is that forEach() might see inconsistent values for the queue >>>>>> and next fields of a Reference, but we don't want to grab a lock >>>>>> walking the whole queue, we could instead grab the lock as we look at >>>>>> each Reference (and do the "back-up" trick if we were interfered >>>>>> with). Of course this is slower than going lock-free, but it's not any >>>>>> more overhead than the ReferenceHandler thread or FinalizerThreads incur. >>>>>> >>>>>> The only benefit of this solution over the others is that it is less >>>>>> clever, and I'm not sure how much cleverness this problem deserves. >>>>>> Given that, and ranking the solutions as "lock" < (clever) "volatile" >>>>>> < "fence", I'd be happier with the "volatile" or "lock" solution if >>>>>> that is sufficient. >>>>>> >>>>>> - Derek >>>>>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>>>>> forEach iteration method with no concrete logic. >>>>>>>>> >>>>>>>>> It would be possible to encapsulate the entire logic into a special >>>>>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>>>>> static method(s) (printFinalizationQueue)... You could just expose >>>>>>>>> a package-private forEach static method from Finalizer and code the >>>>>>>>> rest in DiagnosticCommands. >>>>>>>> That's good for encapsulation. But I'm concerned that if "forEach" >>>>>>>> got exposed beyond careful use in DiagnosticCommands, and the >>>>>>>> Referents were leaked back into the heap, then we could get >>>>>>>> unexpected object resurrection after finalization. This isn't a bug >>>>>>>> on it's own - any finalizer might resurrect its object if not >>>>>>>> careful, but ordinarily /only/ the finalizer could resurrect the >>>>>>>> object. This could invalidate application invariants? >>>>>>> Well, it all stays in the confines of package-private API - internal >>>>>>> to JDK. Any future additional use should be reviewed carefully. >>>>>>> Comments on the forEach() method should warn about that. >>>>>>> >>>>>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>>>>> /another/ case of diagnostics affecting application behavior. And >>>>>>>> there are pathological scenarios where this gets severe. This is >>>>>>>> unfortunate but not uncommon. There is enough complication here that >>>>>>>> you should be sure that the fix for diagnostics performance doesn't >>>>>>>> introduce subtle bugs to the system in general. A change in this >>>>>>>> area should get a thorough review from both the runtime and GC sides. >>>>>>> Is the webrev.02 proposed above more acceptable in that respect? It >>>>>>> does not introduce any logical changes to existing code. >>>>>>> >>>>>>>> Better yet, the reference handling code in GC and runtime should >>>>>>>> probably be thrown out and re-written, but that's another issue :-) >>>>>>> I may have some proposals in that direction. Stay tuned. >>>>>>> >>>>>>> Regards, Peter >>>>>>> >>>>>>>> - Derek >>>>>>>> >>>>>>>>> Regards, Peter >>>>>>>>> >>>>>>>>> >>>>>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>>>>> Everybody, >>>>>>>>>> >>>>>>>>>> Updated version: >>>>>>>>>> >>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>>>>> >>>>>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>>>>> >>>>>>>>>> -Dmitry >>>>>>>>>> >>>>>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>> >>>>>>>>>>> Lots of good comments here. >>>>>>>>>>> >>>>>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>>>>> general iterator and lambda. >>>>>>>>>>> >>>>>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>>>>> >>>>>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>>>>> >>>>>>>>>>> The sorting suggestion is a nice touch. >>>>>>>>>>> >>>>>>>>>>> - Derek White, GC team >>>>>>>>>>> >>>>>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>>> >>>>>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>>>>> Dmitry, >>>>>>>>>>>>> >>>>>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>>>>> >>>>>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>>>>> running out of memory. >>>>>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>>>>> >>>>>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>>>>> interfere with synchronization? >>>>>>>>>>>> >>>>>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>>>>> >>>>>>>>>>>> private void remove() { >>>>>>>>>>>> synchronized (lock) { >>>>>>>>>>>> if (unfinalized == this) { >>>>>>>>>>>> if (this.next != null) { >>>>>>>>>>>> unfinalized = this.next; >>>>>>>>>>>> } else { >>>>>>>>>>>> unfinalized = this.prev; >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> if (this.next != null) { >>>>>>>>>>>> this.next.prev = this.prev; >>>>>>>>>>>> } >>>>>>>>>>>> if (this.prev != null) { >>>>>>>>>>>> this.prev.next = this.next; >>>>>>>>>>>> } >>>>>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>>>>> traverse the list unsynchronized >>>>>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>>>>> finalized */ >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>>>>> pointer could be used instead: >>>>>>>>>>>> >>>>>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>>>>> return (prev == this); >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>>>>> >>>>>>>>>>>> private void add() { >>>>>>>>>>>> synchronized (lock) { >>>>>>>>>>>> if (unfinalized != null) { >>>>>>>>>>>> this.next = unfinalized; >>>>>>>>>>>> unfinalized.prev = this; >>>>>>>>>>>> } >>>>>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>>>>> // instance fully initialized >>>>>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>>>>> U.storeFence(); >>>>>>>>>>>> unfinalized = this; >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>>>>> >>>>>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>>>>> out? >>>>>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>>>>> two purposes: >>>>>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>>>>> >>>>>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>>>>> finalize() method. >>>>>>>>>>>> >>>>>>>>>>>> Regards, Peter >>>>>>>>>>>> >>>>>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>>>>> >>>>>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>>>>> permission() and limit access: >>>>>>>>>>>>> >>>>>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>>>>> "monitor", NULL}; >>>>>>>>>>>>> return p; >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>>>>> >>>>>>>>>>>>> Thanks, >>>>>>>>>>>>> /Staffan >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> Everyone, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Please review the fix: >>>>>>>>>>>>>> >>>>>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>>>>> >>>>>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>>>>> >>>>>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>>>>> with count >>>>>>>>>>>>>> >>>>>>>>>>>>>> -Dmitry >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>>>>> * I would love to change the world, but they won't give me the sources. > From paul.sandoz at oracle.com Tue May 19 10:07:39 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 19 May 2015 12:07:39 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <555AFF9C.3080309@gmail.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> Message-ID: <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> On May 19, 2015, at 11:17 AM, Peter Levart wrote: > Hi, > > On 05/18/2015 12:20 PM, Paul Sandoz wrote: >> Hi Stuart, >> >> I would like to suggest some tweaks to the specification to get across this method is transitioning control of traversal from enumeration to iterator. How about: >> >> Returns an iterator that traverses the remaining elements covered by this enumeration. >> Traversal is undefined if this enumeration is operated on after the call to {@code asIterator}. > > I suppose this part of specification allows alternative overridden implementations of asIterator() method that return Iterator implementation that is more optimal in sense of not delegating to the Enumeration, but using it's own state, right? > Yes, i did have that in mind, but mostly it was proposed that way to get across the sense of transferring control of traversal for the remaining, untraversed, elements. > Should anything be said also about default remove() method inherited from Iterator interface? Are custom asIterator() implementations allowed to return an Iterator that implements remove() in a way that actually removes elements? > Since this method transfers control it seems a little mean to place such a restriction on the returned Iterator. Although, there is no clear means of stating to the caller whether such an iterator supports removal or not, but that seems to be generally the case for any Iterator returning method. Paul. From tomasz.kowalczewski at gmail.com Tue May 19 10:41:43 2015 From: tomasz.kowalczewski at gmail.com (Tomasz Kowalczewski) Date: Tue, 19 May 2015 12:41:43 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> Message-ID: Is there a plan to override the default method asIterator() in specific implementations of Enumeration to avoid creating new object? JarFile::entries already returns JarEntryIterator which is both. To be fair I did some tests and when I wrap Enumerable into simple Iterator adapter it will almost always get scalar replaced by escape analysis (unless, of course, it actually escapes :)). On Tue, May 19, 2015 at 12:07 PM, Paul Sandoz wrote: > > On May 19, 2015, at 11:17 AM, Peter Levart wrote: > > > Hi, > > > > On 05/18/2015 12:20 PM, Paul Sandoz wrote: > >> Hi Stuart, > >> > >> I would like to suggest some tweaks to the specification to get across > this method is transitioning control of traversal from enumeration to > iterator. How about: > >> > >> Returns an iterator that traverses the remaining elements covered by > this enumeration. > >> Traversal is undefined if this enumeration is operated on after the > call to {@code asIterator}. > > > > I suppose this part of specification allows alternative overridden > implementations of asIterator() method that return Iterator implementation > that is more optimal in sense of not delegating to the Enumeration, but > using it's own state, right? > > > > Yes, i did have that in mind, but mostly it was proposed that way to get > across the sense of transferring control of traversal for the remaining, > untraversed, elements. > > > > Should anything be said also about default remove() method inherited > from Iterator interface? Are custom asIterator() implementations allowed to > return an Iterator that implements remove() in a way that actually removes > elements? > > > > Since this method transfers control it seems a little mean to place such a > restriction on the returned Iterator. Although, there is no clear means of > stating to the caller whether such an iterator supports removal or not, but > that seems to be generally the case for any Iterator returning method. > > Paul. > -- Tomasz Kowalczewski From pavel.rappo at oracle.com Tue May 19 11:26:15 2015 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Tue, 19 May 2015 12:26:15 +0100 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> Message-ID: Any specific implementations can always be added later. As far as I can see, the spec for `asIterator()` does not specify any identity/state properties of the returned object. -Pavel > On 19 May 2015, at 11:41, Tomasz Kowalczewski wrote: > > Is there a plan to override the default method asIterator() in specific > implementations of Enumeration to avoid creating new > object? From amy.lu at oracle.com Tue May 19 11:27:40 2015 From: amy.lu at oracle.com (Amy Lu) Date: Tue, 19 May 2015 19:27:40 +0800 Subject: JDK 9 RFR of JDK-8080658: Update FindDecoderBugs.java to use random number generator library Message-ID: <555B1E2C.8090106@oracle.com> sun/nio/cs/FindDecoderBugs.java This test uses randomness and has been observed to intermittently fail. This patch is to update the test to use the random number testing library, to better identify the cause of any future failures. Please review the patch. I also need a sponsor for this change. bug: https://bugs.openjdk.java.net/browse/JDK-8080658 webrev: http://cr.openjdk.java.net/~amlu/8080658/webrev.00/ Thanks, Amy From sundararajan.athijegannathan at oracle.com Tue May 19 12:15:45 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Tue, 19 May 2015 17:45:45 +0530 Subject: RFR 8072002: The spec on javax.script.Compilable contains a typo and confusing inconsistency Message-ID: <555B2971.3080408@oracle.com> Please review http://cr.openjdk.java.net/~sundar/8072002/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8072002 Thanks, -Sundar From marcus.lagergren at oracle.com Tue May 19 12:21:44 2015 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Tue, 19 May 2015 14:21:44 +0200 Subject: RFR 8072002: The spec on javax.script.Compilable contains a typo and confusing inconsistency In-Reply-To: <555B2971.3080408@oracle.com> References: <555B2971.3080408@oracle.com> Message-ID: +1 > On 19 May 2015, at 14:15, A. Sundararajan wrote: > > Please review http://cr.openjdk.java.net/~sundar/8072002/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8072002 > > Thanks, > -Sundar From paul.sandoz at oracle.com Tue May 19 12:26:03 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 19 May 2015 14:26:03 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> Message-ID: <214874C8-F3CF-4EDD-8E9A-E9C1EAA0433E@oracle.com> On May 19, 2015, at 12:41 PM, Tomasz Kowalczewski wrote: > Is there a plan to override the default method asIterator() in specific implementations of Enumeration to avoid creating new object? JarFile::entries already returns JarEntryIterator which is both. > I suppose one could, it's easy to do in some cases like in JarFile. Given that Enumeration is a legacy thing time could be better spent on adding Stream returning methods, which already exist on JarFile/ZipFile. Contributions will be warmly received for Stream returning methods on ClassLoader, NetworkInterface etc.! > To be fair I did some tests and when I wrap Enumerable into simple Iterator adapter it will almost always get scalar replaced by escape analysis (unless, of course, it actually escapes :)). > Right :-) works until it doesn't. Paul. From attila.szegedi at oracle.com Tue May 19 12:26:16 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Tue, 19 May 2015 14:26:16 +0200 Subject: RFR 8072002: The spec on javax.script.Compilable contains a typo and confusing inconsistency In-Reply-To: <555B2971.3080408@oracle.com> References: <555B2971.3080408@oracle.com> Message-ID: +1 > On May 19, 2015, at 2:15 PM, A. Sundararajan wrote: > > Please review http://cr.openjdk.java.net/~sundar/8072002/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8072002 > > Thanks, > -Sundar From Roger.Riggs at Oracle.com Tue May 19 13:24:09 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 19 May 2015 09:24:09 -0400 Subject: JDK 9 RFR of JDK-8080658: Update FindDecoderBugs.java to use random number generator library In-Reply-To: <555B1E2C.8090106@oracle.com> References: <555B1E2C.8090106@oracle.com> Message-ID: <555B3979.2050904@Oracle.com> Hi Amy, Looks fine. Roger On 5/19/2015 7:27 AM, Amy Lu wrote: > sun/nio/cs/FindDecoderBugs.java > > This test uses randomness and has been observed to intermittently > fail. This patch is to update the test to use the random number > testing library, to better identify the cause of any future failures. > > Please review the patch. I also need a sponsor for this change. > > bug: https://bugs.openjdk.java.net/browse/JDK-8080658 > webrev: http://cr.openjdk.java.net/~amlu/8080658/webrev.00/ > > Thanks, > Amy > From Roger.Riggs at Oracle.com Tue May 19 13:43:17 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 19 May 2015 09:43:17 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <40097F7F-38B4-42FB-8A84-4070C6F9C7E4@oracle.com> References: <5550CFA1.9010606@Oracle.com> <68D6442A-D329-45CF-BE11-43D110918811@oracle.com> <555A5046.1020401@Oracle.com> <40097F7F-38B4-42FB-8A84-4070C6F9C7E4@oracle.com> Message-ID: <555B3DF5.30400@Oracle.com> Hi Paul, a couple of followup responses... On 5/18/2015 5:16 PM, Paul Sandoz wrote: > >>> >>> 251 /** >>> 252 * Kills the subprocess forcibly. The subprocess represented by this >>> 253 * {@code Process} object is forcibly terminated. >>> 254 * Forcible process destruction is defined as the immediate termination of a >>> 255 * process, whereas normal termination allows a process to shut down cleanly. >>> 256 * If the process is not alive, no action is taken. >>> 257 *

>>> 258 * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is >>> 259 * {@link java.util.concurrent.CompletableFuture#complete completed} >>> 260 * when the process has terminated. >>> 261 * >> insert @implSpec >>> 262 *

The default implementation of this method invokes {@link #destroy} >>> 263 * and so may not forcibly terminate the process. >> insert @implNote >>> 264 * Concrete implementations of this class are strongly encouraged to override >>> 265 * this method with a compliant implementation. >> legacy spec - move up before other @ tags >>> 266 * Invoking this method on {@code Process} objects returned by >>> 267 * {@link ProcessBuilder#start} and {@link Runtime#exec} forcibly terminate >>> 268 * the process. >>> 269 * >>> >>> Use @ImplNote? >> Most of this is spec, not informational. > Sorry i meant @implSpec, including for the "Concrete impls..." bit. Perhaps I misunderstood the narrow scope of @implSpec. The @implSpec is only for the specific implementation of the method being declared. The concrete implementations are internal subclasses are out of that scope. ... >>> >>> 361 * If the process is {@link #isAlive not alive} the {@link CompletableFuture} >>> 362 * is immediately {@link java.util.concurrent.CompletableFuture#complete completed}. >>> >>> s/is immediately/is returned/ ? >> The important action to be specified is that the CF is completed() immediately. >> Potentially it could say it is completed before the CF is returned from onExit(). >> > Yeah, that is what i was trying to get across, it returns with an already completed CF. ok; * If the process is not alive the CompletableFuture returned has been completed. > > >>> >>> 406 * @return a {@code CompletableFuture} for the Process; >>> 407 * a unique instance is returned for each call to {@code onExit}. >>> 408 * >>> >>> Any need to mention about unique instances? >> yes, since the hierarchy of the CF instances is visible to the app and it makes >> a difference whether a unique CF is returned for each call or whether >> the same CF is returned from each call. > Perhaps say "Returns a new CF..." and "@return a new {@code ..." ? ok > >>> >>> 429 /** >>> 430 * Returns a ProcessHandle for the Process. >>> 431 * >>> >>> Some methods talk about "the subprocess" where as others talk about "the Process" and others "the process". >> That variation of terminology predates this update. > I think it's best to try and be consistent throughout the class e.g. keep with the existing term or change to consistently use a new term. > > >>> >>> 456 /** >>> 457 * Returns a snapshot of information about the process. >>> 458 * >>> 459 *

An {@link ProcessHandle.Info} instance has various accessor methods >>> 460 * that return information about the process, if the process is alive and >>> 461 * the information is available, otherwise {@code null} is returned. >>> 462 * >>> 463 * @implSpec >>> 464 * This implementation returns information about the process as: >>> 465 * {@link #toHandle toHandle().info()}. >>> 466 * >>> 467 * @return a snapshot of information about the process; non-null >>> >>> Dangling "non-null". Do you mean it's can never be null or ", otherwise null if the process is not alive or such information is not available"? I suspect the former now all Info methods return Optional. >> It is always non-null. > Ok, so the first paragraph needs tweaking. ok, the description of the methods of the info class are better left to the Info class. ... >>> >>> 86 /** >>> 87 * Returns the native process ID of the process. The native process ID is an >>> 88 * identification number that the operating system assigns to the process. >>> 89 * >>> 90 * @return the native process ID of the process >>> 91 * @throws UnsupportedOperationException if the implementation >>> 92 * does not support this operation >>> 93 */ >>> 94 long getPid(); >>> >>> In what cases could this throw a USO if the static "of "method did not? >> Its in an interface that might have arbitrary implementations. In a theoretical >> Process implementation for remote processes their might not be a viable pid >> or the access controls might be such that the PID is meaningless or restricted. >> > Ok, i think i get it: a call ProcessHandle.getPid obtained from ProcessHandle.of will never from a USO but other implementations of ProcessHandle might. yes >>> >>> 326 * @return an {@code Optional} for the process to be >>> 327 * forcibly destroyed; >>> 328 * the {@code Optional} has the value of the ProcessHandle >>> 329 * if the request to terminate was successful, otherwise it is empty >>> 330 * @throws IllegalStateException if the process is the current process >>> 331 */ >>> 332 Optional destroyForcibly(); >>> >>> Under what cases would an empty optional be returned? e.g. if native permissions are not granted? >> yes, but Alan's and other remarks recommend changing the return type. >> boolean will cover case to reflect that it was not possible to request the process >> to be destroyed without creating a confusing state of an Optional. > Yes, that seems a better signal. What could the caller do if false is returned? not much i guess except log something. Correct, there is not much to log unless the OS specific error returns are exposed. Thanks, Roger From tomasz.kowalczewski at gmail.com Tue May 19 13:46:54 2015 From: tomasz.kowalczewski at gmail.com (Tomasz Kowalczewski) Date: Tue, 19 May 2015 15:46:54 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <214874C8-F3CF-4EDD-8E9A-E9C1EAA0433E@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> <214874C8-F3CF-4EDD-8E9A-E9C1EAA0433E@oracle.com> Message-ID: Are you talking about ClassLoader::{findResources, getBootstrapResources, getResources, getSystemResources} and NetworkInterface::{getInetAddresses, getNetworkInterfaces, getSubInterfaces}? On Tue, May 19, 2015 at 2:26 PM, Paul Sandoz wrote: > On May 19, 2015, at 12:41 PM, Tomasz Kowalczewski < > tomasz.kowalczewski at gmail.com> wrote: > > Is there a plan to override the default method asIterator() in specific > implementations of Enumeration to avoid creating new object? > JarFile::entries already returns JarEntryIterator which is both. > > > > I suppose one could, it's easy to do in some cases like in JarFile. > > Given that Enumeration is a legacy thing time could be better spent on > adding Stream returning methods, which already exist on JarFile/ZipFile. > > Contributions will be warmly received for Stream returning methods on > ClassLoader, NetworkInterface etc.! > > > > To be fair I did some tests and when I wrap Enumerable into simple > Iterator adapter it will almost always get scalar replaced by escape > analysis (unless, of course, it actually escapes :)). > > > > Right :-) works until it doesn't. > > Paul. > -- Tomasz Kowalczewski From rob.mckenna at oracle.com Tue May 19 13:58:43 2015 From: rob.mckenna at oracle.com (Rob McKenna) Date: Tue, 19 May 2015 14:58:43 +0100 Subject: RFR: 8077822: javac does not recognize '*.java' as file if '-J' option is specified Message-ID: <555B4193.1000108@oracle.com> Hi folks, Because of platform specifics the Java launcher contains some extra wildcard expansion processing on Windows. As part of this processing the list of args received by CreateApplicationArgs (java_md.c) is compared to the original list in the java launchers main method. Unfortunately the CreateApplicationArgs list has already been filtered by TranslateApplicationArgs which removes VM specific flags. This results in the launcher incorrectly neglecting to expand wildcard arguments. This fix filters the main method args in the same way so CreateApplicationArgs will be comparing like with like. http://cr.openjdk.java.net/~robm/8077822/webrev.01/ -Rob From stuart.marks at oracle.com Tue May 19 15:28:54 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Tue, 19 May 2015 08:28:54 -0700 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <1B161A9D-6AD7-4AE9-83D3-74F6167ED643@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555A6B89.7060801@oracle.com> <1B161A9D-6AD7-4AE9-83D3-74F6167ED643@oracle.com> Message-ID: <555B56B6.2090505@oracle.com> On 5/19/15 1:04 AM, Paul Sandoz wrote: > On May 19, 2015, at 12:45 AM, Stuart Marks wrote: >> OK, good. I tweaked it somewhat to say "if any method is called" instead of "operated on" to make it absolutely clear that the underlying Enumeration shouldn't be touched after the call to asIterator(). (Yes, that includes hasMoreElements.) >> > > Ok. FWIW "operated on" is a term we have used in Stream and Spliterator. > > e.g.: > > *

Traversal of elements should be accomplished through the spliterator. > * The behaviour of splitting and traversal is undefined if the iterator is > * operated on after the spliterator is returned. When I was reading the version of the Enumeration spec that had "operated on" I was thinking of hasMoreElements() implementations with side effects, and then I had a little argument with the voice in my head that said, "But I wasn't operating on the Enumeration, I just called hasMoreElements() to see if it had any more elements!" and so I sighed and said, "Just don't call any methods on Enumeration, OK??!" (Yep, you heard it here first: we design APIs by having arguments with the voices in our heads.) s'marks From paul.sandoz at oracle.com Tue May 19 15:35:14 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 19 May 2015 17:35:14 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> <214874C8-F3CF-4EDD-8E9A-E9C1EAA0433E@oracle.com> Message-ID: <3E06751E-C0D9-49B6-B711-2A4C85770D24@oracle.com> On May 19, 2015, at 3:46 PM, Tomasz Kowalczewski wrote: > Are you talking about ClassLoader::{findResources, getBootstrapResources, getResources, getSystemResources} and NetworkInterface::{getInetAddresses, getNetworkInterfaces, getSubInterfaces}? Yes, all those are potential candidates to consider for additional stream returning methods. A little more care is probably required for ClassLoader. Paul. > > On Tue, May 19, 2015 at 2:26 PM, Paul Sandoz wrote: > On May 19, 2015, at 12:41 PM, Tomasz Kowalczewski wrote: > > Is there a plan to override the default method asIterator() in specific implementations of Enumeration to avoid creating new object? JarFile::entries already returns JarEntryIterator which is both. > > > > I suppose one could, it's easy to do in some cases like in JarFile. > > Given that Enumeration is a legacy thing time could be better spent on adding Stream returning methods, which already exist on JarFile/ZipFile. > > Contributions will be warmly received for Stream returning methods on ClassLoader, NetworkInterface etc.! > > > > To be fair I did some tests and when I wrap Enumerable into simple Iterator adapter it will almost always get scalar replaced by escape analysis (unless, of course, it actually escapes :)). > > > > Right :-) works until it doesn't. > > Paul. > > > > -- > Tomasz Kowalczewski From martinrb at google.com Tue May 19 15:42:41 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 19 May 2015 08:42:41 -0700 Subject: JDK 9 RFR of JDK-8080658: Update FindDecoderBugs.java to use random number generator library In-Reply-To: <555B1E2C.8090106@oracle.com> References: <555B1E2C.8090106@oracle.com> Message-ID: Thanks. We believe there is a bug in the JDK revealed by FindDecoderBugs - so actually find that bug and provide a repro recipe! On Tue, May 19, 2015 at 4:27 AM, Amy Lu wrote: > sun/nio/cs/FindDecoderBugs.java > > This test uses randomness and has been observed to intermittently fail. > This patch is to update the test to use the random number testing library, > to better identify the cause of any future failures. > > Please review the patch. I also need a sponsor for this change. > > bug: https://bugs.openjdk.java.net/browse/JDK-8080658 > webrev: http://cr.openjdk.java.net/~amlu/8080658/webrev.00/ > > Thanks, > Amy > > From joe.darcy at oracle.com Tue May 19 15:46:48 2015 From: joe.darcy at oracle.com (joe darcy) Date: Tue, 19 May 2015 08:46:48 -0700 Subject: JDK 9 RFR of JDK-8080658: Update FindDecoderBugs.java to use random number generator library In-Reply-To: References: <555B1E2C.8090106@oracle.com> Message-ID: <555B5AE8.6080707@oracle.com> On 5/19/2015 8:42 AM, Martin Buchholz wrote: > Thanks. > > We believe there is a bug in the JDK revealed by FindDecoderBugs - so > actually find that bug and provide a repro recipe! Yes, the random number library in the jtreg directory prints out the seed used, which should make reproducing the failure much easier :-) -Joe From Roger.Riggs at Oracle.com Tue May 19 15:48:14 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 19 May 2015 11:48:14 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555AF5A2.5060205@gmail.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> <5555CC06.4020507@gmail.com> <555A5E81.8050804@Oracle.com> <555AF5A2.5060205@gmail.com> Message-ID: <555B5B3E.60104@Oracle.com> Hi Peter, On 5/19/2015 4:34 AM, Peter Levart wrote: > Hi Roger, > > On 05/18/2015 11:49 PM, Roger Riggs wrote: >> The earlier spec specifically used the common pool but from a >> specification point of view >> it allows more flexibility in the implementation not to bind onExit >> to the commonPool. >> Its not clear that the attributes of threads used to handle output or >> managing Processes >> are the same as those attributed to the commonPool. >> >> The default sizing of the commonPool is based on the number of >> processors >> and does not grow (except via the ManagedBlockers) mechanism. >> The number of threads waiting for processes is unrelated to the >> number of CPUs. >> It is simpler to maintain to use a separate pool and not depend on >> consistent >> assumptions between Process handling and the commonPool. > > I'm not advocating to use commonPool for waiting on the process > exit(s). We have special low-stack-size reaper threads for this > purpose and in future there could be just one thread maybe. I'm also > not advocating to use commonPool in default Process.onExit() > implementation where the thread must wait for process to exit. I'm > just questiong the use of commonPool vs. AsyncExecutor in > ProcessImpl.onExit() and ProcessHandleImpl.onExit() where there is an > async CompletableFuture stage inserted to shield from exposing > internal low-stack-size threads. > > The code that is executed by commonPool (or AsyncExecutor) by onExit() > continuations doesn't wait for process to exit. The number of > processes spawned does not matter directly. Only the rate of process > exits does. The code executed will be a cleanup-type / > post-exit-actions-type of code which seems to be typical code for > commonPool. Code dealing with process input/output will typically be > executed concurrently with the Process while the process is still > running and not by onExit() continuations. makes sense > > On 05/18/2015 11:49 PM, Roger Riggs wrote: >> One alternative is for onExit to return a CF subclass that maps >> synchronous methods >> to the corresponding async methods. Each call to onExit would return >> a new proxy >> that would delegate to a new CF created from the >> ExitCompletion.handle(...). >> For all requests that involved calling app code it would delegate to >> the corresponding >> async method. For example, >> >> CompletableFuture cf = >> ProcessHandleImpl.completion(getPid(), false) >> .handle((exitStatus, unusedThrowable) -> this); >> return new CompletionProxy(cf); >> >> The CompletionProxy can ensure that all CFs that call application >> code are Async. >> It would override the syncronous methods and redirect to the >> corresponding Async method. >> >> public CompletableFuture thenApply(Function> ProcessHandle, ? extends U> fn) { >> return thenApplyAsync(fn); >> } >> >> The CompletionProxy can also supply the Executor as needed unless >> supplied by the application >> >> It adds a simple delegation but removed the extra task dispatch >> except where needed. >> >> Does that work as you would expect? >> >> Thanks, Roger > > I thought about that too. Unfortunately, there are also xxxAsync(..., > Executor) methods that appear to attach asynchronous continuations. > And they do, if passed-in Executor dispatches to separate threads. But > users can pass in a "SynchronousExecutor" like the following: > > public class SynchronousExecutor implements Executor { > @Override > public void execute(Runnable command) { > command.run(); > } > } > > ...which makes xxxAsync(..., Executor) methods equivalent to > synchronous-continuation-attaching methods. It might be a bit interventionist, but its possible check the concrete type of the executors and allow direct use of those that are built-in; or to replace unknown ones with a built-in. It would be lighter weight than always queuing a task and potentially starting up a new thread. > > It would be nice to have an API that guaranteed division of threads > between internal-code and user-code threads, but such API would have > to be constructed around something different than Executor interface. > I think what we have with insertion of an async stage is the best we > can do with CompletableFuture API. ok, the implementation can be updated if something new becomes available. > > The only question remaining is whether to use AsyncExecutor in > ProcessImpl and ProcessHandleImpl .onExit() methods for executing the > inserted async stage (and any synchronous continuation of it), or only > in default implementation of Process.onExit() for waiting on process > exit. The AsyncExecutor properties are such that it doesn't pre-start > any threads and if not used, doesn't represent any system overhead. > This is good if it is normally not used and would make it a good > candidate for default Process.onExit() implementation which is used > only in uncommon custom Process implementations. Using it in > ProcessImpl and ProcessHandleImpl .onExit() methods makes it being > used after each onExit() call, albeit potentially only briefly, so > there's a chance that only one thread will ever be started and will > die after every 60s of inactivity. commonPool() is no different from > that perspective, but there is a chance, being a common pool, that it > is used for other purposes too, so potentially less thread starts and > stops can be achieved. Makes sense > There's also the lack of uniformity if AsyncExecutor is used which can > have surprising effects. For example, a user switches from using > synchronous onExit() continuation to asynchronous one and as a result > the executor changes which can results in different behavior. That argument would inhibit changing the implementation since there is an implicit dependency on the implementation of the Executor. > > I would be *for* using the AsyncExecutor in Process[Handle]Impl if it > could be set as default Executor for any continuation born from > returned CompletableFuture transitively. There were some changes > announced from jsr166 team that would allow that (subclassing CF so > that the methods returned a subclass of CF), so this could perhaps be > the way to go... A factory for the new CF's that are returned from CF would be quite useful if/when that comes to pass. I've updated the implementation to use the commonPool for ProcessHandleImpl and the ProcessImpls and retaining the asyncExecutor pool for Process.onExit. Thanks, Roger > > Regards, Peter > From vladimir.x.ivanov at oracle.com Tue May 19 15:50:04 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 19 May 2015 18:50:04 +0300 Subject: RFR(XS) : 8055269 : java/lang/invoke/MethodHandles/CatchExceptionTest.java fails intermittently In-Reply-To: <555B03E0.6040709@oracle.com> References: <555A268E.8090206@oracle.com> <555A2835.4030004@oracle.com> <555A297D.3050805@oracle.com> <555B03E0.6040709@oracle.com> Message-ID: <555B5BAC.2040006@oracle.com> Looks good then! Best regards, Vladimir Ivanov On 5/19/15 12:35 PM, Igor Ignatyev wrote: > Vladimir, > > thank you for review. > > regarding slot consumption calculation, to get parameters limited by > slot number, the test uses Helper.getParams method which implements this > calculation > (test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java:133-148) > > > -- > Igor > > On 05/18/2015 09:03 PM, Vladimir Ivanov wrote: >> Ok, now I see long.class in the list :-) >> >> Does the test checks 255 limit on slots or logical arguments? It should >> check slot size, but I don't see logic for computing slot consumption >> for generated signatures. >> >> Best regards, >> Vladimir Ivanov >> >> On 5/18/15 8:58 PM, Vladimir Ivanov wrote: >>> Igor, >>> >>> Looks good. >>> >>> You don't need to bother computing slot size for a signature since you >>> use only 1-slot types, do you? >>> >>> test/java/lang/invoke/MethodHandles/CatchExceptionTest.java: >>> Class classes[] = { >>> Object.class, >>> long.class, >>> int.class, >>> byte.class, >>> Integer[].class, >>> double[].class, >>> String.class, >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> On 5/18/15 8:51 PM, Igor Ignatyev wrote: >>>> http://cr.openjdk.java.net/~iignatyev/8055269/webrev.00/ >>>> 23 lines changed: 8 ins; 9 del; 6 mod >>>> >>>> Hi all, >>>> >>>> please review the tiny fix for CatchExceptionTest test. >>>> >>>> problem: the tests generates a target w/ 255 parameters, so a >>>> corresponding handler should have 256 parameters. that violates >>>> restrictions. >>>> >>>> fix: limit target's arity by 254 >>>> >>>> side changes: >>>> - cover a handler w/o dropped arguments case >>>> - fix a typo in a comment >>>> - always print maxArg, maxDrop and generated parameters' classes >>>> - print test properties in runTest method instead of ctor. >>>> >>>> testing: locally, w/ and w/o -Dthorough >>>> JBS: https://jbs.oracle.com/bugs/browse/JDK-8055269 >>>> From daniel.fuchs at oracle.com Tue May 19 16:13:52 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 19 May 2015 18:13:52 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> Message-ID: <555B6140.2010700@oracle.com> On 19/05/15 12:07, Paul Sandoz wrote: >> Should anything be said also about default remove() method inherited from Iterator interface? Are custom asIterator() implementations allowed to return an Iterator that implements remove() in a way that actually removes elements? >> > > Since this method transfers control it seems a little mean to place such a restriction on the returned Iterator. Although, there is no clear means of stating to the caller whether such an iterator supports removal or not, but that seems to be generally the case for any Iterator returning method. Ah... Interesting use case. I hadn't thought of that. What should ConcurrentHashMap.keys().asIterator().remove() do? cheers, -- daniel From chris.hegarty at oracle.com Tue May 19 16:19:07 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 19 May 2015 17:19:07 +0100 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <555B6140.2010700@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> <555B6140.2010700@oracle.com> Message-ID: <9759D303-DCCA-45B9-ADC3-92F4807AB066@oracle.com> On 19 May 2015, at 17:13, Daniel Fuchs wrote: > On 19/05/15 12:07, Paul Sandoz wrote: >>> Should anything be said also about default remove() method inherited from Iterator interface? Are custom asIterator() implementations allowed to return an Iterator that implements remove() in a way that actually removes elements? >>> > >> Since this method transfers control it seems a little mean to place such a restriction on the returned Iterator. Although, there is no clear means of stating to the caller whether such an iterator supports removal or not, but that seems to be generally the case for any Iterator returning method. + * @implSpec + * The returned Iterator's {@link Iterator#hasNext hasNext} method calls and returns + * the value from this Enumeration's {@code hasMoreElements} method; its + * {@link Iterator#next next} method calls and returns the value from this Enumeration's + * {@code nextElement} method; and its {@link Iterator#remove remove} method throws + * {@code UnsupportedOperationException}. + * Why not turn the proposed implSpec into an implNote, and leave it up to other API?s returning Enumerations to specify their behaviour of asIterator, if they override the default. -Chris. > > Ah... Interesting use case. I hadn't thought of that. > > What should ConcurrentHashMap.keys().asIterator().remove() do? > > cheers, > > -- daniel From daniel.fuchs at oracle.com Tue May 19 17:02:56 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 19 May 2015 19:02:56 +0200 Subject: RFR: 8080608: Missing archive name from jdeps -v -e output if no dependency on other JAR Message-ID: <555B6CC0.5070000@oracle.com> Hi, Please find below a patch for jdeps: http://cr.openjdk.java.net/~dfuchs/webrev_8080608/webrev.00/ https://bugs.openjdk.java.net/browse/JDK-8080608 The issue is described in JDK-8080608 as follows: I have 2 jars: indirect2.jar: class use.indirect2.UseUnsafeIndirectly2 { static Object obj = new use.unsafe.UseUnsafeClass(); } unsafe.jar: class use.unsafe.UseUnsafeClass { static Object unsafe = Unsafe.getUnsafe(); } class use.unsafe.UseClassWithUnsafe { static Object obj = new UseUnsafeClass() } When I run: jdeps -v -e use.unsafe.UseUnsafeClass indirect2.jar unsafe.jar it prints: indirect2.jar -> dist/unsafe.jar use.indirect2.UseUnsafeIndirectly2 -> use.unsafe.UseUnsafeClass unsafe.jar use.unsafe.UseClassWithUnsafe -> use.unsafe.UseUnsafeClass unsafe.jar as if use.unsafe.UseClassWithUnsafe was contained in indirect2.jar, while it is in fact contained in unsafe.jar... The fix will make sure that jdeps prints instead: indirect2.jar -> dist/unsafe.jar use.indirect2.UseUnsafeIndirectly2 -> use.unsafe.UseUnsafeClass unsafe.jar unsafe.jar -> dist/unsafe.jar use.unsafe.UseClassWithUnsafe -> use.unsafe.UseUnsafeClass unsafe.jar best regards, -- daniel From paul.sandoz at oracle.com Tue May 19 17:03:45 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 19 May 2015 19:03:45 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <555B6140.2010700@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> <555B6140.2010700@oracle.com> Message-ID: <4F4B61E8-EAFB-4331-834C-1045C7588C7B@oracle.com> On May 19, 2015, at 6:13 PM, Daniel Fuchs wrote: > On 19/05/15 12:07, Paul Sandoz wrote: >>> Should anything be said also about default remove() method inherited from Iterator interface? Are custom asIterator() implementations allowed to return an Iterator that implements remove() in a way that actually removes elements? >>> > >> Since this method transfers control it seems a little mean to place such a restriction on the returned Iterator. Although, there is no clear means of stating to the caller whether such an iterator supports removal or not, but that seems to be generally the case for any Iterator returning method. > > Ah... Interesting use case. I hadn't thought of that. > > What should ConcurrentHashMap.keys().asIterator().remove() do? > I would not have high expectations that it will not throw unless there was some explicit documentation. This is legacy stuff. One should really be using CHM.keysSet(). Paul. From paul.sandoz at oracle.com Tue May 19 17:55:27 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 19 May 2015 19:55:27 +0200 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork Message-ID: Hi, https://bugs.openjdk.java.net/browse/JDK-8080623 diff -r ea3ca5cfc3c6 src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 20:04:29 2015 +0300 +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 19:54:00 2015 +0200 @@ -1328,13 +1328,9 @@ /** * Number of times to spin-wait before blocking. The spins (in * awaitRunStateLock and awaitWork) currently use randomized - * spins. If/when MWAIT-like intrinsics becomes available, they - * may allow quieter spinning. The value of SPINS must be a power - * of two, at least 4. The current value causes spinning for a - * small fraction of typical context-switch times, well worthwhile - * given the typical likelihoods that blocking is not necessary. + * spins. Currently set to zero to reduce CPU usage. */ - private static final int SPINS = 1 << 11; + private static final int SPINS = 0; /** * Increment for seed generators. See class ThreadLocal for This is a quick fix from Doug to reduce the CPU usage in F/J computations that was introduced with the fix for JDK-805624 to reduce thread construction. Many thanks to Staffan Friberg for doing the performance work and analysis. The F/J pool makes a worker thread spin for a bit while waiting for more work to become available rather than immediately blocking. This results in higher CPU usage and can cause performance regressions since there is less CPU resources available to other threads or applications. The interim fix is to turn off spinning. This has the effect of making questionable cases worse (e.g. parallel streams with an inappropriate small number elements). It will be back ported to 8u60 and it is planned that a better solution will be introduced in 9 (and time permitting it may be possible to backport that). Paul. From chris.hegarty at oracle.com Tue May 19 18:08:05 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 19 May 2015 19:08:05 +0100 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork In-Reply-To: References: Message-ID: <8B1C8753-92C9-4DA3-AB6A-C3CADFAD9A43@oracle.com> On 19 May 2015, at 18:55, Paul Sandoz wrote: > Hi, > > https://bugs.openjdk.java.net/browse/JDK-8080623 > > diff -r ea3ca5cfc3c6 src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java > --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 20:04:29 2015 +0300 > +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 19:54:00 2015 +0200 > @@ -1328,13 +1328,9 @@ > /** > * Number of times to spin-wait before blocking. The spins (in > * awaitRunStateLock and awaitWork) currently use randomized > - * spins. If/when MWAIT-like intrinsics becomes available, they > - * may allow quieter spinning. The value of SPINS must be a power > - * of two, at least 4. The current value causes spinning for a > - * small fraction of typical context-switch times, well worthwhile > - * given the typical likelihoods that blocking is not necessary. > + * spins. Currently set to zero to reduce CPU usage. > */ > - private static final int SPINS = 1 << 11; > + private static final int SPINS = 0; > > /** > * Increment for seed generators. See class ThreadLocal for > > This is a quick fix from Doug to reduce the CPU usage in F/J computations that was introduced with the fix for JDK-805624 to reduce thread construction. Many thanks to Staffan Friberg for doing the performance work and analysis. > > The F/J pool makes a worker thread spin for a bit while waiting for more work to become available rather than immediately blocking. This results in higher CPU usage and can cause performance regressions since there is less CPU resources available to other threads or applications. > > The interim fix is to turn off spinning. This has the effect of making questionable cases worse (e.g. parallel streams with an inappropriate small number elements). > > It will be back ported to 8u60 and it is planned that a better solution will be introduced in 9 (and time permitting it may be possible to backport that). Sounds like a reasonable plan. The change looks ok, for now. -Chris. > Paul. From mikhail.cherkasov at oracle.com Tue May 19 18:13:23 2015 From: mikhail.cherkasov at oracle.com (mikhail cherkasov) Date: Tue, 19 May 2015 21:13:23 +0300 Subject: [8] RFR of 8066985: Java Webstart downloading packed files can result in Timezone set to UTC In-Reply-To: <551AF091.9060904@oracle.com> References: <550976B9.6030503@oracle.com> <5509F73C.6000306@oracle.com> <550AD4C9.9030905@oracle.com> <550AEF48.4070904@gmail.com> <550AF969.7070706@gmail.com> <550C36FD.701@oracle.com> <5511C5BE.2010809@oracle.com> <5511E9CB.7050504@oracle.com> <5512850F.90701@oracle.com> <5512D20D.4070709@oracle.com> <55145EBE.7070005@oracle.com> <55157E45.1030204@oracle.com> <55192507.4090704@oracle.com> <551AF091.9060904@oracle.com> Message-ID: <555B7D43.3020802@oracle.com> Hi there, I reverted the last change, now test uses native unpacker as before. But I fixed the test other way, now I warm up native unpacker to make it initialized on native level before the main part of test: http://cr.openjdk.java.net/~mcherkas/8066985/webrev.11/test/tools/pack200/DefaultTimeZoneTest.java.html Thanks, Mikhail. On 3/31/2015 10:08 PM, mikhail cherkasov wrote: > And one more change in test. > > Native packer/unpacker can throw exception during execution, but this > issue is out of scope of this fix, > so I just disable it for test: > > http://cr.openjdk.java.net/~mcherkas/8066985/webrev.09/test/tools/pack200/DefaultTimeZoneTest.java.html > > > On 3/30/2015 1:27 PM, mikhail cherkasov wrote: >> >> On 3/27/2015 6:59 PM, Kumar Srinivasan wrote: >>> yes that will work!, also why aren't all these final ? >> fixed: http://cr.openjdk.java.net/~mcherkas/8066985/webrev.08/ >> >> > From kumar.x.srinivasan at oracle.com Tue May 19 18:22:55 2015 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Tue, 19 May 2015 11:22:55 -0700 Subject: RFR: 8077822: javac does not recognize '*.java' as file if '-J' option is specified In-Reply-To: <555B4193.1000108@oracle.com> References: <555B4193.1000108@oracle.com> Message-ID: <555B7F7F.8060006@oracle.com> Hi Rob, Looks good, except a small nit, I would've written this with a positive check + /* Copy the non-vm args */ + for (i = 0; i < nargc ; i++) { + const char *arg = stdargs[i].arg; + if (arg[0] != '-' || arg[1] != 'J') { + argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg)); + argv[nargs].arg = JLI_StringDup(arg); + argv[nargs].has_wildcard = stdargs[i].has_wildcard; + nargs++; + } + } as follows..... /* Copy the non-vm args */ for (i = 0; i < nargc ; i++) { const char *arg = stdargs[i].arg; if (arg[0] == '-' && arg[1] == 'J') // OR if (JLI_StrNCmp(arg, "-J", JLI_StrLen("-J") == 0) continue; argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg)); argv[nargs].arg = JLI_StringDup(arg); argv[nargs].has_wildcard = stdargs[i].has_wildcard; nargs++; } Thanks Kumar On 5/19/2015 6:58 AM, Rob McKenna wrote: > Hi folks, > > Because of platform specifics the Java launcher contains some extra > wildcard expansion processing on Windows. > > As part of this processing the list of args received by > CreateApplicationArgs (java_md.c) is compared to the original list in > the java launchers main method. > > Unfortunately the CreateApplicationArgs list has already been filtered > by TranslateApplicationArgs which removes VM specific flags. This > results in the launcher incorrectly neglecting to expand wildcard > arguments. > > This fix filters the main method args in the same way so > CreateApplicationArgs will be comparing like with like. > > http://cr.openjdk.java.net/~robm/8077822/webrev.01/ > > -Rob From rob.mckenna at oracle.com Tue May 19 18:38:25 2015 From: rob.mckenna at oracle.com (Rob McKenna) Date: Tue, 19 May 2015 19:38:25 +0100 Subject: RFR: 8077822: javac does not recognize '*.java' as file if '-J' option is specified In-Reply-To: <555B7F7F.8060006@oracle.com> References: <555B4193.1000108@oracle.com> <555B7F7F.8060006@oracle.com> Message-ID: <555B8321.40002@oracle.com> Thanks Kumar, I'll alter (& build / test) it before pushing. -Rob On 19/05/15 19:22, Kumar Srinivasan wrote: > Hi Rob, > > Looks good, except a small nit, I would've written this with a positive > check > > + /* Copy the non-vm args */ > + for (i = 0; i < nargc ; i++) { > + const char *arg = stdargs[i].arg; > + if (arg[0] != '-' || arg[1] != 'J') { > + argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * > sizeof(StdArg)); > + argv[nargs].arg = JLI_StringDup(arg); > + argv[nargs].has_wildcard = stdargs[i].has_wildcard; > + nargs++; > + } > + } > > > as follows..... > > /* Copy the non-vm args */ > for (i = 0; i < nargc ; i++) { > const char *arg = stdargs[i].arg; > if (arg[0] == '-' && arg[1] == 'J') // OR if (JLI_StrNCmp(arg, > "-J", JLI_StrLen("-J") == 0) > continue; > argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg)); > argv[nargs].arg = JLI_StringDup(arg); > argv[nargs].has_wildcard = stdargs[i].has_wildcard; > nargs++; > } > > > Thanks > Kumar > > On 5/19/2015 6:58 AM, Rob McKenna wrote: >> Hi folks, >> >> Because of platform specifics the Java launcher contains some extra >> wildcard expansion processing on Windows. >> >> As part of this processing the list of args received by >> CreateApplicationArgs (java_md.c) is compared to the original list in >> the java launchers main method. >> >> Unfortunately the CreateApplicationArgs list has already been filtered >> by TranslateApplicationArgs which removes VM specific flags. This >> results in the launcher incorrectly neglecting to expand wildcard >> arguments. >> >> This fix filters the main method args in the same way so >> CreateApplicationArgs will be comparing like with like. >> >> http://cr.openjdk.java.net/~robm/8077822/webrev.01/ >> >> -Rob > From ivan.gerasimov at oracle.com Tue May 19 19:40:41 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 19 May 2015 22:40:41 +0300 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal Message-ID: <555B91B9.80204@oracle.com> Hi everyone! What about this variant: http://cr.openjdk.java.net/~igerasim/8080535/02/webrev/ No named constant. A comment in the code about initial capacity. In the test, we use the same constant to check if it were sufficient to hold the final number of entries. If someone evil shrinks the initial capacity in the code, the test will not be able to detect it, though it seems unlikely. // Please ignore the change to test/TEST.groups in the webrev; it is a leftover from a fix for JDK-8080330 Sincerely yours, Ivan From joe.darcy at oracle.com Tue May 19 19:41:36 2015 From: joe.darcy at oracle.com (joe darcy) Date: Tue, 19 May 2015 12:41:36 -0700 Subject: JDK 9 RFR of JDK-8075284: fix up miscellaneous TM constructions Message-ID: <555B91F0.1080604@oracle.com> Hello, Please review these changes for JDK-8075284: fix up miscellaneous TM constructions http://cr.openjdk.java.net/~darcy/8075284.0/ which replace convoluted HTML markup for expressing a trademark sign with the HTML ™ --- build and docs build pass with the changes Thanks, -Joe From lance.andersen at oracle.com Tue May 19 19:53:00 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 19 May 2015 15:53:00 -0400 Subject: JDK 9 RFR of JDK-8075284: fix up miscellaneous TM constructions In-Reply-To: <555B91F0.1080604@oracle.com> References: <555B91F0.1080604@oracle.com> Message-ID: Hi Joe, Looks like a typo in src/java.sql/share/classes/java/sql/package.html: -is included in the JavaTM -Standard Edition (Java SETM), version 7. +is included in the Java&trae; I believe there were just two occurrences of the above typo. The rest looks ok Best Lance On May 19, 2015, at 3:41 PM, joe darcy wrote: > Hello, > > Please review these changes for > > JDK-8075284: fix up miscellaneous TM constructions > http://cr.openjdk.java.net/~darcy/8075284.0/ > > which replace convoluted HTML markup for expressing a trademark sign with the HTML ™ --- build and docs build pass with the changes > > Thanks, > > -Joe > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From huizhe.wang at oracle.com Tue May 19 20:09:10 2015 From: huizhe.wang at oracle.com (huizhe wang) Date: Tue, 19 May 2015 13:09:10 -0700 Subject: JDK 9 RFR of JDK-8075284: fix up miscellaneous TM constructions In-Reply-To: <555B91F0.1080604@oracle.com> References: <555B91F0.1080604@oracle.com> Message-ID: <555B9866.6030206@oracle.com> Hi Joe, Looks good to me. You might also change the followings if you want: src/jdk.jdi/share/classes/com/sun/jdi/request/AccessWatchpointRequest.java ------------------------------------------------------------------------ @@ -29,12 +29,11 @@ /** * Request for notification when the contents of a field are accessed * in the target VM. * This event will be triggered when the specified field is accessed - * by JavaTM programming - * language code or by a + * by Java™ programming language code or by a * Java Native Interface (JNI) get function*(Get<Type>Field, * GetStatic<Type>Field).* ({@code GetField, GetStaticField}). src/jdk.jdi/share/classes/com/sun/jdi/request/ModificationWatchpointRequest.java ------------------------------------------------------------------------ @@ -28,11 +28,11 @@ import com.sun.jdi.*; /** * Request for notification when a field is set. * This event will be triggered when a value is assigned to the specified - * field with a JavaTM programming + * field with a Java™ programming * language statement (assignment, increment, etc) or by a * Java Native Interface (JNI) set function*(Set<Type>Field, * SetStatic<Type>Field).* ({@code SetField, SetStaticField}). -Joe On 5/19/2015 12:41 PM, joe darcy wrote: > Hello, > > Please review these changes for > > JDK-8075284: fix up miscellaneous TM constructions > http://cr.openjdk.java.net/~darcy/8075284.0/ > > which replace convoluted HTML markup for expressing a trademark sign > with the HTML ™ --- build and docs build pass with the changes > > Thanks, > > -Joe > From Roger.Riggs at Oracle.com Tue May 19 20:15:25 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 19 May 2015 16:15:25 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555B5B3E.60104@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> <5555CC06.4020507@gmail.com> <555A5E81.8050804@Oracle.com> <555AF5A2.5060205@gmail.com> <555B5B3E.60104@Oracle.com> Message-ID: <555B99DD.7050009@Oracle.com> The webrev, javadoc, and specdiffs have been updated to address recent recommendations: Please review and comment: Webrev: http://cr.openjdk.java.net/~rriggs/webrev-ph/ (May 19) javadoc: http://cr.openjdk.java.net/~rriggs/ph-apidraft/ (May 19) Diffs of the spec/javadoc from previous draft: http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-19/overview-summary.html Thanks, Roger From joe.darcy at oracle.com Tue May 19 20:28:17 2015 From: joe.darcy at oracle.com (joe darcy) Date: Tue, 19 May 2015 13:28:17 -0700 Subject: JDK 9 RFR of JDK-8075284: fix up miscellaneous TM constructions In-Reply-To: References: <555B91F0.1080604@oracle.com> Message-ID: <555B9CE1.5070002@oracle.com> Hi Lance, Well spotted! I'll push a corrected version with -is included in the JavaTM -Standard Edition (Java SETM), version 7. +is included in the Java™ Standard Edition (Java SE™), version 7. (From a quick grep, there weren't any other "&trae" typos in the patch. Thanks, -Joe On 5/19/2015 12:53 PM, Lance Andersen wrote: > Hi Joe, > > Looks like a typo in src/java.sql/share/classes/java/sql/package.html: > > -is included in the JavaTM > -Standard Edition (Java SETM), version 7. > +is included in the Java&trae; > > I believe there were just two occurrences of the above typo. > > The rest looks ok > > Best > Lance > On May 19, 2015, at 3:41 PM, joe darcy > wrote: > >> Hello, >> >> Please review these changes for >> >> JDK-8075284: fix up miscellaneous TM constructions >> http://cr.openjdk.java.net/~darcy/8075284.0/ >> >> >> which replace convoluted HTML markup for expressing a trademark sign >> with the HTML ™ --- build and docs build pass with the changes >> >> 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 kim.barrett at oracle.com Tue May 19 20:41:17 2015 From: kim.barrett at oracle.com (Kim Barrett) Date: Tue, 19 May 2015 16:41:17 -0400 Subject: RFR(M, v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5559D85B.2050500@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> Message-ID: <349D924B-DDA8-4F18-8E8F-A0272ED39B4F@oracle.com> On May 18, 2015, at 8:17 AM, Dmitry Samersoff wrote: > > Everyone, > > Please review updated version of the fix: > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ > > Most important part of the fix provided by Peter Levart, so all > credentials belongs to him. > > -Dmitry Looks good, except a bit in Finalizer.printFinalizerQueue, specifically: 122 /* Clear stack slot containing this variable, to decrease 123 the chances of false retention with a conservative GC */ 124 referent = null; Peter already noted these lines are mis-indented. However I?m not convinced that assignment is actually useful, since I think it can be optimized away. From Alan.Bateman at oracle.com Tue May 19 20:44:42 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 19 May 2015 21:44:42 +0100 Subject: RFR [9] 8072839: JAX-B Plugability Layer: using java.util.ServiceLoader In-Reply-To: <55560D2B.3040400@oracle.com> References: <55560D2B.3040400@oracle.com> Message-ID: <555BA0BA.1070208@oracle.com> On 15/05/2015 16:13, Miroslav Kos wrote: > Hi everybody, > > this is review request for: 8072839: JAX-B Plugability Layer: using > java.util.ServiceLoader > The JAX-B API changed a little bit - proprietary ServiceLoader-like > code has been replaced by java.util.ServiceLoader. This change is > required by Jigsaw, old configuration way still supported. > > JBS:https://bugs.openjdk.java.net/browse/JDK-8072839 > webrev: http://cr.openjdk.java.net/~mkos/8072839/jaxws.02/index.html I skimmed through this and it mostly looks okay. Some really long (200+) lines but that seems to be normal in this area. At some point it would be good to do a wider pass over this code and replace the old style tags ( etc.) with newer forms. In JAXBContext it looks likes a typo "loading facilities" when I assume it should be "loading facility". Are there any new tests for this? Existing tests will exercise some of this but I don't see any tests that will exercise JAXBContextFactory. -Alan. From stuart.marks at oracle.com Tue May 19 21:08:32 2015 From: stuart.marks at oracle.com (Stuart Marks) Date: Tue, 19 May 2015 14:08:32 -0700 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <9759D303-DCCA-45B9-ADC3-92F4807AB066@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> <555B6140.2010700@oracle.com> <9759D303-DCCA-45B9-ADC3-92F4807AB066@oracle.com> Message-ID: <555BA650.5080601@oracle.com> On 5/19/15 3:07 AM, Paul Sandoz wrote: > Since this method transfers control it seems a little mean to place such a restriction on the returned Iterator. Although, there is no clear means of stating to the caller whether such an iterator supports removal or not, but that seems to be generally the case for any Iterator returning method. On 19 May 2015, at 17:13, Daniel Fuchs wrote: > What should ConcurrentHashMap.keys().asIterator().remove() do? On 5/19/15 9:19 AM, Chris Hegarty wrote: > + * @implSpec > + * The returned Iterator's {@link Iterator#hasNext hasNext} method calls and returns > + * the value from this Enumeration's {@code hasMoreElements} method; its > + * {@link Iterator#next next} method calls and returns the value from this Enumeration's > + * {@code nextElement} method; and its {@link Iterator#remove remove} method throws > + * {@code UnsupportedOperationException}. > > Why not turn the proposed implSpec into an implNote, and leave it up to other API?s returning Enumerations to specify their behaviour of asIterator, if they override the default. Wait. The interface *contract* part of the spec doesn't place any restrictions on the remove() method of the returned Iterator. It's silent about remove(), and indeed Iterator.remove() is already optional, so you have to look for the spec of the actual Iterator implementation to find out what it does. It's the @implSpec section that says that it throws UnsupportedOperationException. That's necessary because Enumeration.asIterator() is a default method, so its implementation must be specified so that subclassers can decide whether to override. (See [1] for further information.) With the proposed changeset, ConcurrentHashMap.keys().asIterator().remove() will throw UnsupportedOperationException since it doesn't override remove(). Now CHM uses the same object to implement both Iterator and Enumeration, so presumably it could override asIterator() to return "this" and thereby support the remove() operation. However, I don't think there's any point to doing this, as there are already better ways to iterate a CHM. Specifying the behavior of an implementation that doesn't have a public class has always been a bit problematic. See CHM.keySet()'s discussion of Iterator.remove(). Anything that overrides Enumeration.asIterator().remove() to do something other than the default would have to do something similar. s'marks [1] https://bugs.openjdk.java.net/browse/JDK-8068562 From derek.white at oracle.com Tue May 19 21:10:42 2015 From: derek.white at oracle.com (Derek White) Date: Tue, 19 May 2015 17:10:42 -0400 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5559D85B.2050500@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> Message-ID: <555BA6D2.2050600@oracle.com> On 5/18/15 8:17 AM, Dmitry Samersoff wrote: > Everyone, > > Please review updated version of the fix: > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ > > Most important part of the fix provided by Peter Levart, so all > credentials belongs to him. > > -Dmitry Looks good to me. I also pinged Mandy to check it from a Library perspective. It sounds like she has a review in progress... - Derek > > On 2015-05-16 15:48, Peter Levart wrote: >> >> On 05/16/2015 02:38 PM, Peter Levart wrote: >>> >>> On 05/16/2015 09:35 AM, Dmitry Samersoff wrote: >>>> Derek, >>>> >>>> Personally, I'm for volatile over explicit fence too. >>>> >>>> So I'll change the code if Peter don't have objections. >>> There are no objections. There's one unneeded volatile store to .next >>> field then in enqueue(), but it is followed by another volatile store, >>> so there shouldn't be overhead on Intel and SPARC at least. >>> >>> Regards, Peter >> If you make .next field volatile, then perhaps you could also cache it's >> value in reallyPoll() into a local variable, so that it is not read >> twice. Like this: >> >> private Reference reallyPoll() { /* Must hold lock */ >> Reference r = head; >> if (r != null) { >> Reference rn = r.next; // HERE !!! >> head = (rn == r) ? >> null : >> rn; // Unchecked due to the next field having a raw type >> in Reference >> r.queue = NULL; >> r.next = r; >> queueLength--; >> if (r instanceof FinalReference) { >> sun.misc.VM.addFinalRefCount(-1); >> } >> return r; >> } >> return null; >> } >> >> >> >> Peter >> >> >>>> -Dmitry >>>> >>>> On 2015-05-16 01:59, Derek White wrote: >>>>> Hi Dmitry, Peter, >>>>> >>>>> I should read my email more frequently - I missed Dmitry's last webrev >>>>> email. >>>>> >>>>> My comments on a preference for volatile over Unsafe are not a strong >>>>> objection to using Unsafe fences. I just don't have enough experience >>>>> with Unsafe fences yet to agree that this use is correct. >>>>> >>>>> While looking over this Reference code I found 3-6 really simple things >>>>> that need cleaning up that have been there for years, so I'm not a big >>>>> cheerleader for more complicated things here :-) >>>>> >>>>> - Derek >>>>> >>>>> On 5/15/15 6:46 PM, Derek White wrote: >>>>>> Hi Peter, >>>>>> >>>>>> Some comments below... >>>>>> >>>>>> On 5/14/15 3:50 AM, Peter Levart wrote: >>>>>>> Hi Derek, >>>>>>> >>>>>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>>>>> Hi Peter, >>>>>>>> >>>>>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>>>>> but I have some concerns... >>>>>>> I did have a concern too, ... >>>>>>> >>>>>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>>>>> Hi Dmitry, >>>>>>>>> >>>>>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>>>>> logical. >>>>>>>>> >>>>>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>>>>> threads for the entire time of iteration. This can blow up the >>>>>>>>> application. Suppose one wants to diagnose the application because >>>>>>>>> he suspects that finalizer thread hardly keeps up with production >>>>>>>>> of finalizable instances. This can happen if the allocation rate of >>>>>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>>>>>>> up gradually and is already holding several million objects. Now >>>>>>>>> you initiate the diagnostic command to print the queue. The >>>>>>>>> iteration over and grouping/counting of several millions of >>>>>>>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>>>>>>> reference handler thread. But does not block the threads that >>>>>>>>> allocate finalizable objects. By the time the iteration is over, >>>>>>>>> the JVM blows up and application slows down to a halt doing GCs >>>>>>>>> most of the time, getting OOMEs, etc... >>>>>>>>> >>>>>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>>>>> purposes without holding a lock. The modification required to do >>>>>>>>> that is the following (havent tested this, but I think it should work): >>>>>>>>> >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>>>>> >>>>>>>> One issue to watch out for is the garbage collectors inspect the >>>>>>>> Reference.next field from C code directly (to distinguish active vs. >>>>>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>>>>> >>>>>>>> Your change makes "inactive" References superficially look like >>>>>>>> "enqueued" References. The GC code is rather subtle and I haven't >>>>>>>> yet seen a case where it would get confused by this change, but >>>>>>>> there could easily be something like that lurking in the GC code. >>>>>>> ...but then I thought that GC can in no way treat a Reference >>>>>>> differently whether it is still enqueued in a ReferenceQueue or >>>>>>> already dequeued (inactive) - responsibility is already on the Java >>>>>>> side. Currently the definition of Reference.next is this: >>>>>>> >>>>>>> /* When active: NULL >>>>>>> * pending: this >>>>>>> * Enqueued: next reference in queue (or this if last) >>>>>>> * Inactive: this >>>>>>> */ >>>>>>> @SuppressWarnings("rawtypes") >>>>>>> Reference next; >>>>>>> >>>>>>> We see that, unless GC inspects all ReferenceQueue instances and >>>>>>> scans their lists too, the state of a Reference that is enqueued as >>>>>>> last in list is indistinguishable from the state of inactive >>>>>>> Reference. So I deduced that this distinction (enqueued/inactive) >>>>>>> can't be established solely on the value of .next field ( == this or >>>>>>> != this)... >>>>>>> >>>>>>> But I should inspect the GC code too to build a better understanding >>>>>>> of that part of the story... >>>>>>> >>>>>>> Anyway. It turns out that there is already enough state in Reference >>>>>>> to destinguish between it being enqueued as last in list and already >>>>>>> dequeued (inactive) - the additional state is Reference.queue that >>>>>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>>>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>>>>> (r.next and r.queue) are assigned and read in correct order. This can >>>>>>> be achieved either by making Reference.next a volatile field or by a >>>>>>> couple of explicit fences: >>>>>>> >>>>>>> >>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>>>>> >>>>>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>>>>> before linking the reference into the queue's head in >>>>>>> ReferenceQueue.enqueue(): >>>>>>> >>>>>>> r.queue = ENQUEUED; >>>>>>> r.next = (head == null) ? r : head; >>>>>>> head = r; >>>>>>> >>>>>>> Both stores are volatile. >>>>>> This sounds a bit better. I don't have a good handle on the pros and >>>>>> cons of a volatile field over explicit fences via Unsafe in this case. >>>>>> Kim might jump in soon. >>>>>> >>>>>> I'd like to suggest an entirely less-clever solution. Since the >>>>>> problem is that forEach() might see inconsistent values for the queue >>>>>> and next fields of a Reference, but we don't want to grab a lock >>>>>> walking the whole queue, we could instead grab the lock as we look at >>>>>> each Reference (and do the "back-up" trick if we were interfered >>>>>> with). Of course this is slower than going lock-free, but it's not any >>>>>> more overhead than the ReferenceHandler thread or FinalizerThreads incur. >>>>>> >>>>>> The only benefit of this solution over the others is that it is less >>>>>> clever, and I'm not sure how much cleverness this problem deserves. >>>>>> Given that, and ranking the solutions as "lock" < (clever) "volatile" >>>>>> < "fence", I'd be happier with the "volatile" or "lock" solution if >>>>>> that is sufficient. >>>>>> >>>>>> - Derek >>>>>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>>>>> forEach iteration method with no concrete logic. >>>>>>>>> >>>>>>>>> It would be possible to encapsulate the entire logic into a special >>>>>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>>>>> static method(s) (printFinalizationQueue)... You could just expose >>>>>>>>> a package-private forEach static method from Finalizer and code the >>>>>>>>> rest in DiagnosticCommands. >>>>>>>> That's good for encapsulation. But I'm concerned that if "forEach" >>>>>>>> got exposed beyond careful use in DiagnosticCommands, and the >>>>>>>> Referents were leaked back into the heap, then we could get >>>>>>>> unexpected object resurrection after finalization. This isn't a bug >>>>>>>> on it's own - any finalizer might resurrect its object if not >>>>>>>> careful, but ordinarily /only/ the finalizer could resurrect the >>>>>>>> object. This could invalidate application invariants? >>>>>>> Well, it all stays in the confines of package-private API - internal >>>>>>> to JDK. Any future additional use should be reviewed carefully. >>>>>>> Comments on the forEach() method should warn about that. >>>>>>> >>>>>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>>>>> /another/ case of diagnostics affecting application behavior. And >>>>>>>> there are pathological scenarios where this gets severe. This is >>>>>>>> unfortunate but not uncommon. There is enough complication here that >>>>>>>> you should be sure that the fix for diagnostics performance doesn't >>>>>>>> introduce subtle bugs to the system in general. A change in this >>>>>>>> area should get a thorough review from both the runtime and GC sides. >>>>>>> Is the webrev.02 proposed above more acceptable in that respect? It >>>>>>> does not introduce any logical changes to existing code. >>>>>>> >>>>>>>> Better yet, the reference handling code in GC and runtime should >>>>>>>> probably be thrown out and re-written, but that's another issue :-) >>>>>>> I may have some proposals in that direction. Stay tuned. >>>>>>> >>>>>>> Regards, Peter >>>>>>> >>>>>>>> - Derek >>>>>>>> >>>>>>>>> Regards, Peter >>>>>>>>> >>>>>>>>> >>>>>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>>>>> Everybody, >>>>>>>>>> >>>>>>>>>> Updated version: >>>>>>>>>> >>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>>>>> >>>>>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>>>>> >>>>>>>>>> -Dmitry >>>>>>>>>> >>>>>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>> >>>>>>>>>>> Lots of good comments here. >>>>>>>>>>> >>>>>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>>>>> general iterator and lambda. >>>>>>>>>>> >>>>>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>>>>> >>>>>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>>>>> >>>>>>>>>>> The sorting suggestion is a nice touch. >>>>>>>>>>> >>>>>>>>>>> - Derek White, GC team >>>>>>>>>>> >>>>>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>>> >>>>>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>>>>> Dmitry, >>>>>>>>>>>>> >>>>>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>>>>> >>>>>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>>>>> running out of memory. >>>>>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>>>>> >>>>>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>>>>> interfere with synchronization? >>>>>>>>>>>> >>>>>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>>>>> >>>>>>>>>>>> private void remove() { >>>>>>>>>>>> synchronized (lock) { >>>>>>>>>>>> if (unfinalized == this) { >>>>>>>>>>>> if (this.next != null) { >>>>>>>>>>>> unfinalized = this.next; >>>>>>>>>>>> } else { >>>>>>>>>>>> unfinalized = this.prev; >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> if (this.next != null) { >>>>>>>>>>>> this.next.prev = this.prev; >>>>>>>>>>>> } >>>>>>>>>>>> if (this.prev != null) { >>>>>>>>>>>> this.prev.next = this.next; >>>>>>>>>>>> } >>>>>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>>>>> traverse the list unsynchronized >>>>>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>>>>> finalized */ >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>>>>> pointer could be used instead: >>>>>>>>>>>> >>>>>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>>>>> return (prev == this); >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>>>>> >>>>>>>>>>>> private void add() { >>>>>>>>>>>> synchronized (lock) { >>>>>>>>>>>> if (unfinalized != null) { >>>>>>>>>>>> this.next = unfinalized; >>>>>>>>>>>> unfinalized.prev = this; >>>>>>>>>>>> } >>>>>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>>>>> // instance fully initialized >>>>>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>>>>> U.storeFence(); >>>>>>>>>>>> unfinalized = this; >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>>>>> >>>>>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>>>>> out? >>>>>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>>>>> two purposes: >>>>>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>>>>> >>>>>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>>>>> finalize() method. >>>>>>>>>>>> >>>>>>>>>>>> Regards, Peter >>>>>>>>>>>> >>>>>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>>>>> >>>>>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>>>>> permission() and limit access: >>>>>>>>>>>>> >>>>>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>>>>> "monitor", NULL}; >>>>>>>>>>>>> return p; >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>>>>> >>>>>>>>>>>>> Thanks, >>>>>>>>>>>>> /Staffan >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> Everyone, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Please review the fix: >>>>>>>>>>>>>> >>>>>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>>>>> >>>>>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>>>>> >>>>>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>>>>> with count >>>>>>>>>>>>>> >>>>>>>>>>>>>> -Dmitry >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>>>>> * I would love to change the world, but they won't give me the sources. > From Roger.Riggs at Oracle.com Tue May 19 21:32:25 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 19 May 2015 17:32:25 -0400 Subject: RFR 9: [TESTBUG] 8078582: java/lang/Runtime/exec/LotsOfOutput.java fails intermittently with Process consumes memory Message-ID: <555BABE9.3070702@Oracle.com> Please review this update to a test to make it resilient to small allocations that may bump the total memory. The test will also collect more data if it fails again. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-xx/ Issue: https://bugs.openjdk.java.net/browse/JDK-8078582 Thanks, Roger From joe.darcy at oracle.com Tue May 19 22:04:40 2015 From: joe.darcy at oracle.com (joe darcy) Date: Tue, 19 May 2015 15:04:40 -0700 Subject: JDK 9 RFR of JDK-8080711: Prepare sun/nio/cs/FindEncoderBugs.java to find intermittent failures Message-ID: <555BB378.9080807@oracle.com> Hello, The test sun/nio/cs/FindEncoderBugs.java has some intermittent failures; I'd like to update it to use the random number library to help track those failures down. Patch below. Thanks, -Joe diff -r b1a68681ccac test/sun/nio/cs/FindEncoderBugs.java --- a/test/sun/nio/cs/FindEncoderBugs.java Tue May 19 13:30:03 2015 -0700 +++ b/test/sun/nio/cs/FindEncoderBugs.java Tue May 19 15:04:20 2015 -0700 @@ -25,15 +25,18 @@ * @test * @bug 6233345 6381699 6381702 6381705 6381706 * @summary Encode many char sequences in many ways + * @library /lib/testlibrary/ + * @build jdk.testlibrary.* * @run main/timeout=1200 FindEncoderBugs * @author Martin Buchholz - * @key randomness + * @key randomness intermittent */ import java.util.*; import java.util.regex.*; import java.nio.*; import java.nio.charset.*; +import jdk.testlibrary.RandomFactory; public class FindEncoderBugs { @@ -456,7 +459,7 @@ } } - private final static Random rnd = new Random(); + private final static Random rnd = RandomFactory.getRandom(); private static char randomChar() { return (char) rnd.nextInt(Character.MAX_VALUE); } From joe.darcy at oracle.com Tue May 19 22:32:24 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Tue, 19 May 2015 15:32:24 -0700 Subject: JDK 9 RFR of JDK-8075284: fix up miscellaneous TM constructions In-Reply-To: <555B9866.6030206@oracle.com> References: <555B91F0.1080604@oracle.com> <555B9866.6030206@oracle.com> Message-ID: <555BB9F8.2030901@oracle.com> Hi Joe, I just wanted to keep this changeset focused on the TM issues, but I don't oppose the other improvements you've suggested being made. Thanks, -Joe On 5/19/2015 1:09 PM, huizhe wang wrote: > Hi Joe, > > Looks good to me. You might also change the followings if you want: > > src/jdk.jdi/share/classes/com/sun/jdi/request/AccessWatchpointRequest.java > ------------------------------------------------------------------------ > @@ -29,12 +29,11 @@ > > /** > * Request for notification when the contents of a field are accessed > * in the target VM. > * This event will be triggered when the specified field is accessed > - * by JavaTM programming > - * language code or by a > + * by Java™ programming language code or by a > * Java Native Interface (JNI) get function*(Get<Type>Field, > * GetStatic<Type>Field).* > > ({@code GetField, GetStaticField}). > > > src/jdk.jdi/share/classes/com/sun/jdi/request/ModificationWatchpointRequest.java > ------------------------------------------------------------------------ > @@ -28,11 +28,11 @@ > import com.sun.jdi.*; > > /** > * Request for notification when a field is set. > * This event will be triggered when a value is assigned to the specified > - * field with a JavaTM programming > + * field with a Java™ programming > * language statement (assignment, increment, etc) or by a > * Java Native Interface (JNI) set function*(Set<Type>Field, > * SetStatic<Type>Field).* > > ({@code SetField, SetStaticField}). > > > -Joe > > On 5/19/2015 12:41 PM, joe darcy wrote: >> Hello, >> >> Please review these changes for >> >> JDK-8075284: fix up miscellaneous TM constructions >> http://cr.openjdk.java.net/~darcy/8075284.0/ >> >> which replace convoluted HTML markup for expressing a trademark sign >> with the HTML ™ --- build and docs build pass with the changes >> >> Thanks, >> >> -Joe >> > From ivan.gerasimov at oracle.com Tue May 19 23:23:57 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 20 May 2015 02:23:57 +0300 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555B99DD.7050009@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> <5555CC06.4020507@gmail.com> <555A5E81.8050804@Oracle.com> <555AF5A2.5060205@gmail.com> <555B5B3E.60104@Oracle.com> <555B99DD.7050009@Oracle.com> Message-ID: <555BC60D.6000201@oracle.com> On 19.05.2015 23:15, Roger Riggs wrote: > The webrev, javadoc, and specdiffs have been updated to address recent > recommendations: > > Please review and comment: > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-ph/ (May 19) > src/java.base/windows/classes/java/lang/ProcessImpl.java : 37 import java.lang.Override; must be some over-obliging IDE? :-) Sincerely yours, Ivan > javadoc: > http://cr.openjdk.java.net/~rriggs/ph-apidraft/ (May 19) > > Diffs of the spec/javadoc from previous draft: > http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-19/overview-summary.html > > > Thanks, Roger > > From mandy.chung at oracle.com Tue May 19 23:44:24 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 19 May 2015 16:44:24 -0700 Subject: RFR: 8080608: Missing archive name from jdeps -v -e output if no dependency on other JAR In-Reply-To: <555B6CC0.5070000@oracle.com> References: <555B6CC0.5070000@oracle.com> Message-ID: <555BCAD8.1080500@oracle.com> On 05/19/2015 10:02 AM, Daniel Fuchs wrote: > Hi, > > Please find below a patch for jdeps: > > http://cr.openjdk.java.net/~dfuchs/webrev_8080608/webrev.00/ > https://bugs.openjdk.java.net/browse/JDK-8080608 > > : > > The fix will make sure that jdeps prints instead: > > indirect2.jar -> dist/unsafe.jar > use.indirect2.UseUnsafeIndirectly2 -> use.unsafe.UseUnsafeClass > unsafe.jar > unsafe.jar -> dist/unsafe.jar > use.unsafe.UseClassWithUnsafe -> use.unsafe.UseUnsafeClass unsafe.jar A dependency from unsafe.jar to itself is redundant and thus was excluded from the returned value of the requires method. Maybe better just to output without any dependence like this: unsafe.jar use.unsafe.UseClassWithUnsafe -> use.unsafe.UseUnsafeClass unsafe.jar Analyzer.java 147 if (result.requires.isEmpty() && type == Type.VERBOSE && hasDependences(source)) { Is type == Type.VERBOSE necessary? If hasDependences(source) returns true, "unsafe.jar" is missing for non-verbose mode I assume. This long line should be broken into multiple lines. Maybe good to initialize Stream to handle the empty and non-empty case to avoid duplicate code line 148-149: final ArchiveDeps result = results.get(source); Stream reqs = result.requires().stream(); if (result.requires().isEmpty()&& hasDependences(source)) { reqs = Stream.of(source); } reqs.sorted(..... I haven't reviewed the tests. They are named as closure. Are these tests for the new jdeps enhancement that you are thinking? Thanks Mandy From martinrb at google.com Tue May 19 23:55:36 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 19 May 2015 16:55:36 -0700 Subject: RFR 9: [TESTBUG] 8078582: java/lang/Runtime/exec/LotsOfOutput.java fails intermittently with Process consumes memory In-Reply-To: <555BABE9.3070702@Oracle.com> References: <555BABE9.3070702@Oracle.com> Message-ID: LotsOfOutput is a lousy test. totalMemory can grow with any quantum. Better would be watching usedMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); as suggested at http://stackoverflow.com/questions/3571203/what-is-the-exact-meaning-of-runtime-getruntime-totalmemory-and-freememory On Tue, May 19, 2015 at 2:32 PM, Roger Riggs wrote: > Please review this update to a test to make it resilient to small > allocations > that may bump the total memory. The test will also collect more data if > it fails again. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-xx/ > > Issue: > https://bugs.openjdk.java.net/browse/JDK-8078582 > > Thanks, Roger > > > > From Roger.Riggs at Oracle.com Wed May 20 01:28:15 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 19 May 2015 21:28:15 -0400 Subject: JDK 9 RFR of JDK-8080711: Prepare sun/nio/cs/FindEncoderBugs.java to find intermittent failures In-Reply-To: <555BB378.9080807@oracle.com> References: <555BB378.9080807@oracle.com> Message-ID: <555BE32F.3070100@Oracle.com> Hi Joe, Looks fine. Roger On 5/19/15 6:04 PM, joe darcy wrote: > Hello, > > The test sun/nio/cs/FindEncoderBugs.java has some intermittent > failures; I'd like to update it to use the random number library to > help track those failures down. > > Patch below. > > Thanks, > > -Joe > > diff -r b1a68681ccac test/sun/nio/cs/FindEncoderBugs.java > --- a/test/sun/nio/cs/FindEncoderBugs.java Tue May 19 13:30:03 2015 > -0700 > +++ b/test/sun/nio/cs/FindEncoderBugs.java Tue May 19 15:04:20 2015 > -0700 > @@ -25,15 +25,18 @@ > * @test > * @bug 6233345 6381699 6381702 6381705 6381706 > * @summary Encode many char sequences in many ways > + * @library /lib/testlibrary/ > + * @build jdk.testlibrary.* > * @run main/timeout=1200 FindEncoderBugs > * @author Martin Buchholz > - * @key randomness > + * @key randomness intermittent > */ > > import java.util.*; > import java.util.regex.*; > import java.nio.*; > import java.nio.charset.*; > +import jdk.testlibrary.RandomFactory; > > public class FindEncoderBugs { > > @@ -456,7 +459,7 @@ > } > } > > - private final static Random rnd = new Random(); > + private final static Random rnd = RandomFactory.getRandom(); > private static char randomChar() { > return (char) rnd.nextInt(Character.MAX_VALUE); > } > From Roger.Riggs at Oracle.com Wed May 20 01:50:07 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 19 May 2015 21:50:07 -0400 Subject: RFR 9: [TESTBUG] 8078582: java/lang/Runtime/exec/LotsOfOutput.java fails intermittently with Process consumes memory In-Reply-To: References: <555BABE9.3070702@Oracle.com> Message-ID: <555BE84F.1090606@Oracle.com> Hi, Ok, how about this: Webrev: http://cr.openjdk.java.net/~rriggs/webrev-lots-8078582/ Thanks, Roger On 5/19/15 7:55 PM, Martin Buchholz wrote: > LotsOfOutput is a lousy test. totalMemory can grow with any quantum. > Better would be watching > usedMemory = Runtime.getRuntime().totalMemory() - > Runtime.getRuntime().freeMemory(); > as suggested at > http://stackoverflow.com/questions/3571203/what-is-the-exact-meaning-of-runtime-getruntime-totalmemory-and-freememory > > On Tue, May 19, 2015 at 2:32 PM, Roger Riggs > wrote: > > Please review this update to a test to make it resilient to small > allocations > that may bump the total memory. The test will also collect more > data if it fails again. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-xx/ > > > Issue: > https://bugs.openjdk.java.net/browse/JDK-8078582 > > Thanks, Roger > > > > From martinrb at google.com Wed May 20 02:14:59 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 19 May 2015 19:14:59 -0700 Subject: RFR 9: [TESTBUG] 8078582: java/lang/Runtime/exec/LotsOfOutput.java fails intermittently with Process consumes memory In-Reply-To: <555BE84F.1090606@Oracle.com> References: <555BABE9.3070702@Oracle.com> <555BE84F.1090606@Oracle.com> Message-ID: Thanks, Roger. This is a much better test now (but still not actually a good one...) Probably want to be optimistic and delete + * @key intermittent On Tue, May 19, 2015 at 6:50 PM, Roger Riggs wrote: > Hi, > > Ok, how about this: > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-lots-8078582/ > > Thanks, Roger > > > > On 5/19/15 7:55 PM, Martin Buchholz wrote: > > LotsOfOutput is a lousy test. totalMemory can grow with any quantum. > Better would be watching > usedMemory = Runtime.getRuntime().totalMemory() - > Runtime.getRuntime().freeMemory(); > as suggested at > > http://stackoverflow.com/questions/3571203/what-is-the-exact-meaning-of-runtime-getruntime-totalmemory-and-freememory > > On Tue, May 19, 2015 at 2:32 PM, Roger Riggs > wrote: > >> Please review this update to a test to make it resilient to small >> allocations >> that may bump the total memory. The test will also collect more data if >> it fails again. >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-xx/ >> >> Issue: >> https://bugs.openjdk.java.net/browse/JDK-8078582 >> >> Thanks, Roger >> >> >> >> > > From joe.darcy at oracle.com Wed May 20 02:21:32 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Tue, 19 May 2015 19:21:32 -0700 Subject: RFR 9: [TESTBUG] 8078582: java/lang/Runtime/exec/LotsOfOutput.java fails intermittently with Process consumes memory In-Reply-To: References: <555BABE9.3070702@Oracle.com> <555BE84F.1090606@Oracle.com> Message-ID: <555BEFAC.3020107@oracle.com> On 5/19/2015 7:14 PM, Martin Buchholz wrote: > Thanks, Roger. This is a much better test now (but still not actually a > good one...) > > Probably want to be optimistic and delete > > + * @key intermittent That is an interesting (and as yet unresolved) policy question: how should removal of intermittent keywords be managed? Although it requires another bug in the future, be default I'd prefer if the intermittent tag stayed on and was only removed after some parole period where it was observed to not fail. The length / extent of this period should be inversely proportional to the probability of failure. Concretely, if a test fails 1 out of 100 test runs it doesn't need to be run a long as a test that fails 1 out of 1,000 test runs. -Joe > > > > On Tue, May 19, 2015 at 6:50 PM, Roger Riggs wrote: > >> Hi, >> >> Ok, how about this: >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-lots-8078582/ >> >> Thanks, Roger >> >> >> >> On 5/19/15 7:55 PM, Martin Buchholz wrote: >> >> LotsOfOutput is a lousy test. totalMemory can grow with any quantum. >> Better would be watching >> usedMemory = Runtime.getRuntime().totalMemory() - >> Runtime.getRuntime().freeMemory(); >> as suggested at >> >> http://stackoverflow.com/questions/3571203/what-is-the-exact-meaning-of-runtime-getruntime-totalmemory-and-freememory >> >> On Tue, May 19, 2015 at 2:32 PM, Roger Riggs >> wrote: >> >>> Please review this update to a test to make it resilient to small >>> allocations >>> that may bump the total memory. The test will also collect more data if >>> it fails again. >>> >>> Webrev: >>> http://cr.openjdk.java.net/~rriggs/webrev-xx/ >>> >>> Issue: >>> https://bugs.openjdk.java.net/browse/JDK-8078582 >>> >>> Thanks, Roger >>> >>> >>> >>> >> From Roger.Riggs at Oracle.com Wed May 20 02:25:36 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 19 May 2015 22:25:36 -0400 Subject: RFR 9: [TESTBUG] 8078582: java/lang/Runtime/exec/LotsOfOutput.java fails intermittently with Process consumes memory In-Reply-To: <555BEFAC.3020107@oracle.com> References: <555BABE9.3070702@Oracle.com> <555BE84F.1090606@Oracle.com> <555BEFAC.3020107@oracle.com> Message-ID: <555BF0A0.2060203@Oracle.com> Hi Joe, Thanks, I was pondering on what to do. The intermittent keyword was not already on this test though it has been failing intermittently. I agree that it is useful for the keyword to remain as a reminder that it was intermittent until there is some evidence about long term stability. Roger On 5/19/15 10:21 PM, Joseph D. Darcy wrote: > On 5/19/2015 7:14 PM, Martin Buchholz wrote: >> Thanks, Roger. This is a much better test now (but still not actually a >> good one...) >> >> Probably want to be optimistic and delete >> >> + * @key intermittent > > That is an interesting (and as yet unresolved) policy question: how > should removal of intermittent keywords be managed? > > Although it requires another bug in the future, be default I'd prefer > if the intermittent tag stayed on and was only removed after some > parole period where it was observed to not fail. The length / extent > of this period should be inversely proportional to the probability of > failure. > > Concretely, if a test fails 1 out of 100 test runs it doesn't need to > be run a long as a test that fails 1 out of 1,000 test runs. > > -Joe > >> >> >> >> On Tue, May 19, 2015 at 6:50 PM, Roger Riggs >> wrote: >> >>> Hi, >>> >>> Ok, how about this: >>> >>> Webrev: >>> http://cr.openjdk.java.net/~rriggs/webrev-lots-8078582/ >>> >>> Thanks, Roger >>> >>> >>> >>> On 5/19/15 7:55 PM, Martin Buchholz wrote: >>> >>> LotsOfOutput is a lousy test. totalMemory can grow with any quantum. >>> Better would be watching >>> usedMemory = Runtime.getRuntime().totalMemory() - >>> Runtime.getRuntime().freeMemory(); >>> as suggested at >>> >>> http://stackoverflow.com/questions/3571203/what-is-the-exact-meaning-of-runtime-getruntime-totalmemory-and-freememory >>> >>> >>> On Tue, May 19, 2015 at 2:32 PM, Roger Riggs >>> wrote: >>> >>>> Please review this update to a test to make it resilient to small >>>> allocations >>>> that may bump the total memory. The test will also collect more >>>> data if >>>> it fails again. >>>> >>>> Webrev: >>>> http://cr.openjdk.java.net/~rriggs/webrev-xx/ >>>> >>>> Issue: >>>> https://bugs.openjdk.java.net/browse/JDK-8078582 >>>> >>>> Thanks, Roger >>>> >>>> >>>> >>>> >>> > From joe.darcy at oracle.com Wed May 20 02:28:19 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Tue, 19 May 2015 19:28:19 -0700 Subject: RFR 9: [TESTBUG] 8078582: java/lang/Runtime/exec/LotsOfOutput.java fails intermittently with Process consumes memory In-Reply-To: <555BF0A0.2060203@Oracle.com> References: <555BABE9.3070702@Oracle.com> <555BE84F.1090606@Oracle.com> <555BEFAC.3020107@oracle.com> <555BF0A0.2060203@Oracle.com> Message-ID: <555BF143.90608@oracle.com> Hi Roger, On 5/19/2015 7:25 PM, Roger Riggs wrote: > Hi Joe, > > Thanks, I was pondering on what to do. The intermittent keyword was > not already on this test > though it has been failing intermittently. > > I agree that it is useful for the keyword to remain as a reminder that > it was intermittent > until there is some evidence about long term stability. An advantage of that policy is that it enables targeted test runs of the tests known or suspected of intermittently failing (jtreg -k:intermittent ...). Such additional scrutiny should be able to be continued after an update to the test has been made so that there is an opportunity to verify that the fix holds up and reduces the probability of failure. Thanks, -Joe > > Roger > > > On 5/19/15 10:21 PM, Joseph D. Darcy wrote: >> On 5/19/2015 7:14 PM, Martin Buchholz wrote: >>> Thanks, Roger. This is a much better test now (but still not >>> actually a >>> good one...) >>> >>> Probably want to be optimistic and delete >>> >>> + * @key intermittent >> >> That is an interesting (and as yet unresolved) policy question: how >> should removal of intermittent keywords be managed? >> >> Although it requires another bug in the future, be default I'd prefer >> if the intermittent tag stayed on and was only removed after some >> parole period where it was observed to not fail. The length / extent >> of this period should be inversely proportional to the probability of >> failure. >> >> Concretely, if a test fails 1 out of 100 test runs it doesn't need to >> be run a long as a test that fails 1 out of 1,000 test runs. >> >> -Joe >> >>> >>> >>> >>> On Tue, May 19, 2015 at 6:50 PM, Roger Riggs >>> wrote: >>> >>>> Hi, >>>> >>>> Ok, how about this: >>>> >>>> Webrev: >>>> http://cr.openjdk.java.net/~rriggs/webrev-lots-8078582/ >>>> >>>> Thanks, Roger >>>> >>>> >>>> >>>> On 5/19/15 7:55 PM, Martin Buchholz wrote: >>>> >>>> LotsOfOutput is a lousy test. totalMemory can grow with any quantum. >>>> Better would be watching >>>> usedMemory = Runtime.getRuntime().totalMemory() - >>>> Runtime.getRuntime().freeMemory(); >>>> as suggested at >>>> >>>> http://stackoverflow.com/questions/3571203/what-is-the-exact-meaning-of-runtime-getruntime-totalmemory-and-freememory >>>> >>>> >>>> On Tue, May 19, 2015 at 2:32 PM, Roger Riggs >>>> wrote: >>>> >>>>> Please review this update to a test to make it resilient to small >>>>> allocations >>>>> that may bump the total memory. The test will also collect more >>>>> data if >>>>> it fails again. >>>>> >>>>> Webrev: >>>>> http://cr.openjdk.java.net/~rriggs/webrev-xx/ >>>>> >>>>> Issue: >>>>> https://bugs.openjdk.java.net/browse/JDK-8078582 >>>>> >>>>> Thanks, Roger >>>>> >>>>> >>>>> >>>>> >>>> >> > From mandy.chung at oracle.com Wed May 20 02:54:11 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 19 May 2015 19:54:11 -0700 Subject: RFR(M, v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5559D85B.2050500@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> Message-ID: <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> > On May 18, 2015, at 5:17 AM, Dmitry Samersoff wrote: > > Please review updated version of the fix: > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ > > Most important part of the fix provided by Peter Levart, so all > credentials belongs to him. My apology for being late to the review. The subject line doesn?t catch my attention early enough :) I have to do further detail review tomorrow or so to follow the discussion and closely inspect the reference implementation. Just to give you a quick comment. I?m okay to add ReferenceQueue.forEach method at the first glance. However I have trouble for Finalizer.printFinalizationQueue method that doesn?t belong there. What are the other alternatives you have explored? Mandy From dmitry.samersoff at oracle.com Wed May 20 06:51:23 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Wed, 20 May 2015 09:51:23 +0300 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> Message-ID: <555C2EEB.1050505@oracle.com> Mandy, > However I have trouble for > Finalizer.printFinalizationQueue method that doesn?t belong there. > What are the other alternatives you have explored? Other alternatives could be to do all hashing/sorting/printing on native layer i.e. implement printFinalizationQueue inside VM. Both options has pros and cons - Java based solution requires less JNI calls and better readable but takes more memory. It might be better to return an array of Map.Entry objects to VM rather than one huge string. -Dmitry On 2015-05-20 05:54, Mandy Chung wrote: > >> On May 18, 2015, at 5:17 AM, Dmitry Samersoff >> > wrote: >> >> Please review updated version of the fix: >> >> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ >> >> Most important part of the fix provided by Peter Levart, so all >> credentials belongs to him. > > > My apology for being late to the review. The subject line doesn?t catch > my attention early enough :) > > I have to do further detail review tomorrow or so to follow the > discussion and closely inspect the reference implementation. Just to > give you a quick comment. I?m okay to add ReferenceQueue.forEach method > at the first glance. However I have trouble for > Finalizer.printFinalizationQueue method that doesn?t belong there. What > are the other alternatives you have explored? > > Mandy > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From david.holmes at oracle.com Wed May 20 07:07:52 2015 From: david.holmes at oracle.com (David Holmes) Date: Wed, 20 May 2015 17:07:52 +1000 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork In-Reply-To: References: Message-ID: <555C32C8.90301@oracle.com> On 20/05/2015 3:55 AM, Paul Sandoz wrote: > Hi, > > https://bugs.openjdk.java.net/browse/JDK-8080623 > > diff -r ea3ca5cfc3c6 src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java > --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 20:04:29 2015 +0300 > +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 19:54:00 2015 +0200 > @@ -1328,13 +1328,9 @@ > /** > * Number of times to spin-wait before blocking. The spins (in > * awaitRunStateLock and awaitWork) currently use randomized > - * spins. If/when MWAIT-like intrinsics becomes available, they > - * may allow quieter spinning. The value of SPINS must be a power > - * of two, at least 4. The current value causes spinning for a > - * small fraction of typical context-switch times, well worthwhile > - * given the typical likelihoods that blocking is not necessary. > + * spins. Currently set to zero to reduce CPU usage. I'd keep the commentary even if disabling spinning at this time. David ----- > */ > - private static final int SPINS = 1 << 11; > + private static final int SPINS = 0; > > /** > * Increment for seed generators. See class ThreadLocal for > > This is a quick fix from Doug to reduce the CPU usage in F/J computations that was introduced with the fix for JDK-805624 to reduce thread construction. Many thanks to Staffan Friberg for doing the performance work and analysis. > > The F/J pool makes a worker thread spin for a bit while waiting for more work to become available rather than immediately blocking. This results in higher CPU usage and can cause performance regressions since there is less CPU resources available to other threads or applications. > > The interim fix is to turn off spinning. This has the effect of making questionable cases worse (e.g. parallel streams with an inappropriate small number elements). > > It will be back ported to 8u60 and it is planned that a better solution will be introduced in 9 (and time permitting it may be possible to backport that). > > Paul. > > > From roland.westrelin at oracle.com Wed May 20 07:14:25 2015 From: roland.westrelin at oracle.com (Roland Westrelin) Date: Wed, 20 May 2015 09:14:25 +0200 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <5559E3A5.8030108@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> <55533CAE.3050201@oracle.com> <55549297.5020002@oracle.com> <5555E343.5050600@oracle.com> <5559E3A5.8030108@oracle.com> Message-ID: > What do you think about the following version: > http://cr.openjdk.java.net/~vlivanov/8079205/webrev.04 Still looks good to me. Roland. From paul.sandoz at oracle.com Wed May 20 07:20:43 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 20 May 2015 09:20:43 +0200 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <9759D303-DCCA-45B9-ADC3-92F4807AB066@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> <555B6140.2010700@oracle.com> <9759D303-DCCA-45B9-ADC3-92F4807AB066@oracle.com> Message-ID: <4645B33F-3ACC-48E3-B937-6AF18A7C3F59@oracle.com> On May 19, 2015, at 6:19 PM, Chris Hegarty wrote: > > On 19 May 2015, at 17:13, Daniel Fuchs wrote: > >> On 19/05/15 12:07, Paul Sandoz wrote: >>>> Should anything be said also about default remove() method inherited from Iterator interface? Are custom asIterator() implementations allowed to return an Iterator that implements remove() in a way that actually removes elements? >>>>> >>> Since this method transfers control it seems a little mean to place such a restriction on the returned Iterator. Although, there is no clear means of stating to the caller whether such an iterator supports removal or not, but that seems to be generally the case for any Iterator returning method. > > + * @implSpec > + * The returned Iterator's {@link Iterator#hasNext hasNext} method calls and returns > + * the value from this Enumeration's {@code hasMoreElements} method; its > + * {@link Iterator#next next} method calls and returns the value from this Enumeration's > + * {@code nextElement} method; and its {@link Iterator#remove remove} method throws > + * {@code UnsupportedOperationException}. > + * > > Why not turn the proposed implSpec into an implNote, and leave it up to other API?s returning Enumerations to specify their behaviour of asIterator, if they override the default. > The @implSpec section is specifying the behaviour of the default implementation. Usually we prefix with "The default implementation ...". Paul. From peter.levart at gmail.com Wed May 20 08:22:28 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 20 May 2015 10:22:28 +0200 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <555C2EEB.1050505@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> Message-ID: <555C4444.6050008@gmail.com> On 05/20/2015 08:51 AM, Dmitry Samersoff wrote: > Mandy, > >> However I have trouble for >> Finalizer.printFinalizationQueue method that doesn?t belong there. >> What are the other alternatives you have explored? > Other alternatives could be to do all hashing/sorting/printing on native > layer i.e. implement printFinalizationQueue inside VM. > > Both options has pros and cons - Java based solution requires less JNI > calls and better readable but takes more memory. > > It might be better to return an array of Map.Entry > objects to VM rather than one huge string. > > -Dmitry Hi Dmitry, What about creating a special package-private java.lang.ref.DiagnosticCommands class which is then used as the home of static printFinalizationQueue method (and possible future diagnostic commands methods in the package). You could then expose a static package-private method from Finalizer: static void forEachEnqueued(Consumer> action) { queue.forEach(action); } ...and use it to implement the printFinalizationQueue. Regards, Peter > > > > On 2015-05-20 05:54, Mandy Chung wrote: >>> On May 18, 2015, at 5:17 AM, Dmitry Samersoff >>> > wrote: >>> >>> Please review updated version of the fix: >>> >>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ >>> >>> Most important part of the fix provided by Peter Levart, so all >>> credentials belongs to him. >> >> My apology for being late to the review. The subject line doesn?t catch >> my attention early enough :) >> >> I have to do further detail review tomorrow or so to follow the >> discussion and closely inspect the reference implementation. Just to >> give you a quick comment. I?m okay to add ReferenceQueue.forEach method >> at the first glance. However I have trouble for >> Finalizer.printFinalizationQueue method that doesn?t belong there. What >> are the other alternatives you have explored? >> >> Mandy >> > From peter.levart at gmail.com Wed May 20 08:39:04 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 20 May 2015 10:39:04 +0200 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555B99DD.7050009@Oracle.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> <5555CC06.4020507@gmail.com> <555A5E81.8050804@Oracle.com> <555AF5A2.5060205@gmail.com> <555B5B3E.60104@Oracle.com> <555B99DD.7050009@Oracle.com> Message-ID: <555C4828.5070803@gmail.com> Hi Roger, I looked at Martin's idea and I think that we don't need the AsyncExecutor at all (it already sounds like I hate it ;-). Using ManagedBlocker, a ForkJoinPoll can compensate and grow it's pool as needed when Process.waitFor() blocks. So we could leverage this feature and simplify things even further: http://cr.openjdk.java.net/~plevart/jdk9-sandbox/JDK-8046092-branch/webrev.03/ Passing a commonPool() to xxxAsync() methods is unneeded as the default is exactly the same. If CompletableFuture ever gets a feature to specify a default Executor for all it's descendants, then we can revisit this if needed. What do you think? Regards, Peter On 05/19/2015 10:15 PM, Roger Riggs wrote: > The webrev, javadoc, and specdiffs have been updated to address recent > recommendations: > > Please review and comment: > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-ph/ (May 19) > > javadoc: > http://cr.openjdk.java.net/~rriggs/ph-apidraft/ (May 19) > > Diffs of the spec/javadoc from previous draft: > http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-19/overview-summary.html > > > Thanks, Roger From dmitry.samersoff at oracle.com Wed May 20 08:42:04 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Wed, 20 May 2015 11:42:04 +0300 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <555C4444.6050008@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <555C4444.6050008@gmail.com> Message-ID: <555C48DC.7000005@oracle.com> Peter, > What about creating a special package-private > java.lang.ref.DiagnosticCommands class I'm not quite happy with current printFinalizationQueue method - love to have a way to print directly to DCMD pipe from Java rather than return a huge string to VM. But lang.ref.Finalizer is cached by VM (see SystemDictionary::Finalizer_klass()) and is known as special i.e. check-when-modify-hotspot class. We don't plan to expand this DCMD so I'm reluctant to create a separate class for one simple static method - it adds extra cost of compiling/loading/care. -Dmitry On 2015-05-20 11:22, Peter Levart wrote: > > > On 05/20/2015 08:51 AM, Dmitry Samersoff wrote: >> Mandy, >> >>> However I have trouble for >>> Finalizer.printFinalizationQueue method that doesn?t belong there. >>> What are the other alternatives you have explored? >> Other alternatives could be to do all hashing/sorting/printing on native >> layer i.e. implement printFinalizationQueue inside VM. >> >> Both options has pros and cons - Java based solution requires less JNI >> calls and better readable but takes more memory. >> >> It might be better to return an array of Map.Entry >> objects to VM rather than one huge string. >> >> -Dmitry > > Hi Dmitry, > > What about creating a special package-private > java.lang.ref.DiagnosticCommands class which is then used as the home of > static printFinalizationQueue method (and possible future diagnostic > commands methods in the package). You could then expose a static > package-private method from Finalizer: > > static void forEachEnqueued(Consumer> action) { > queue.forEach(action); > } > > ...and use it to implement the printFinalizationQueue. > > Regards, Peter > > >> >> >> >> On 2015-05-20 05:54, Mandy Chung wrote: >>>> On May 18, 2015, at 5:17 AM, Dmitry Samersoff >>>> > >>>> wrote: >>>> >>>> Please review updated version of the fix: >>>> >>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ >>>> >>>> Most important part of the fix provided by Peter Levart, so all >>>> credentials belongs to him. >>> >>> My apology for being late to the review. The subject line doesn?t catch >>> my attention early enough :) >>> >>> I have to do further detail review tomorrow or so to follow the >>> discussion and closely inspect the reference implementation. Just to >>> give you a quick comment. I?m okay to add ReferenceQueue.forEach method >>> at the first glance. However I have trouble for >>> Finalizer.printFinalizationQueue method that doesn?t belong there. What >>> are the other alternatives you have explored? >>> >>> Mandy >>> >> > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From chris.hegarty at oracle.com Wed May 20 08:47:30 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 20 May 2015 09:47:30 +0100 Subject: RFR(s): 8072726: add adapter to convert Enumeration to Iterator In-Reply-To: <4645B33F-3ACC-48E3-B937-6AF18A7C3F59@oracle.com> References: <5556912D.2020000@oracle.com> <345CC8A1-6DCA-4823-A0D1-8E49C5A43554@oracle.com> <555AFF9C.3080309@gmail.com> <50555693-16A0-4731-B53F-89A8045B2A32@oracle.com> <555B6140.2010700@oracle.com> <9759D303-DCCA-45B9-ADC3-92F4807AB066@oracle.com> <4645B33F-3ACC-48E3-B937-6AF18A7C3F59@oracle.com> Message-ID: <555C4A22.9010608@oracle.com> On 20/05/15 08:20, Paul Sandoz wrote: > > On May 19, 2015, at 6:19 PM, Chris Hegarty wrote: > >> >> On 19 May 2015, at 17:13, Daniel Fuchs wrote: >> >>> On 19/05/15 12:07, Paul Sandoz wrote: >>>>> Should anything be said also about default remove() method inherited from Iterator interface? Are custom asIterator() implementations allowed to return an Iterator that implements remove() in a way that actually removes elements? >>>>>> >>>> Since this method transfers control it seems a little mean to place such a restriction on the returned Iterator. Although, there is no clear means of stating to the caller whether such an iterator supports removal or not, but that seems to be generally the case for any Iterator returning method. >> >> + * @implSpec >> + * The returned Iterator's {@link Iterator#hasNext hasNext} method calls and returns >> + * the value from this Enumeration's {@code hasMoreElements} method; its >> + * {@link Iterator#next next} method calls and returns the value from this Enumeration's >> + * {@code nextElement} method; and its {@link Iterator#remove remove} method throws >> + * {@code UnsupportedOperationException}. >> + * >> >> Why not turn the proposed implSpec into an implNote, and leave it up to other API?s returning Enumerations to specify their behaviour of asIterator, if they override the default. >> > > The @implSpec section is specifying the behaviour of the default implementation. Usually we prefix with "The default implementation ...". D'oh, I mixed up @implSpec and @implNote (again). What Stuart has already cover this. -Chris. > Paul. > From paul.sandoz at oracle.com Wed May 20 09:04:15 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 20 May 2015 11:04:15 +0200 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: <555B91B9.80204@oracle.com> References: <555B91B9.80204@oracle.com> Message-ID: <6E1D96B2-8A0C-4CDF-91D1-1E8DE0916A95@oracle.com> On May 19, 2015, at 9:40 PM, Ivan Gerasimov wrote: > Hi everyone! > > What about this variant: > http://cr.openjdk.java.net/~igerasim/8080535/02/webrev/ > 45 int mapSize = map.size(); Not used. 49 int INITIAL_CAPACITY = 680; //(int)(510 / 0.75f + 1.0f); Change to lower case. Just had an idea... I believe static intializers are executed in textual order. So you could have a static code block after all static UnicodeBlock instances have been defined that asserts the size == 510 (or is <= 1024 * 0.75). In that case i would argue a static final representing the expected size is justified. Then your test can derive the initial capacity from mapSize. Paul. > No named constant. > A comment in the code about initial capacity. > In the test, we use the same constant to check if it were sufficient to hold the final number of entries. > > If someone evil shrinks the initial capacity in the code, the test will not be able to detect it, though it seems unlikely. > > // Please ignore the change to test/TEST.groups in the webrev; it is a leftover from a fix for JDK-8080330 > > Sincerely yours, > Ivan > From paul.sandoz at oracle.com Wed May 20 09:28:45 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 20 May 2015 11:28:45 +0200 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork In-Reply-To: <555C32C8.90301@oracle.com> References: <555C32C8.90301@oracle.com> Message-ID: <168C61AB-074F-4E36-9297-75E26B10F937@oracle.com> On May 20, 2015, at 9:07 AM, David Holmes wrote: > On 20/05/2015 3:55 AM, Paul Sandoz wrote: >> Hi, >> >> https://bugs.openjdk.java.net/browse/JDK-8080623 >> >> diff -r ea3ca5cfc3c6 src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java >> --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 20:04:29 2015 +0300 >> +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 19:54:00 2015 +0200 >> @@ -1328,13 +1328,9 @@ >> /** >> * Number of times to spin-wait before blocking. The spins (in >> * awaitRunStateLock and awaitWork) currently use randomized >> - * spins. If/when MWAIT-like intrinsics becomes available, they >> - * may allow quieter spinning. The value of SPINS must be a power >> - * of two, at least 4. The current value causes spinning for a >> - * small fraction of typical context-switch times, well worthwhile >> - * given the typical likelihoods that blocking is not necessary. >> + * spins. Currently set to zero to reduce CPU usage. > > I'd keep the commentary even if disabling spinning at this time. > Some of removed commentary makes less sense given the motivation to set the value to zero. How about the following tweak: /** * Number of times to spin-wait before blocking. The spins (in * awaitRunStateLock and awaitWork) currently use randomized - * spins. If/when MWAIT-like intrinsics becomes available, they - * may allow quieter spinning. The value of SPINS must be a power - * of two, at least 4. The current value causes spinning for a - * small fraction of typical context-switch times, well worthwhile - * given the typical likelihoods that blocking is not necessary. + * spins. Currently set to zero to reduce CPU usage. + * + * If greater than zero the value of SPINS must be a power + * of two, at least 4. A value of 2048 causes spinning for a + * small fraction of typical context-switch times. + * + * If/when MWAIT-like intrinsics becomes available, they + * may allow quieter spinning. */ - private static final int SPINS = 1 << 11; + private static final int SPINS = 0; Paul. From david.holmes at oracle.com Wed May 20 09:46:32 2015 From: david.holmes at oracle.com (David Holmes) Date: Wed, 20 May 2015 19:46:32 +1000 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork In-Reply-To: <168C61AB-074F-4E36-9297-75E26B10F937@oracle.com> References: <555C32C8.90301@oracle.com> <168C61AB-074F-4E36-9297-75E26B10F937@oracle.com> Message-ID: <555C57F8.3020307@oracle.com> On 20/05/2015 7:28 PM, Paul Sandoz wrote: > > On May 20, 2015, at 9:07 AM, David Holmes wrote: > >> On 20/05/2015 3:55 AM, Paul Sandoz wrote: >>> Hi, >>> >>> https://bugs.openjdk.java.net/browse/JDK-8080623 >>> >>> diff -r ea3ca5cfc3c6 src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java >>> --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 20:04:29 2015 +0300 >>> +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 19:54:00 2015 +0200 >>> @@ -1328,13 +1328,9 @@ >>> /** >>> * Number of times to spin-wait before blocking. The spins (in >>> * awaitRunStateLock and awaitWork) currently use randomized >>> - * spins. If/when MWAIT-like intrinsics becomes available, they >>> - * may allow quieter spinning. The value of SPINS must be a power >>> - * of two, at least 4. The current value causes spinning for a >>> - * small fraction of typical context-switch times, well worthwhile >>> - * given the typical likelihoods that blocking is not necessary. >>> + * spins. Currently set to zero to reduce CPU usage. >> >> I'd keep the commentary even if disabling spinning at this time. >> > > Some of removed commentary makes less sense given the motivation to set the value to zero. How about the following tweak: > > /** > * Number of times to spin-wait before blocking. The spins (in > * awaitRunStateLock and awaitWork) currently use randomized > - * spins. If/when MWAIT-like intrinsics becomes available, they > - * may allow quieter spinning. The value of SPINS must be a power > - * of two, at least 4. The current value causes spinning for a > - * small fraction of typical context-switch times, well worthwhile > - * given the typical likelihoods that blocking is not necessary. > + * spins. Currently set to zero to reduce CPU usage. I've lost the context for what "spin" is getting randomized ?? > + * > + * If greater than zero the value of SPINS must be a power > + * of two, at least 4. A value of 2048 causes spinning for a > + * small fraction of typical context-switch times. > + * > + * If/when MWAIT-like intrinsics becomes available, they > + * may allow quieter spinning. Yep that's fine - thanks. David > */ > - private static final int SPINS = 1 << 11; > + private static final int SPINS = 0; > > Paul. > From daniel.fuchs at oracle.com Wed May 20 10:09:15 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 20 May 2015 12:09:15 +0200 Subject: RFR: 8080608: Missing archive name from jdeps -v -e output if no dependency on other JAR In-Reply-To: <555BCAD8.1080500@oracle.com> References: <555B6CC0.5070000@oracle.com> <555BCAD8.1080500@oracle.com> Message-ID: <555C5D4B.6080503@oracle.com> On 20/05/15 01:44, Mandy Chung wrote: > On 05/19/2015 10:02 AM, Daniel Fuchs wrote: >> Hi, >> >> Please find below a patch for jdeps: >> >> http://cr.openjdk.java.net/~dfuchs/webrev_8080608/webrev.00/ >> https://bugs.openjdk.java.net/browse/JDK-8080608 >> >> : >> >> The fix will make sure that jdeps prints instead: >> >> indirect2.jar -> dist/unsafe.jar >> use.indirect2.UseUnsafeIndirectly2 -> use.unsafe.UseUnsafeClass >> unsafe.jar >> unsafe.jar -> dist/unsafe.jar >> use.unsafe.UseClassWithUnsafe -> use.unsafe.UseUnsafeClass unsafe.jar > > A dependency from unsafe.jar to itself is redundant and thus was > excluded from the returned value of the requires method. Maybe better > just to output without any dependence like this: > > unsafe.jar > use.unsafe.UseClassWithUnsafe -> use.unsafe.UseUnsafeClass unsafe.jar I'm not sure it's redundant because the dependency written -> This is the only place were the path to the archive appears - and I believe it's good to keep it (+ it makes the output more regular and thus easier to parse with simple greps etc...). > > Analyzer.java > > 147 if (result.requires.isEmpty() && type == Type.VERBOSE && > hasDependences(source)) { > Is type == Type.VERBOSE necessary? If hasDependences(source) > returns true, > "unsafe.jar" is missing for non-verbose mode I assume. Yes - for summary mode, having a line that tells you unsafe.jar -> dist/unsafe.jar and nothing else is not very helpful. Actually - I think the test should be type != Type.SUMMARY rather than type == Type.VERBOSE. > This long line should be broken into multiple lines. > > Maybe good to initialize Stream to handle the empty and > non-empty case to avoid duplicate code line 148-149: > final ArchiveDeps result = results.get(source); > Stream reqs = result.requires().stream(); > if (result.requires().isEmpty()&& hasDependences(source)) { > reqs = Stream.of(source); > } > reqs.sorted(..... Right. Good idea. New webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8080608/webrev.01/ > I haven't reviewed the tests. They are named as closure. Are these > tests for the new jdeps enhancement that you are thinking? Hmmm... well - yes and now. The 'closure' directory name might be a misnomer... Maybe 'VerboseFormat' would be a better name. But the test tests the verbose format by performing a closure... There is only one test: JdepsDependencyClosure (containing several test cases). The rest are just dummy java files on which the test performs its analysis. The test accept arguments in the form of either --test: (where is the test case to run and is a number in [0..3]), or -e -v This means that you can use the test as a means to get the closure on all classes depending on a particular class, where only the classes in the given are analyzed. So yes - it could serve as a basis to develop the tests that will come with the new enhancement I was thinking about, but I'm not sure it will be directly usable for that in this form. In the mean time, someone who would need to get the closure of his own classes depending on an unsupported usage of a private sun.* API could also use that test as if it where a stand alone tool (no guarantee made that it won't break on some untested formatting though). best regards, -- daniel > > Thanks > Mandy From paul.sandoz at oracle.com Wed May 20 10:24:08 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 20 May 2015 12:24:08 +0200 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork In-Reply-To: <555C57F8.3020307@oracle.com> References: <555C32C8.90301@oracle.com> <168C61AB-074F-4E36-9297-75E26B10F937@oracle.com> <555C57F8.3020307@oracle.com> Message-ID: <9CAD4D10-35D5-4C04-B19D-6C4D7D57B3CA@oracle.com> On May 20, 2015, at 11:46 AM, David Holmes wrote: > On 20/05/2015 7:28 PM, Paul Sandoz wrote: >> >> On May 20, 2015, at 9:07 AM, David Holmes wrote: >> >>> On 20/05/2015 3:55 AM, Paul Sandoz wrote: >>>> Hi, >>>> >>>> https://bugs.openjdk.java.net/browse/JDK-8080623 >>>> >>>> diff -r ea3ca5cfc3c6 src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java >>>> --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 20:04:29 2015 +0300 >>>> +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 19:54:00 2015 +0200 >>>> @@ -1328,13 +1328,9 @@ >>>> /** >>>> * Number of times to spin-wait before blocking. The spins (in >>>> * awaitRunStateLock and awaitWork) currently use randomized >>>> - * spins. If/when MWAIT-like intrinsics becomes available, they >>>> - * may allow quieter spinning. The value of SPINS must be a power >>>> - * of two, at least 4. The current value causes spinning for a >>>> - * small fraction of typical context-switch times, well worthwhile >>>> - * given the typical likelihoods that blocking is not necessary. >>>> + * spins. Currently set to zero to reduce CPU usage. >>> >>> I'd keep the commentary even if disabling spinning at this time. >>> >> >> Some of removed commentary makes less sense given the motivation to set the value to zero. How about the following tweak: >> >> /** >> * Number of times to spin-wait before blocking. The spins (in >> * awaitRunStateLock and awaitWork) currently use randomized >> - * spins. If/when MWAIT-like intrinsics becomes available, they >> - * may allow quieter spinning. The value of SPINS must be a power >> - * of two, at least 4. The current value causes spinning for a >> - * small fraction of typical context-switch times, well worthwhile >> - * given the typical likelihoods that blocking is not necessary. >> + * spins. Currently set to zero to reduce CPU usage. > > I've lost the context for what "spin" is getting randomized ?? > Not sure there was much context to begin with :-) best to look at the implementation: a spin value, initialized to SPINS, is (if > 0) decremented if the next value from a PRNG (Marsaglia-like) is non-negative. >> + * >> + * If greater than zero the value of SPINS must be a power >> + * of two, at least 4. A value of 2048 causes spinning for a >> + * small fraction of typical context-switch times. >> + * >> + * If/when MWAIT-like intrinsics becomes available, they >> + * may allow quieter spinning. > > Yep that's fine - thanks. > Thanks, Paul. From amy.lu at oracle.com Wed May 20 10:54:46 2015 From: amy.lu at oracle.com (Amy Lu) Date: Wed, 20 May 2015 18:54:46 +0800 Subject: JDK 9 RFR of JDK-8080680: sun/nio/cs/TestCompoundTest.java should be removed from TEST.groups Message-ID: <555C67F6.1050700@oracle.com> sun/nio/cs/TestCompoundTest.java This test was removed in JDK-8080330, it should also be removed from TEST.groups Please help to review and sponsor this simple patch: bug: https://bugs.openjdk.java.net/browse/JDK-8080680 webrev: http://cr.openjdk.java.net/~amlu/8080680/webrev.00/ --- old/test/TEST.groups 2015-05-20 18:48:25.000000000 +0800 +++ new/test/TEST.groups 2015-05-20 18:48:25.000000000 +0800 @@ -534,7 +534,6 @@ sun/nio/cs/OLD/TestIBMDB.java \ sun/nio/cs/SJISCanEncode.java \ sun/nio/cs/Test6254467.java \ - sun/nio/cs/TestCompoundTest.java \ sun/nio/cs/TestCp834_SBCS.java \ sun/nio/cs/TestEUC_TW.java \ sun/nio/cs/TestISO2022CNDecoder.java \ Thanks, Amy From staffan.larsen at oracle.com Wed May 20 11:19:58 2015 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Wed, 20 May 2015 13:19:58 +0200 Subject: RFR(M, v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5559D85B.2050500@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> Message-ID: Dmitry, I?ve look at the changes on the hotspot side. vm/services/diagnosticCommand.hpp: 270 static const char* impact() { 271 return "Low"; 272 } I wonder if the impact should be ?Medium? instead. There aren?t any good guidelines for what impact means, but finalizerinfo does have non-negible impact. test/serviceability/dcmd/gc/FinalizerInfoTest.java: 69 while(wasInitialized != objectsCount); I don?t get the point of this loop. wasInitialized will always be equal to objectsCount at this point. 72 while(wasTrapped < 1); Perhaps the System.gc() call should be inside this loop? test/serviceability/dcmd/gc/HeapInfoTest.java: Can you add some output verification here? /Staffan > On 18 maj 2015, at 14:17, Dmitry Samersoff wrote: > > Everyone, > > Please review updated version of the fix: > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ > > Most important part of the fix provided by Peter Levart, so all > credentials belongs to him. > > -Dmitry > > On 2015-05-16 15:48, Peter Levart wrote: >> >> >> On 05/16/2015 02:38 PM, Peter Levart wrote: >>> >>> >>> On 05/16/2015 09:35 AM, Dmitry Samersoff wrote: >>>> Derek, >>>> >>>> Personally, I'm for volatile over explicit fence too. >>>> >>>> So I'll change the code if Peter don't have objections. >>> >>> There are no objections. There's one unneeded volatile store to .next >>> field then in enqueue(), but it is followed by another volatile store, >>> so there shouldn't be overhead on Intel and SPARC at least. >>> >>> Regards, Peter >> >> If you make .next field volatile, then perhaps you could also cache it's >> value in reallyPoll() into a local variable, so that it is not read >> twice. Like this: >> >> private Reference reallyPoll() { /* Must hold lock */ >> Reference r = head; >> if (r != null) { >> Reference rn = r.next; // HERE !!! >> head = (rn == r) ? >> null : >> rn; // Unchecked due to the next field having a raw type >> in Reference >> r.queue = NULL; >> r.next = r; >> queueLength--; >> if (r instanceof FinalReference) { >> sun.misc.VM.addFinalRefCount(-1); >> } >> return r; >> } >> return null; >> } >> >> >> >> Peter >> >> >>> >>>> -Dmitry >>>> >>>> On 2015-05-16 01:59, Derek White wrote: >>>>> Hi Dmitry, Peter, >>>>> >>>>> I should read my email more frequently - I missed Dmitry's last webrev >>>>> email. >>>>> >>>>> My comments on a preference for volatile over Unsafe are not a strong >>>>> objection to using Unsafe fences. I just don't have enough experience >>>>> with Unsafe fences yet to agree that this use is correct. >>>>> >>>>> While looking over this Reference code I found 3-6 really simple things >>>>> that need cleaning up that have been there for years, so I'm not a big >>>>> cheerleader for more complicated things here :-) >>>>> >>>>> - Derek >>>>> >>>>> On 5/15/15 6:46 PM, Derek White wrote: >>>>>> Hi Peter, >>>>>> >>>>>> Some comments below... >>>>>> >>>>>> On 5/14/15 3:50 AM, Peter Levart wrote: >>>>>>> Hi Derek, >>>>>>> >>>>>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>>>>> Hi Peter, >>>>>>>> >>>>>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>>>>> but I have some concerns... >>>>>>> I did have a concern too, ... >>>>>>> >>>>>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>>>>> Hi Dmitry, >>>>>>>>> >>>>>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>>>>> logical. >>>>>>>>> >>>>>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>>>>> threads for the entire time of iteration. This can blow up the >>>>>>>>> application. Suppose one wants to diagnose the application because >>>>>>>>> he suspects that finalizer thread hardly keeps up with production >>>>>>>>> of finalizable instances. This can happen if the allocation rate of >>>>>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>>>>>>> up gradually and is already holding several million objects. Now >>>>>>>>> you initiate the diagnostic command to print the queue. The >>>>>>>>> iteration over and grouping/counting of several millions of >>>>>>>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>>>>>>> reference handler thread. But does not block the threads that >>>>>>>>> allocate finalizable objects. By the time the iteration is over, >>>>>>>>> the JVM blows up and application slows down to a halt doing GCs >>>>>>>>> most of the time, getting OOMEs, etc... >>>>>>>>> >>>>>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>>>>> purposes without holding a lock. The modification required to do >>>>>>>>> that is the following (havent tested this, but I think it should work): >>>>>>>>> >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>>>>> >>>>>>>> One issue to watch out for is the garbage collectors inspect the >>>>>>>> Reference.next field from C code directly (to distinguish active vs. >>>>>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>>>>> >>>>>>>> Your change makes "inactive" References superficially look like >>>>>>>> "enqueued" References. The GC code is rather subtle and I haven't >>>>>>>> yet seen a case where it would get confused by this change, but >>>>>>>> there could easily be something like that lurking in the GC code. >>>>>>> ...but then I thought that GC can in no way treat a Reference >>>>>>> differently whether it is still enqueued in a ReferenceQueue or >>>>>>> already dequeued (inactive) - responsibility is already on the Java >>>>>>> side. Currently the definition of Reference.next is this: >>>>>>> >>>>>>> /* When active: NULL >>>>>>> * pending: this >>>>>>> * Enqueued: next reference in queue (or this if last) >>>>>>> * Inactive: this >>>>>>> */ >>>>>>> @SuppressWarnings("rawtypes") >>>>>>> Reference next; >>>>>>> >>>>>>> We see that, unless GC inspects all ReferenceQueue instances and >>>>>>> scans their lists too, the state of a Reference that is enqueued as >>>>>>> last in list is indistinguishable from the state of inactive >>>>>>> Reference. So I deduced that this distinction (enqueued/inactive) >>>>>>> can't be established solely on the value of .next field ( == this or >>>>>>> != this)... >>>>>>> >>>>>>> But I should inspect the GC code too to build a better understanding >>>>>>> of that part of the story... >>>>>>> >>>>>>> Anyway. It turns out that there is already enough state in Reference >>>>>>> to destinguish between it being enqueued as last in list and already >>>>>>> dequeued (inactive) - the additional state is Reference.queue that >>>>>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>>>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>>>>> (r.next and r.queue) are assigned and read in correct order. This can >>>>>>> be achieved either by making Reference.next a volatile field or by a >>>>>>> couple of explicit fences: >>>>>>> >>>>>>> >>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>>>>> >>>>>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>>>>> before linking the reference into the queue's head in >>>>>>> ReferenceQueue.enqueue(): >>>>>>> >>>>>>> r.queue = ENQUEUED; >>>>>>> r.next = (head == null) ? r : head; >>>>>>> head = r; >>>>>>> >>>>>>> Both stores are volatile. >>>>>> This sounds a bit better. I don't have a good handle on the pros and >>>>>> cons of a volatile field over explicit fences via Unsafe in this case. >>>>>> Kim might jump in soon. >>>>>> >>>>>> I'd like to suggest an entirely less-clever solution. Since the >>>>>> problem is that forEach() might see inconsistent values for the queue >>>>>> and next fields of a Reference, but we don't want to grab a lock >>>>>> walking the whole queue, we could instead grab the lock as we look at >>>>>> each Reference (and do the "back-up" trick if we were interfered >>>>>> with). Of course this is slower than going lock-free, but it's not any >>>>>> more overhead than the ReferenceHandler thread or FinalizerThreads incur. >>>>>> >>>>>> The only benefit of this solution over the others is that it is less >>>>>> clever, and I'm not sure how much cleverness this problem deserves. >>>>>> Given that, and ranking the solutions as "lock" < (clever) "volatile" >>>>>> < "fence", I'd be happier with the "volatile" or "lock" solution if >>>>>> that is sufficient. >>>>>> >>>>>> - Derek >>>>>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>>>>> forEach iteration method with no concrete logic. >>>>>>>>> >>>>>>>>> It would be possible to encapsulate the entire logic into a special >>>>>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>>>>> static method(s) (printFinalizationQueue)... You could just expose >>>>>>>>> a package-private forEach static method from Finalizer and code the >>>>>>>>> rest in DiagnosticCommands. >>>>>>>> That's good for encapsulation. But I'm concerned that if "forEach" >>>>>>>> got exposed beyond careful use in DiagnosticCommands, and the >>>>>>>> Referents were leaked back into the heap, then we could get >>>>>>>> unexpected object resurrection after finalization. This isn't a bug >>>>>>>> on it's own - any finalizer might resurrect its object if not >>>>>>>> careful, but ordinarily /only/ the finalizer could resurrect the >>>>>>>> object. This could invalidate application invariants? >>>>>>> Well, it all stays in the confines of package-private API - internal >>>>>>> to JDK. Any future additional use should be reviewed carefully. >>>>>>> Comments on the forEach() method should warn about that. >>>>>>> >>>>>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>>>>> /another/ case of diagnostics affecting application behavior. And >>>>>>>> there are pathological scenarios where this gets severe. This is >>>>>>>> unfortunate but not uncommon. There is enough complication here that >>>>>>>> you should be sure that the fix for diagnostics performance doesn't >>>>>>>> introduce subtle bugs to the system in general. A change in this >>>>>>>> area should get a thorough review from both the runtime and GC sides. >>>>>>> Is the webrev.02 proposed above more acceptable in that respect? It >>>>>>> does not introduce any logical changes to existing code. >>>>>>> >>>>>>>> Better yet, the reference handling code in GC and runtime should >>>>>>>> probably be thrown out and re-written, but that's another issue :-) >>>>>>> I may have some proposals in that direction. Stay tuned. >>>>>>> >>>>>>> Regards, Peter >>>>>>> >>>>>>>> - Derek >>>>>>>> >>>>>>>>> Regards, Peter >>>>>>>>> >>>>>>>>> >>>>>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>>>>> Everybody, >>>>>>>>>> >>>>>>>>>> Updated version: >>>>>>>>>> >>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>>>>> >>>>>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>>>>> >>>>>>>>>> -Dmitry >>>>>>>>>> >>>>>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>> >>>>>>>>>>> Lots of good comments here. >>>>>>>>>>> >>>>>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>>>>> general iterator and lambda. >>>>>>>>>>> >>>>>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>>>>> >>>>>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>>>>> >>>>>>>>>>> The sorting suggestion is a nice touch. >>>>>>>>>>> >>>>>>>>>>> - Derek White, GC team >>>>>>>>>>> >>>>>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>>> >>>>>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>>>>> Dmitry, >>>>>>>>>>>>> >>>>>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>>>>> >>>>>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>>>>> running out of memory. >>>>>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>>>>> >>>>>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>>>>> interfere with synchronization? >>>>>>>>>>>> >>>>>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>>>>> >>>>>>>>>>>> private void remove() { >>>>>>>>>>>> synchronized (lock) { >>>>>>>>>>>> if (unfinalized == this) { >>>>>>>>>>>> if (this.next != null) { >>>>>>>>>>>> unfinalized = this.next; >>>>>>>>>>>> } else { >>>>>>>>>>>> unfinalized = this.prev; >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> if (this.next != null) { >>>>>>>>>>>> this.next.prev = this.prev; >>>>>>>>>>>> } >>>>>>>>>>>> if (this.prev != null) { >>>>>>>>>>>> this.prev.next = this.next; >>>>>>>>>>>> } >>>>>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>>>>> traverse the list unsynchronized >>>>>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>>>>> finalized */ >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>>>>> pointer could be used instead: >>>>>>>>>>>> >>>>>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>>>>> return (prev == this); >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>>>>> >>>>>>>>>>>> private void add() { >>>>>>>>>>>> synchronized (lock) { >>>>>>>>>>>> if (unfinalized != null) { >>>>>>>>>>>> this.next = unfinalized; >>>>>>>>>>>> unfinalized.prev = this; >>>>>>>>>>>> } >>>>>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>>>>> // instance fully initialized >>>>>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>>>>> U.storeFence(); >>>>>>>>>>>> unfinalized = this; >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>>>>> >>>>>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>>>>> out? >>>>>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>>>>> two purposes: >>>>>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>>>>> >>>>>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>>>>> finalize() method. >>>>>>>>>>>> >>>>>>>>>>>> Regards, Peter >>>>>>>>>>>> >>>>>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>>>>> >>>>>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>>>>> permission() and limit access: >>>>>>>>>>>>> >>>>>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>>>>> "monitor", NULL}; >>>>>>>>>>>>> return p; >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>>>>> >>>>>>>>>>>>> Thanks, >>>>>>>>>>>>> /Staffan >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> Everyone, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Please review the fix: >>>>>>>>>>>>>> >>>>>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>>>>> >>>>>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>>>>> >>>>>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>>>>> with count >>>>>>>>>>>>>> >>>>>>>>>>>>>> -Dmitry >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>>>>> * I would love to change the world, but they won't give me the sources. >>> >> > > > -- > Dmitry Samersoff > Oracle Java development team, Saint Petersburg, Russia > * I would love to change the world, but they won't give me the sources. From peter.levart at gmail.com Wed May 20 11:44:46 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 20 May 2015 13:44:46 +0200 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <555C48DC.7000005@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <555C4444.6050008@gmail.com> <555C48DC.7000005@oracle.com> Message-ID: <555C73AE.8050601@gmail.com> On 05/20/2015 10:42 AM, Dmitry Samersoff wrote: > Peter, > >> What about creating a special package-private >> java.lang.ref.DiagnosticCommands class > I'm not quite happy with current printFinalizationQueue method - love to > have a way to print directly to DCMD pipe from Java rather than return a > huge string to VM. > > But lang.ref.Finalizer is cached by VM (see > SystemDictionary::Finalizer_klass()) and is known as special > i.e. check-when-modify-hotspot class. > > We don't plan to expand this DCMD so I'm reluctant to create a separate > class for one simple static method - it adds extra cost of > compiling/loading/care. > > -Dmitry Ok then. I see diagnostic commands mostly format their output in native code. But for some of them (like this finalizer histogram) it would be nice to have a Java wrapper for hotspot's outputStream. It wouldn't be difficult to create such a class with JNI bindings, but where should one put it? Into which module? Otherwise, the simplest unformated data structure to return from such a method is an Object[] where you have String/Integer objects intermingled in pairs. Returning a Map.Entry[] is already more complicated to iterate and navigate in native code. Map even more so. Regards, Peter > > On 2015-05-20 11:22, Peter Levart wrote: >> >> On 05/20/2015 08:51 AM, Dmitry Samersoff wrote: >>> Mandy, >>> >>>> However I have trouble for >>>> Finalizer.printFinalizationQueue method that doesn?t belong there. >>>> What are the other alternatives you have explored? >>> Other alternatives could be to do all hashing/sorting/printing on native >>> layer i.e. implement printFinalizationQueue inside VM. >>> >>> Both options has pros and cons - Java based solution requires less JNI >>> calls and better readable but takes more memory. >>> >>> It might be better to return an array of Map.Entry >>> objects to VM rather than one huge string. >>> >>> -Dmitry >> Hi Dmitry, >> >> What about creating a special package-private >> java.lang.ref.DiagnosticCommands class which is then used as the home of >> static printFinalizationQueue method (and possible future diagnostic >> commands methods in the package). You could then expose a static >> package-private method from Finalizer: >> >> static void forEachEnqueued(Consumer> action) { >> queue.forEach(action); >> } >> >> ...and use it to implement the printFinalizationQueue. >> >> Regards, Peter >> >> >>> >>> >>> On 2015-05-20 05:54, Mandy Chung wrote: >>>>> On May 18, 2015, at 5:17 AM, Dmitry Samersoff >>>>> > >>>>> wrote: >>>>> >>>>> Please review updated version of the fix: >>>>> >>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ >>>>> >>>>> Most important part of the fix provided by Peter Levart, so all >>>>> credentials belongs to him. >>>> My apology for being late to the review. The subject line doesn?t catch >>>> my attention early enough :) >>>> >>>> I have to do further detail review tomorrow or so to follow the >>>> discussion and closely inspect the reference implementation. Just to >>>> give you a quick comment. I?m okay to add ReferenceQueue.forEach method >>>> at the first glance. However I have trouble for >>>> Finalizer.printFinalizationQueue method that doesn?t belong there. What >>>> are the other alternatives you have explored? >>>> >>>> Mandy >>>> > From dmitry.samersoff at oracle.com Wed May 20 12:11:57 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Wed, 20 May 2015 15:11:57 +0300 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <555C73AE.8050601@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <555C4444.6050008@gmail.com> <555C48DC.7000005@oracle.com> <555C73AE.8050601@gmail.com> Message-ID: <555C7A0D.3010803@oracle.com> Peter, > I see diagnostic commands mostly format their output in native code. > But for some of them (like this finalizer histogram) it would be nice > to have a Java wrapper for hotspot's outputStream. I love to have an ability to write pure-java DCMD's without touching of hotspot code but it's a long term goal, out of scope of this fix. Just a wrapper around hotspot output stream has a couple of underwear complications around memory management and error handling, so it should be a separate project. -Dmitry On 2015-05-20 14:44, Peter Levart wrote: > > > On 05/20/2015 10:42 AM, Dmitry Samersoff wrote: >> Peter, >> >>> What about creating a special package-private >>> java.lang.ref.DiagnosticCommands class >> I'm not quite happy with current printFinalizationQueue method - love to >> have a way to print directly to DCMD pipe from Java rather than return a >> huge string to VM. >> >> But lang.ref.Finalizer is cached by VM (see >> SystemDictionary::Finalizer_klass()) and is known as special >> i.e. check-when-modify-hotspot class. >> >> We don't plan to expand this DCMD so I'm reluctant to create a separate >> class for one simple static method - it adds extra cost of >> compiling/loading/care. >> >> -Dmitry > > Ok then. > > I see diagnostic commands mostly format their output in native code. But > for some of them (like this finalizer histogram) it would be nice to > have a Java wrapper for hotspot's outputStream. It wouldn't be difficult > to create such a class with JNI bindings, but where should one put it? > Into which module? > > Otherwise, the simplest unformated data structure to return from such a > method is an Object[] where you have String/Integer objects intermingled > in pairs. Returning a Map.Entry[] is already more > complicated to iterate and navigate in native code. Map > even more so. > > Regards, Peter > >> >> On 2015-05-20 11:22, Peter Levart wrote: >>> >>> On 05/20/2015 08:51 AM, Dmitry Samersoff wrote: >>>> Mandy, >>>> >>>>> However I have trouble for >>>>> Finalizer.printFinalizationQueue method that doesn?t belong there. >>>>> What are the other alternatives you have explored? >>>> Other alternatives could be to do all hashing/sorting/printing on >>>> native >>>> layer i.e. implement printFinalizationQueue inside VM. >>>> >>>> Both options has pros and cons - Java based solution requires less JNI >>>> calls and better readable but takes more memory. >>>> >>>> It might be better to return an array of Map.Entry >>>> objects to VM rather than one huge string. >>>> >>>> -Dmitry >>> Hi Dmitry, >>> >>> What about creating a special package-private >>> java.lang.ref.DiagnosticCommands class which is then used as the home of >>> static printFinalizationQueue method (and possible future diagnostic >>> commands methods in the package). You could then expose a static >>> package-private method from Finalizer: >>> >>> static void forEachEnqueued(Consumer> action) { >>> queue.forEach(action); >>> } >>> >>> ...and use it to implement the printFinalizationQueue. >>> >>> Regards, Peter >>> >>> >>>> >>>> >>>> On 2015-05-20 05:54, Mandy Chung wrote: >>>>>> On May 18, 2015, at 5:17 AM, Dmitry Samersoff >>>>>> > >>>>>> wrote: >>>>>> >>>>>> Please review updated version of the fix: >>>>>> >>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ >>>>>> >>>>>> Most important part of the fix provided by Peter Levart, so all >>>>>> credentials belongs to him. >>>>> My apology for being late to the review. The subject line doesn?t >>>>> catch >>>>> my attention early enough :) >>>>> >>>>> I have to do further detail review tomorrow or so to follow the >>>>> discussion and closely inspect the reference implementation. Just to >>>>> give you a quick comment. I?m okay to add ReferenceQueue.forEach >>>>> method >>>>> at the first glance. However I have trouble for >>>>> Finalizer.printFinalizationQueue method that doesn?t belong there. >>>>> What >>>>> are the other alternatives you have explored? >>>>> >>>>> Mandy >>>>> >> > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From dmitry.samersoff at oracle.com Wed May 20 12:28:01 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Wed, 20 May 2015 15:28:01 +0300 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> Message-ID: <555C7DD1.7090600@oracle.com> Staffan, On 2015-05-20 14:19, Staffan Larsen wrote: > Dmitry, > > I?ve look at the changes on the hotspot side. > > vm/services/diagnosticCommand.hpp: > > 270 static const char* impact() { > 271 return "Low"; > 272 } > > I wonder if the impact should be ?Medium? instead. There aren?t any good guidelines for what impact means, but finalizerinfo does have non-negible impact. OK. I'll change it. > > > test/serviceability/dcmd/gc/FinalizerInfoTest.java: > > 69 while(wasInitialized != objectsCount); > > I don?t get the point of this loop. wasInitialized will always be equal to objectsCount at this point. Agree. It left from one of previous experiments. > > 72 while(wasTrapped < 1); > > Perhaps the System.gc() call should be inside this loop? System.gc() instruct hotspot to start GC thread, but this thread may not start immediately. We need this loop to wait for GC thread. > test/serviceability/dcmd/gc/HeapInfoTest.java: > > Can you add some output verification here? This DCMD calls Universe::heap()->print_on() and output of this command should be covered by GC tests, more complicated than this one, because actual output depends to GC and heap parameters. I can just check for presence of "Metaspace" world in the DCMD output. -Dmitry > > > /Staffan > > >> On 18 maj 2015, at 14:17, Dmitry Samersoff wrote: >> >> Everyone, >> >> Please review updated version of the fix: >> >> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.07/ >> >> Most important part of the fix provided by Peter Levart, so all >> credentials belongs to him. >> >> -Dmitry >> >> On 2015-05-16 15:48, Peter Levart wrote: >>> >>> >>> On 05/16/2015 02:38 PM, Peter Levart wrote: >>>> >>>> >>>> On 05/16/2015 09:35 AM, Dmitry Samersoff wrote: >>>>> Derek, >>>>> >>>>> Personally, I'm for volatile over explicit fence too. >>>>> >>>>> So I'll change the code if Peter don't have objections. >>>> >>>> There are no objections. There's one unneeded volatile store to .next >>>> field then in enqueue(), but it is followed by another volatile store, >>>> so there shouldn't be overhead on Intel and SPARC at least. >>>> >>>> Regards, Peter >>> >>> If you make .next field volatile, then perhaps you could also cache it's >>> value in reallyPoll() into a local variable, so that it is not read >>> twice. Like this: >>> >>> private Reference reallyPoll() { /* Must hold lock */ >>> Reference r = head; >>> if (r != null) { >>> Reference rn = r.next; // HERE !!! >>> head = (rn == r) ? >>> null : >>> rn; // Unchecked due to the next field having a raw type >>> in Reference >>> r.queue = NULL; >>> r.next = r; >>> queueLength--; >>> if (r instanceof FinalReference) { >>> sun.misc.VM.addFinalRefCount(-1); >>> } >>> return r; >>> } >>> return null; >>> } >>> >>> >>> >>> Peter >>> >>> >>>> >>>>> -Dmitry >>>>> >>>>> On 2015-05-16 01:59, Derek White wrote: >>>>>> Hi Dmitry, Peter, >>>>>> >>>>>> I should read my email more frequently - I missed Dmitry's last webrev >>>>>> email. >>>>>> >>>>>> My comments on a preference for volatile over Unsafe are not a strong >>>>>> objection to using Unsafe fences. I just don't have enough experience >>>>>> with Unsafe fences yet to agree that this use is correct. >>>>>> >>>>>> While looking over this Reference code I found 3-6 really simple things >>>>>> that need cleaning up that have been there for years, so I'm not a big >>>>>> cheerleader for more complicated things here :-) >>>>>> >>>>>> - Derek >>>>>> >>>>>> On 5/15/15 6:46 PM, Derek White wrote: >>>>>>> Hi Peter, >>>>>>> >>>>>>> Some comments below... >>>>>>> >>>>>>> On 5/14/15 3:50 AM, Peter Levart wrote: >>>>>>>> Hi Derek, >>>>>>>> >>>>>>>> On 05/13/2015 10:34 PM, Derek White wrote: >>>>>>>>> Hi Peter, >>>>>>>>> >>>>>>>>> I don't have smoking gun evidence that your change introduces a bug, >>>>>>>>> but I have some concerns... >>>>>>>> I did have a concern too, ... >>>>>>>> >>>>>>>>> On 5/12/15 6:05 PM, Peter Levart wrote: >>>>>>>>>> Hi Dmitry, >>>>>>>>>> >>>>>>>>>> You iterate the queue then, not the unfinalized list. That's more >>>>>>>>>> logical. >>>>>>>>>> >>>>>>>>>> Holding the queue's lock may pause reference handler and finalizer >>>>>>>>>> threads for the entire time of iteration. This can blow up the >>>>>>>>>> application. Suppose one wants to diagnose the application because >>>>>>>>>> he suspects that finalizer thread hardly keeps up with production >>>>>>>>>> of finalizable instances. This can happen if the allocation rate of >>>>>>>>>> finalizable objects is very high and/or finalize() methods are not >>>>>>>>>> coded to be fast enough. Suppose the queue of Finalizer(s) builds >>>>>>>>>> up gradually and is already holding several million objects. Now >>>>>>>>>> you initiate the diagnostic command to print the queue. The >>>>>>>>>> iteration over and grouping/counting of several millions of >>>>>>>>>> Finalizer(s) takes some time. This blocks finalizer thread and >>>>>>>>>> reference handler thread. But does not block the threads that >>>>>>>>>> allocate finalizable objects. By the time the iteration is over, >>>>>>>>>> the JVM blows up and application slows down to a halt doing GCs >>>>>>>>>> most of the time, getting OOMEs, etc... >>>>>>>>>> >>>>>>>>>> It is possible to iterate the elements of the queue for diagnostic >>>>>>>>>> purposes without holding a lock. The modification required to do >>>>>>>>>> that is the following (havent tested this, but I think it should work): >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.01/ >>>>>>>>>> >>>>>>>>> One issue to watch out for is the garbage collectors inspect the >>>>>>>>> Reference.next field from C code directly (to distinguish active vs. >>>>>>>>> pending, iterate over oops, etc.). You can search hotspot for >>>>>>>>> java_lang_ref_Reference::next*, java_lang_ref_Reference::set_next*. >>>>>>>>> >>>>>>>>> Your change makes "inactive" References superficially look like >>>>>>>>> "enqueued" References. The GC code is rather subtle and I haven't >>>>>>>>> yet seen a case where it would get confused by this change, but >>>>>>>>> there could easily be something like that lurking in the GC code. >>>>>>>> ...but then I thought that GC can in no way treat a Reference >>>>>>>> differently whether it is still enqueued in a ReferenceQueue or >>>>>>>> already dequeued (inactive) - responsibility is already on the Java >>>>>>>> side. Currently the definition of Reference.next is this: >>>>>>>> >>>>>>>> /* When active: NULL >>>>>>>> * pending: this >>>>>>>> * Enqueued: next reference in queue (or this if last) >>>>>>>> * Inactive: this >>>>>>>> */ >>>>>>>> @SuppressWarnings("rawtypes") >>>>>>>> Reference next; >>>>>>>> >>>>>>>> We see that, unless GC inspects all ReferenceQueue instances and >>>>>>>> scans their lists too, the state of a Reference that is enqueued as >>>>>>>> last in list is indistinguishable from the state of inactive >>>>>>>> Reference. So I deduced that this distinction (enqueued/inactive) >>>>>>>> can't be established solely on the value of .next field ( == this or >>>>>>>> != this)... >>>>>>>> >>>>>>>> But I should inspect the GC code too to build a better understanding >>>>>>>> of that part of the story... >>>>>>>> >>>>>>>> Anyway. It turns out that there is already enough state in Reference >>>>>>>> to destinguish between it being enqueued as last in list and already >>>>>>>> dequeued (inactive) - the additional state is Reference.queue that >>>>>>>> transitions from ReferenceQueue.ENQUEUED -> ReferenceQueue.NULL in >>>>>>>> ReferenceQueue.reallyPoll. We need to just make sure the two fields >>>>>>>> (r.next and r.queue) are assigned and read in correct order. This can >>>>>>>> be achieved either by making Reference.next a volatile field or by a >>>>>>>> couple of explicit fences: >>>>>>>> >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~plevart/misc/Finalizer.printFinalizationQueue/webrev.02/ >>>>>>>> >>>>>>>> The assignment of r.queue to ReferenceQueue.ENQUEUED already happens >>>>>>>> before linking the reference into the queue's head in >>>>>>>> ReferenceQueue.enqueue(): >>>>>>>> >>>>>>>> r.queue = ENQUEUED; >>>>>>>> r.next = (head == null) ? r : head; >>>>>>>> head = r; >>>>>>>> >>>>>>>> Both stores are volatile. >>>>>>> This sounds a bit better. I don't have a good handle on the pros and >>>>>>> cons of a volatile field over explicit fences via Unsafe in this case. >>>>>>> Kim might jump in soon. >>>>>>> >>>>>>> I'd like to suggest an entirely less-clever solution. Since the >>>>>>> problem is that forEach() might see inconsistent values for the queue >>>>>>> and next fields of a Reference, but we don't want to grab a lock >>>>>>> walking the whole queue, we could instead grab the lock as we look at >>>>>>> each Reference (and do the "back-up" trick if we were interfered >>>>>>> with). Of course this is slower than going lock-free, but it's not any >>>>>>> more overhead than the ReferenceHandler thread or FinalizerThreads incur. >>>>>>> >>>>>>> The only benefit of this solution over the others is that it is less >>>>>>> clever, and I'm not sure how much cleverness this problem deserves. >>>>>>> Given that, and ranking the solutions as "lock" < (clever) "volatile" >>>>>>> < "fence", I'd be happier with the "volatile" or "lock" solution if >>>>>>> that is sufficient. >>>>>>> >>>>>>> - Derek >>>>>>>>>> I also suggest the addition to the ReferenceQueue to be contained >>>>>>>>>> (package-private) and as generic as possible. That's why I suggest >>>>>>>>>> forEach iteration method with no concrete logic. >>>>>>>>>> >>>>>>>>>> It would be possible to encapsulate the entire logic into a special >>>>>>>>>> package-private class (say java.lang.ref.DiagnosticCommands) with >>>>>>>>>> static method(s) (printFinalizationQueue)... You could just expose >>>>>>>>>> a package-private forEach static method from Finalizer and code the >>>>>>>>>> rest in DiagnosticCommands. >>>>>>>>> That's good for encapsulation. But I'm concerned that if "forEach" >>>>>>>>> got exposed beyond careful use in DiagnosticCommands, and the >>>>>>>>> Referents were leaked back into the heap, then we could get >>>>>>>>> unexpected object resurrection after finalization. This isn't a bug >>>>>>>>> on it's own - any finalizer might resurrect its object if not >>>>>>>>> careful, but ordinarily /only/ the finalizer could resurrect the >>>>>>>>> object. This could invalidate application invariants? >>>>>>>> Well, it all stays in the confines of package-private API - internal >>>>>>>> to JDK. Any future additional use should be reviewed carefully. >>>>>>>> Comments on the forEach() method should warn about that. >>>>>>>> >>>>>>>>> I agree that using a lock over the ReferenceQueue iteration opens up >>>>>>>>> /another/ case of diagnostics affecting application behavior. And >>>>>>>>> there are pathological scenarios where this gets severe. This is >>>>>>>>> unfortunate but not uncommon. There is enough complication here that >>>>>>>>> you should be sure that the fix for diagnostics performance doesn't >>>>>>>>> introduce subtle bugs to the system in general. A change in this >>>>>>>>> area should get a thorough review from both the runtime and GC sides. >>>>>>>> Is the webrev.02 proposed above more acceptable in that respect? It >>>>>>>> does not introduce any logical changes to existing code. >>>>>>>> >>>>>>>>> Better yet, the reference handling code in GC and runtime should >>>>>>>>> probably be thrown out and re-written, but that's another issue :-) >>>>>>>> I may have some proposals in that direction. Stay tuned. >>>>>>>> >>>>>>>> Regards, Peter >>>>>>>> >>>>>>>>> - Derek >>>>>>>>> >>>>>>>>>> Regards, Peter >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On 05/12/2015 07:10 PM, Dmitry Samersoff wrote: >>>>>>>>>>> Everybody, >>>>>>>>>>> >>>>>>>>>>> Updated version: >>>>>>>>>>> >>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.03/ >>>>>>>>>>> >>>>>>>>>>> Now it iterates over queue and output result sorted by number of instances. >>>>>>>>>>> >>>>>>>>>>> -Dmitry >>>>>>>>>>> >>>>>>>>>>> On 2015-05-07 00:51, Derek White wrote: >>>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>>> >>>>>>>>>>>> Lots of good comments here. >>>>>>>>>>>> >>>>>>>>>>>> On the topic of what list should be printed out, I think we should focus >>>>>>>>>>>> on objects waiting to be finalized - e.g. the contents of the >>>>>>>>>>>> ReferenceQueue. It's more of a pain to walk the ReferenceQueue, but you >>>>>>>>>>>> could add a summerizeQueue(TreeMap) method, or a >>>>>>>>>>>> general iterator and lambda. >>>>>>>>>>>> >>>>>>>>>>>> A histogram of objects with finalize methods might also be interesting, >>>>>>>>>>>> but you can get most of the same information from a heap histogram >>>>>>>>>>>> (ClassHistogramDCmd, and search for count of Finalizer instances). >>>>>>>>>>>> >>>>>>>>>>>> BTW, by only locking the ReferenceQueue, we should only be blocking the >>>>>>>>>>>> FinalizerThread from making progress (and I think there's a GC thread >>>>>>>>>>>> that runs after GC that sorts found References objects that need >>>>>>>>>>>> processing into their respective ReferenceQueues). But locking the >>>>>>>>>>>> "unfinalized" list blocks initializing any object with a finalize() method. >>>>>>>>>>>> >>>>>>>>>>>> The sorting suggestion is a nice touch. >>>>>>>>>>>> >>>>>>>>>>>> - Derek White, GC team >>>>>>>>>>>> >>>>>>>>>>>> On 5/5/15 10:40 AM, Peter Levart wrote: >>>>>>>>>>>>> Hi Dmitry, Staffan, >>>>>>>>>>>>> >>>>>>>>>>>>> On 05/05/2015 12:38 PM, Staffan Larsen wrote: >>>>>>>>>>>>>> Dmitry, >>>>>>>>>>>>>> >>>>>>>>>>>>>> I think this should be reviewed on hotspot-gc and core-libs-dev as >>>>>>>>>>>>>> well considering the changes to Finalizer. >>>>>>>>>>>>>> >>>>>>>>>>>>>> I?m a little worried about the potentially very large String that is >>>>>>>>>>>>>> returned from printFinalizationQueue(). A possible different approach >>>>>>>>>>>>>> would be to write printFinalizationQueue() in C++ inside Hotspot. >>>>>>>>>>>>>> That would allow for outputting one line at a time. The output would >>>>>>>>>>>>>> still be saved in memory (since the stream is buffered), but at least >>>>>>>>>>>>>> the data is only saved once in memory, then. It would make the code a >>>>>>>>>>>>>> bit harder to write, so its a question of how scared we are of >>>>>>>>>>>>>> running out of memory. >>>>>>>>>>>>> If the output is just a histogram of # of instances per class name, >>>>>>>>>>>>> then it should not be too large, as there are not many different >>>>>>>>>>>>> classes overriding finalize() method (I counted 72 overriddings of >>>>>>>>>>>>> finalize() method in the whole jdk/src tree). >>>>>>>>>>>>> >>>>>>>>>>>>> I'm more concerned about the fact that while traversing the list, a >>>>>>>>>>>>> lock is held, which might impact prompt finalization(). Is it >>>>>>>>>>>>> acceptable for diagnostic output to impact performance and/or >>>>>>>>>>>>> interfere with synchronization? >>>>>>>>>>>>> >>>>>>>>>>>>> It might be possible to scan the list without holding a lock for >>>>>>>>>>>>> diagnostic purposes if Finalizer.remove() didn't set the removed >>>>>>>>>>>>> Finalizer.next pointer to point back to itself: >>>>>>>>>>>>> >>>>>>>>>>>>> private void remove() { >>>>>>>>>>>>> synchronized (lock) { >>>>>>>>>>>>> if (unfinalized == this) { >>>>>>>>>>>>> if (this.next != null) { >>>>>>>>>>>>> unfinalized = this.next; >>>>>>>>>>>>> } else { >>>>>>>>>>>>> unfinalized = this.prev; >>>>>>>>>>>>> } >>>>>>>>>>>>> } >>>>>>>>>>>>> if (this.next != null) { >>>>>>>>>>>>> this.next.prev = this.prev; >>>>>>>>>>>>> } >>>>>>>>>>>>> if (this.prev != null) { >>>>>>>>>>>>> this.prev.next = this.next; >>>>>>>>>>>>> } >>>>>>>>>>>>> // this.next = this; must not be set so that we can >>>>>>>>>>>>> traverse the list unsynchronized >>>>>>>>>>>>> this.prev = this; /* Indicates that this has been >>>>>>>>>>>>> finalized */ >>>>>>>>>>>>> } >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> For detecting whether a Finalizer is already processed, the 'prev' >>>>>>>>>>>>> pointer could be used instead: >>>>>>>>>>>>> >>>>>>>>>>>>> private boolean hasBeenFinalized() { >>>>>>>>>>>>> return (prev == this); >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> Also, to make sure a data race dereferencing 'unfinalized' in >>>>>>>>>>>>> unsynchronized printFinalizationQueue() would get you a fully >>>>>>>>>>>>> initialized Finalizer instance (in particular the next pointer), you >>>>>>>>>>>>> would have to make the 'unfinalized' field volatile or insert an >>>>>>>>>>>>> Unsafe.storeFence() before assigning to 'unfinalized': >>>>>>>>>>>>> >>>>>>>>>>>>> private void add() { >>>>>>>>>>>>> synchronized (lock) { >>>>>>>>>>>>> if (unfinalized != null) { >>>>>>>>>>>>> this.next = unfinalized; >>>>>>>>>>>>> unfinalized.prev = this; >>>>>>>>>>>>> } >>>>>>>>>>>>> // make sure a data race dereferencing 'unfinalized' >>>>>>>>>>>>> // in printFinalizationQueue() does see the Finalizer >>>>>>>>>>>>> // instance fully initialized >>>>>>>>>>>>> // (in particular the 'next' pointer) >>>>>>>>>>>>> U.storeFence(); >>>>>>>>>>>>> unfinalized = this; >>>>>>>>>>>>> } >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> By doing these modifications, I think you can remove >>>>>>>>>>>>> synchronized(lock) {} from printFinalizationQueue(). >>>>>>>>>>>>> >>>>>>>>>>>>>> I see you are traversing the ?unfinalized? list in Finalizer, whereas >>>>>>>>>>>>>> the old SA code for ?-finalizerinfo' traverses the ?queue? list. I am >>>>>>>>>>>>>> not sure of the difference, perhaps someone from the GC team can help >>>>>>>>>>>>>> out? >>>>>>>>>>>>> The 'queue' is a ReferenceQueue of Finalizer (FinalReference) >>>>>>>>>>>>> instances pending processing by finalizer thread because their >>>>>>>>>>>>> referents are eligible for finalization (they are not reachable any >>>>>>>>>>>>> more). The 'unfinalized' is a doubly-linked list of all Finalizer >>>>>>>>>>>>> instances for which their referents have not been finalized yet >>>>>>>>>>>>> (including those that are still reachable and alive). The later serves >>>>>>>>>>>>> two purposes: >>>>>>>>>>>>> - it keeps Finalizer instances reachable until they are processed >>>>>>>>>>>>> - it is a source of unfinalized instances for >>>>>>>>>>>>> running-finalizers-on-exit if requested by >>>>>>>>>>>>> System.runFinalizersOnExit(true); >>>>>>>>>>>>> >>>>>>>>>>>>> So it really depends on what one would like to see. Showing the queue >>>>>>>>>>>>> may be interesting if one wants to see how the finalizer thread is >>>>>>>>>>>>> coping with processing the finalize() invocations. Showing unfinalized >>>>>>>>>>>>> list may be interesting if one wants to know how many live + >>>>>>>>>>>>> finalization pending instances are there on the heap that override >>>>>>>>>>>>> finalize() method. >>>>>>>>>>>>> >>>>>>>>>>>>> Regards, Peter >>>>>>>>>>>>> >>>>>>>>>>>>>> For the output, it would be a nice touch to sort it on the number of >>>>>>>>>>>>>> references for each type. Perhaps outputting it more like a table >>>>>>>>>>>>>> (see the old code again) would also make it easier to digest. >>>>>>>>>>>>>> >>>>>>>>>>>>>> In diagnosticCommand.hpp, the new commands should override >>>>>>>>>>>>>> permission() and limit access: >>>>>>>>>>>>>> >>>>>>>>>>>>>> static const JavaPermission permission() { >>>>>>>>>>>>>> JavaPermission p = {"java.lang.management.ManagementPermission", >>>>>>>>>>>>>> "monitor", NULL}; >>>>>>>>>>>>>> return p; >>>>>>>>>>>>>> } >>>>>>>>>>>>>> >>>>>>>>>>>>>> The two tests don?t validate the output in any way. Would it be >>>>>>>>>>>>>> possible to add validation? Perhaps hard to make sure an object is on >>>>>>>>>>>>>> the finalizer queue? Hmm. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>> /Staffan >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> On 5 maj 2015, at 12:01, Dmitry Samersoff >>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Everyone, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Please review the fix: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.01/ >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> heap dcmd outputs the same information as SIGBREAK >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> finalizerinfo dcmd outputs a list of all classes in finalization queue >>>>>>>>>>>>>>> with count >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -Dmitry >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Dmitry Samersoff >>>>>>>>>>>>>>> Oracle Java development team, Saint Petersburg, Russia >>>>>>>>>>>>>>> * I would love to change the world, but they won't give me the sources. >>>> >>> >> >> >> -- >> Dmitry Samersoff >> Oracle Java development team, Saint Petersburg, Russia >> * I would love to change the world, but they won't give me the sources. > -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From paul.sandoz at oracle.com Wed May 20 12:32:26 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 20 May 2015 14:32:26 +0200 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> <55533CAE.3050201@oracle.com> <55549297.5020002@oracle.com> <5555E343.5050600@oracle.com> <5559E3A5.8030108@oracle.com> Message-ID: <59A05F7D-058A-4A9B-BA65-17A71A57254D@oracle.com> On May 20, 2015, at 9:14 AM, Roland Westrelin wrote: >> What do you think about the following version: >> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.04 > > Still looks good to me. > And to me. Injected fields seem a little magical but safer. Paul. From miroslav.kos at oracle.com Wed May 20 12:38:30 2015 From: miroslav.kos at oracle.com (Miroslav Kos) Date: Wed, 20 May 2015 14:38:30 +0200 Subject: RFR [9] 8072839: JAX-B Plugability Layer: using java.util.ServiceLoader In-Reply-To: <555BA0BA.1070208@oracle.com> References: <55560D2B.3040400@oracle.com> <555BA0BA.1070208@oracle.com> Message-ID: <555C8046.9030700@oracle.com> On 19/05/15 22:44, Alan Bateman wrote: > On 15/05/2015 16:13, Miroslav Kos wrote: >> Hi everybody, >> >> this is review request for: 8072839: JAX-B Plugability Layer: using >> java.util.ServiceLoader >> The JAX-B API changed a little bit - proprietary ServiceLoader-like >> code has been replaced by java.util.ServiceLoader. This change is >> required by Jigsaw, old configuration way still supported. >> >> JBS:https://bugs.openjdk.java.net/browse/JDK-8072839 >> webrev: http://cr.openjdk.java.net/~mkos/8072839/jaxws.02/index.html > I skimmed through this and it mostly looks okay. Some really long > (200+) lines but that seems to be normal in this area. At some point > it would be good to do a wider pass over this code and replace the old > style tags ( etc.) with newer forms. > > In JAXBContext it looks likes a typo "loading facilities" when I > assume it should be "loading facility". > > Are there any new tests for this? Existing tests will exercise some of > this but I don't see any tests that will exercise JAXBContextFactory. > > -Alan. Thanks for checking - would you be ok with addressing javadoc later? Of course, typo can be fixed easily right away ... Regarding tests - I created new tests for many different setup combination, but they require environment setup (property files in jdk conf dir, java.util.ServiceLoader descriptors, System property). The tests are using bash scipting (testing different env combinations) and I don't have currently jtreg version of those. To test the glassfish part, I ran glassfish smoke tests. Thanks Miran From kumar.x.srinivasan at oracle.com Wed May 20 12:44:26 2015 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Wed, 20 May 2015 05:44:26 -0700 Subject: [8] RFR of 8066985: Java Webstart downloading packed files can result in Timezone set to UTC In-Reply-To: <555B7D43.3020802@oracle.com> References: <550976B9.6030503@oracle.com> <5509F73C.6000306@oracle.com> <550AD4C9.9030905@oracle.com> <550AEF48.4070904@gmail.com> <550AF969.7070706@gmail.com> <550C36FD.701@oracle.com> <5511C5BE.2010809@oracle.com> <5511E9CB.7050504@oracle.com> <5512850F.90701@oracle.com> <5512D20D.4070709@oracle.com> <55145EBE.7070005@oracle.com> <55157E45.1030204@oracle.com> <55192507.4090704@oracle.com> <551AF091.9060904@oracle.com> <555B7D43.3020802@oracle.com> Message-ID: <555C81AA.8090003@oracle.com> I noticed you have added braces for single line if-statements elsewhere. But here you have src/share/classes/com/sun/java/util/jar/pack/Utils.java + if (tz != null) TimeZone.setDefault(tz); Besides that we are good. Thanks Kumar On 5/19/2015 11:13 AM, mikhail cherkasov wrote: > Hi there, > > I reverted the last change, now test uses native unpacker as before. > But I fixed the test other way, now I warm up native unpacker to make > it initialized on native level before > the main part of test: > http://cr.openjdk.java.net/~mcherkas/8066985/webrev.11/test/tools/pack200/DefaultTimeZoneTest.java.html > > > Thanks, > Mikhail. > > On 3/31/2015 10:08 PM, mikhail cherkasov wrote: >> And one more change in test. >> >> Native packer/unpacker can throw exception during execution, but this >> issue is out of scope of this fix, >> so I just disable it for test: >> >> http://cr.openjdk.java.net/~mcherkas/8066985/webrev.09/test/tools/pack200/DefaultTimeZoneTest.java.html >> >> >> On 3/30/2015 1:27 PM, mikhail cherkasov wrote: >>> >>> On 3/27/2015 6:59 PM, Kumar Srinivasan wrote: >>>> yes that will work!, also why aren't all these final ? >>> fixed: http://cr.openjdk.java.net/~mcherkas/8066985/webrev.08/ >>> >>> >> > From vladimir.x.ivanov at oracle.com Wed May 20 13:03:10 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 20 May 2015 16:03:10 +0300 Subject: [9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared In-Reply-To: <59A05F7D-058A-4A9B-BA65-17A71A57254D@oracle.com> References: <554CEF76.8090903@oracle.com> <554DD477.7000703@gmail.com> <5551DC44.9060902@oracle.com> <5553191F.6080800@oracle.com> <72E25593-3E65-48F6-86D4-75B8E6CB8C6B@oracle.com> <55533CAE.3050201@oracle.com> <55549297.5020002@oracle.com> <5555E343.5050600@oracle.com> <5559E3A5.8030108@oracle.com> <59A05F7D-058A-4A9B-BA65-17A71A57254D@oracle.com> Message-ID: <555C860E.1020508@oracle.com> Paul, Roland, thanks for review. Best regards, Vladimir Ivanov On 5/20/15 3:32 PM, Paul Sandoz wrote: > > On May 20, 2015, at 9:14 AM, Roland Westrelin wrote: > >>> What do you think about the following version: >>> http://cr.openjdk.java.net/~vlivanov/8079205/webrev.04 >> >> Still looks good to me. >> > > And to me. > > Injected fields seem a little magical but safer. > > Paul. > From david.holmes at oracle.com Wed May 20 13:19:22 2015 From: david.holmes at oracle.com (David Holmes) Date: Wed, 20 May 2015 23:19:22 +1000 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork In-Reply-To: <9CAD4D10-35D5-4C04-B19D-6C4D7D57B3CA@oracle.com> References: <555C32C8.90301@oracle.com> <168C61AB-074F-4E36-9297-75E26B10F937@oracle.com> <555C57F8.3020307@oracle.com> <9CAD4D10-35D5-4C04-B19D-6C4D7D57B3CA@oracle.com> Message-ID: <555C89DA.4030709@oracle.com> On 20/05/2015 8:24 PM, Paul Sandoz wrote: > > On May 20, 2015, at 11:46 AM, David Holmes wrote: > >> On 20/05/2015 7:28 PM, Paul Sandoz wrote: >>> >>> On May 20, 2015, at 9:07 AM, David Holmes wrote: >>> >>>> On 20/05/2015 3:55 AM, Paul Sandoz wrote: >>>>> Hi, >>>>> >>>>> https://bugs.openjdk.java.net/browse/JDK-8080623 >>>>> >>>>> diff -r ea3ca5cfc3c6 src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java >>>>> --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 20:04:29 2015 +0300 >>>>> +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Tue May 19 19:54:00 2015 +0200 >>>>> @@ -1328,13 +1328,9 @@ >>>>> /** >>>>> * Number of times to spin-wait before blocking. The spins (in >>>>> * awaitRunStateLock and awaitWork) currently use randomized >>>>> - * spins. If/when MWAIT-like intrinsics becomes available, they >>>>> - * may allow quieter spinning. The value of SPINS must be a power >>>>> - * of two, at least 4. The current value causes spinning for a >>>>> - * small fraction of typical context-switch times, well worthwhile >>>>> - * given the typical likelihoods that blocking is not necessary. >>>>> + * spins. Currently set to zero to reduce CPU usage. >>>> >>>> I'd keep the commentary even if disabling spinning at this time. >>>> >>> >>> Some of removed commentary makes less sense given the motivation to set the value to zero. How about the following tweak: >>> >>> /** >>> * Number of times to spin-wait before blocking. The spins (in >>> * awaitRunStateLock and awaitWork) currently use randomized >>> - * spins. If/when MWAIT-like intrinsics becomes available, they >>> - * may allow quieter spinning. The value of SPINS must be a power >>> - * of two, at least 4. The current value causes spinning for a >>> - * small fraction of typical context-switch times, well worthwhile >>> - * given the typical likelihoods that blocking is not necessary. >>> + * spins. Currently set to zero to reduce CPU usage. >> >> I've lost the context for what "spin" is getting randomized ?? >> > > Not sure there was much context to begin with :-) best to look at the implementation: a spin value, initialized to SPINS, is (if > 0) decremented if the next value from a PRNG (Marsaglia-like) is non-negative. Not sure I grok why we would randomize the spin but ... Thanks, David > > >>> + * >>> + * If greater than zero the value of SPINS must be a power >>> + * of two, at least 4. A value of 2048 causes spinning for a >>> + * small fraction of typical context-switch times. >>> + * >>> + * If/when MWAIT-like intrinsics becomes available, they >>> + * may allow quieter spinning. >> >> Yep that's fine - thanks. >> > > Thanks, > Paul. > From ivan.gerasimov at oracle.com Wed May 20 13:24:14 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 20 May 2015 16:24:14 +0300 Subject: JDK 9 RFR of JDK-8080680: sun/nio/cs/TestCompoundTest.java should be removed from TEST.groups In-Reply-To: <555C67F6.1050700@oracle.com> References: <555C67F6.1050700@oracle.com> Message-ID: <555C8AFE.8000702@oracle.com> Looks good. Sincerely yours, Ivan On 20.05.2015 13:54, Amy Lu wrote: > sun/nio/cs/TestCompoundTest.java > > This test was removed in JDK-8080330, it should also be removed from > TEST.groups > > Please help to review and sponsor this simple patch: > > bug: https://bugs.openjdk.java.net/browse/JDK-8080680 > webrev: http://cr.openjdk.java.net/~amlu/8080680/webrev.00/ > > --- old/test/TEST.groups 2015-05-20 18:48:25.000000000 +0800 > +++ new/test/TEST.groups 2015-05-20 18:48:25.000000000 +0800 > @@ -534,7 +534,6 @@ > sun/nio/cs/OLD/TestIBMDB.java \ > sun/nio/cs/SJISCanEncode.java \ > sun/nio/cs/Test6254467.java \ > - sun/nio/cs/TestCompoundTest.java \ > sun/nio/cs/TestCp834_SBCS.java \ > sun/nio/cs/TestEUC_TW.java \ > sun/nio/cs/TestISO2022CNDecoder.java \ > > Thanks, > Amy > > From vitalyd at gmail.com Wed May 20 13:29:03 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Wed, 20 May 2015 09:29:03 -0400 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork In-Reply-To: <555C89DA.4030709@oracle.com> References: <555C32C8.90301@oracle.com> <168C61AB-074F-4E36-9297-75E26B10F937@oracle.com> <555C57F8.3020307@oracle.com> <9CAD4D10-35D5-4C04-B19D-6C4D7D57B3CA@oracle.com> <555C89DA.4030709@oracle.com> Message-ID: It's to prevent cpu from getting a memory violation hazard when it exits the busy wait. The commentary alludes to having pause instruction available, to notify cpu that the code is busy waiting, but that instruction isn't available. The randomness is to fool branch prediction so as to not have too many instructions out of order in flight when it ultimately breaks out of the loop. sent from my phone On May 20, 2015 9:20 AM, "David Holmes" wrote: > On 20/05/2015 8:24 PM, Paul Sandoz wrote: > >> >> On May 20, 2015, at 11:46 AM, David Holmes >> wrote: >> >> On 20/05/2015 7:28 PM, Paul Sandoz wrote: >>> >>>> >>>> On May 20, 2015, at 9:07 AM, David Holmes >>>> wrote: >>>> >>>> On 20/05/2015 3:55 AM, Paul Sandoz wrote: >>>>> >>>>>> Hi, >>>>>> >>>>>> https://bugs.openjdk.java.net/browse/JDK-8080623 >>>>>> >>>>>> diff -r ea3ca5cfc3c6 >>>>>> src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java >>>>>> --- >>>>>> a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java >>>>>> Tue May 19 20:04:29 2015 +0300 >>>>>> +++ >>>>>> b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java >>>>>> Tue May 19 19:54:00 2015 +0200 >>>>>> @@ -1328,13 +1328,9 @@ >>>>>> /** >>>>>> * Number of times to spin-wait before blocking. The spins (in >>>>>> * awaitRunStateLock and awaitWork) currently use randomized >>>>>> - * spins. If/when MWAIT-like intrinsics becomes available, they >>>>>> - * may allow quieter spinning. The value of SPINS must be a power >>>>>> - * of two, at least 4. The current value causes spinning for a >>>>>> - * small fraction of typical context-switch times, well >>>>>> worthwhile >>>>>> - * given the typical likelihoods that blocking is not necessary. >>>>>> + * spins. Currently set to zero to reduce CPU usage. >>>>>> >>>>> >>>>> I'd keep the commentary even if disabling spinning at this time. >>>>> >>>>> >>>> Some of removed commentary makes less sense given the motivation to set >>>> the value to zero. How about the following tweak: >>>> >>>> /** >>>> * Number of times to spin-wait before blocking. The spins (in >>>> * awaitRunStateLock and awaitWork) currently use randomized >>>> - * spins. If/when MWAIT-like intrinsics becomes available, they >>>> - * may allow quieter spinning. The value of SPINS must be a power >>>> - * of two, at least 4. The current value causes spinning for a >>>> - * small fraction of typical context-switch times, well worthwhile >>>> - * given the typical likelihoods that blocking is not necessary. >>>> + * spins. Currently set to zero to reduce CPU usage. >>>> >>> >>> I've lost the context for what "spin" is getting randomized ?? >>> >>> >> Not sure there was much context to begin with :-) best to look at the >> implementation: a spin value, initialized to SPINS, is (if > 0) decremented >> if the next value from a PRNG (Marsaglia-like) is non-negative. >> > > Not sure I grok why we would randomize the spin but ... > > Thanks, > David > > >> >> + * >>>> + * If greater than zero the value of SPINS must be a power >>>> + * of two, at least 4. A value of 2048 causes spinning for a >>>> + * small fraction of typical context-switch times. >>>> + * >>>> + * If/when MWAIT-like intrinsics becomes available, they >>>> + * may allow quieter spinning. >>>> >>> >>> Yep that's fine - thanks. >>> >>> >> Thanks, >> Paul. >> >> From dl at cs.oswego.edu Wed May 20 13:29:58 2015 From: dl at cs.oswego.edu (Doug Lea) Date: Wed, 20 May 2015 09:29:58 -0400 Subject: RFR 8080623 CPU overhead in FJ due to spinning in awaitWork In-Reply-To: <555C89DA.4030709@oracle.com> References: <555C32C8.90301@oracle.com> <168C61AB-074F-4E36-9297-75E26B10F937@oracle.com> <555C57F8.3020307@oracle.com> <9CAD4D10-35D5-4C04-B19D-6C4D7D57B3CA@oracle.com> <555C89DA.4030709@oracle.com> Message-ID: <555C8C56.1080503@cs.oswego.edu> On 05/20/2015 09:19 AM, David Holmes wrote: >> Not sure there was much context to begin with :-) best to look at the >> implementation: a spin value, initialized to SPINS, is (if > 0) decremented if >> the next value from a PRNG (Marsaglia-like) is non-negative. > > Not sure I grok why we would randomize the spin but ... > To better spread out delays to reduce future contention. It's analogous to randomized back-offs. -Doug From daniel.fuchs at oracle.com Wed May 20 13:30:35 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 20 May 2015 15:30:35 +0200 Subject: RFR [9] 8072839: JAX-B Plugability Layer: using java.util.ServiceLoader In-Reply-To: <55560D2B.3040400@oracle.com> References: <55560D2B.3040400@oracle.com> Message-ID: <555C8C7B.7060801@oracle.com> Hi Miroslav, I haven't looked in all details, but this text in JAXBContext.java looks odd to me - it seems that the bullet is repeated twice (or if they differ - the diff must be subtle): lines 241-257 seem identical to lines 259-275 241 *

  • 242 * Look for resource /META-INF/services/javax.xml.bind.JAXBContext using provided class loader. 243 * Methods without class loader parameter use {@code Thread.currentThread().getContextClassLoader()}. 244 * If such a resource exists, its content is assumed to be the provider factory class and must supply 245 * an implementation class containing the following method signatures: 246 * 247 *
      248  *
      249  * public static JAXBContext createContext(
      250  *                                      String contextPath,
      251  *                                      ClassLoader classLoader,
      252  *                                      Map<String,Object> 
    properties throws JAXBException
      253  *
      254  * public static JAXBContext createContext(
      255  *                                      Class[] classes,
      256  *                                      Map<String,Object> 
    properties ) throws JAXBException
      257  * 
    258 * 259 *
  • 260 * Look for resource /META-INF/services/javax.xml.bind.JAXBContext using provided class loader. 261 * Methods without class loader parameter use {@code Thread.currentThread().getContextClassLoader()}. 262 * If such a resource exists, its content is assumed to be the provider factory class and must supply 263 * an implementation class containing the following method signatures: 264 * 265 *
      266  *
      267  * public static JAXBContext createContext(
      268  *                                      String contextPath,
      269  *                                      ClassLoader classLoader,
      270  *                                      Map<String,Object> 
    properties throws JAXBException
      271  *
      272  * public static JAXBContext createContext(
      273  *                                      Class[] classes,
      274  *                                      Map<String,Object> 
    properties ) throws JAXBException
      275  * 
    So if I understand well - this is somewhat similar to what ServiceLoader does in terms of lookup, except that the mechanism defined here does not use an instance of the declared class, nor require that the class declared in /META-INF/services/javax.xml.bind.JAXBContext is a subclass of JAXBContext - but simply that it defines the appropriate static factory methods... Maybe the fact that this step is deprecated should be noted more prominently in the bullet itself. best regards, -- daniel On 15/05/15 17:13, Miroslav Kos wrote: > Hi everybody, > > this is review request for: 8072839: JAX-B Plugability Layer: using > java.util.ServiceLoader > The JAX-B API changed a little bit - proprietary ServiceLoader-like code > has been replaced by java.util.ServiceLoader. This change is required by > Jigsaw, old configuration way still supported. > > JBS:https://bugs.openjdk.java.net/browse/JDK-8072839 > webrev: http://cr.openjdk.java.net/~mkos/8072839/jaxws.02/index.html > CCC: http://ccc.us.oracle.com/8072839 > > Testing: JAX-WS (standalone) unit tests, no, jtreg tests available now, > TCK/JCK tests will require new tests. > > Thanks > Miran > From Alan.Bateman at oracle.com Wed May 20 14:17:18 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 20 May 2015 15:17:18 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> Message-ID: <555C976E.4050604@oracle.com> On 14/05/2015 09:26, Chris Hegarty wrote: > I think we?ve agreed that we are not going to attempt to re-introduce the problematic interruptible I/O mechanism. These new methods are targeted at specific use-cases and common patterns found in code. I?d like to do a final review of the spec before finalising it. > > http://cr.openjdk.java.net/~chegar/readBytes/webrev.00 I read through the javadoc and it looks good. A passing comment is that the areas of the byte array that aren't touched by readNBytes seems a bit much and a distraction to have it covered in two paragraphs. In @param b then it says "buffer" when I assume it should be "byte array" to be consistent with the method description. -Alan From chris.hegarty at oracle.com Wed May 20 14:33:33 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 20 May 2015 15:33:33 +0100 Subject: RFR [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <555C976E.4050604@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> <555C976E.4050604@oracle.com> Message-ID: <555C9B3D.9000201@oracle.com> On 20/05/15 15:17, Alan Bateman wrote: > On 14/05/2015 09:26, Chris Hegarty wrote: >> I think we?ve agreed that we are not going to attempt to re-introduce >> the problematic interruptible I/O mechanism. These new methods are >> targeted at specific use-cases and common patterns found in code. I?d >> like to do a final review of the spec before finalising it. >> >> http://cr.openjdk.java.net/~chegar/readBytes/webrev.00 > I read through the javadoc and it looks good. Thanks Alan. > A passing comment is that the areas of the byte array that aren't > touched by readNBytes seems a bit much and a distraction to have it > covered in two paragraphs. Roger made the very same comment. I justified the duplication as the paragraphs are covering potentially two different cases. One where some data is read, and the other when no data is read. Given this has some up twice now, I'll just remove the second paragraph. > In @param b then it says "buffer" when I assume it should be "byte > array" to be consistent with the method description. Fixed. Thanks, -Chris. > -Alan > From Roger.Riggs at Oracle.com Wed May 20 16:03:49 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 20 May 2015 12:03:49 -0400 Subject: RFR 9: 8077350 Process API Updates Implementation Review In-Reply-To: <555C4828.5070803@gmail.com> References: <5550CFA1.9010606@Oracle.com> <55535CC7.3000503@Oracle.com> <555492DC.7030707@gmail.com> <5554A6D4.6060902@Oracle.com> <5555CC06.4020507@gmail.com> <555A5E81.8050804@Oracle.com> <555AF5A2.5060205@gmail.com> <555B5B3E.60104@Oracle.com> <555B99DD.7050009@Oracle.com> <555C4828.5070803@gmail.com> Message-ID: <555CB065.20709@Oracle.com> Hi Peter, yes, your patch does reduce the code quite a bit except where the complexity is needed. The commonPool does have a soft limit (256/system property) on the number of compensating processes it will start. That limit would only come into play for subclasses of Process that did not properly override onExit to delegate to the underlying builtin Process implementation. So, probably not a big risk. It might be desirable to put the loop and exception handling inside the ManagedBlocker but the difference is only in the creation of additional inner class instances in the case of InterruptedExceptions. Thanks, Roger On 5/20/2015 4:39 AM, Peter Levart wrote: > Hi Roger, > > I looked at Martin's idea and I think that we don't need the > AsyncExecutor at all (it already sounds like I hate it ;-). Using > ManagedBlocker, a ForkJoinPoll can compensate and grow it's pool as > needed when Process.waitFor() blocks. So we could leverage this > feature and simplify things even further: > > http://cr.openjdk.java.net/~plevart/jdk9-sandbox/JDK-8046092-branch/webrev.03/ > > > Passing a commonPool() to xxxAsync() methods is unneeded as the > default is exactly the same. If CompletableFuture ever gets a feature > to specify a default Executor for all it's descendants, then we can > revisit this if needed. > > What do you think? > > Regards, Peter > > On 05/19/2015 10:15 PM, Roger Riggs wrote: >> The webrev, javadoc, and specdiffs have been updated to address >> recent recommendations: >> >> Please review and comment: >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-ph/ (May 19) >> >> javadoc: >> http://cr.openjdk.java.net/~rriggs/ph-apidraft/ (May 19) >> >> Diffs of the spec/javadoc from previous draft: >> http://cr.openjdk.java.net/~rriggs/ph-diffs-2015-05-19/overview-summary.html >> >> >> Thanks, Roger > From mandy.chung at oracle.com Wed May 20 17:20:34 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 20 May 2015 10:20:34 -0700 Subject: JDK 9 RFR of JDK-8080680: sun/nio/cs/TestCompoundTest.java should be removed from TEST.groups In-Reply-To: <555C67F6.1050700@oracle.com> References: <555C67F6.1050700@oracle.com> Message-ID: <8C6E43C9-2527-47F3-A858-18DD67E5E71B@oracle.com> Looks good. Mandy > On May 20, 2015, at 3:54 AM, Amy Lu wrote: > > sun/nio/cs/TestCompoundTest.java > > This test was removed in JDK-8080330, it should also be removed from TEST.groups > > Please help to review and sponsor this simple patch: > > bug: https://bugs.openjdk.java.net/browse/JDK-8080680 > webrev: http://cr.openjdk.java.net/~amlu/8080680/webrev.00/ > > --- old/test/TEST.groups 2015-05-20 18:48:25.000000000 +0800 > +++ new/test/TEST.groups 2015-05-20 18:48:25.000000000 +0800 > @@ -534,7 +534,6 @@ > sun/nio/cs/OLD/TestIBMDB.java \ > sun/nio/cs/SJISCanEncode.java \ > sun/nio/cs/Test6254467.java \ > - sun/nio/cs/TestCompoundTest.java \ > sun/nio/cs/TestCp834_SBCS.java \ > sun/nio/cs/TestEUC_TW.java \ > sun/nio/cs/TestISO2022CNDecoder.java \ > > Thanks, > Amy From ivan.gerasimov at oracle.com Wed May 20 17:32:16 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 20 May 2015 20:32:16 +0300 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: <6E1D96B2-8A0C-4CDF-91D1-1E8DE0916A95@oracle.com> References: <555B91B9.80204@oracle.com> <6E1D96B2-8A0C-4CDF-91D1-1E8DE0916A95@oracle.com> Message-ID: <555CC520.2070401@oracle.com> On 20.05.2015 12:04, Paul Sandoz wrote: > On May 19, 2015, at 9:40 PM, Ivan Gerasimov wrote: > >> Hi everyone! >> >> What about this variant: >> http://cr.openjdk.java.net/~igerasim/8080535/02/webrev/ >> > 45 int mapSize = map.size(); > > Not used. > > > 49 int INITIAL_CAPACITY = 680; //(int)(510 / 0.75f + 1.0f); > > Change to lower case. Thanks, will fix both. > > Just had an idea... I believe static intializers are executed in textual order. So you could have a static code block after all static UnicodeBlock instances have been defined that asserts the size == 510 (or is <= 1024 * 0.75). In that case i would argue a static final representing the expected size is justified. > > Then your test can derive the initial capacity from mapSize. I've just checked www.unicode.org to see how many new entries we can expect in the nearest future. Unicode 7 will add 32 new blocks (96 with aliases): http://www.unicode.org/versions/Unicode7.0.0/ Unicode 8 will add 10 more blocks (30 with aliases): http://www.unicode.org/versions/beta-8.0.0.html So, after implementing Unicode 7 and 8 in java we're going to have 510+96+30 = 636 entries in the map. The internal array of size 1024 (as it will be, if (510/.75 + 1) is used for the initial capacity), is going to be sufficient to hold all these. So, I think we're going to be good for a few next years. And once the number of entries exceeds 768, the resgression test will warn us. Here's the update with the corrections to the test as you suggested: http://cr.openjdk.java.net/~igerasim/8080535/03/webrev/ Sincerely yours, Ivan > Paul. > >> No named constant. >> A comment in the code about initial capacity. >> In the test, we use the same constant to check if it were sufficient to hold the final number of entries. >> >> If someone evil shrinks the initial capacity in the code, the test will not be able to detect it, though it seems unlikely. >> >> // Please ignore the change to test/TEST.groups in the webrev; it is a leftover from a fix for JDK-8080330 >> >> Sincerely yours, >> Ivan >> > > From xueming.shen at oracle.com Wed May 20 17:57:15 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 20 May 2015 10:57:15 -0700 Subject: RFR 8080640: Reduce copying when reading JAR/ZIP entries In-Reply-To: <555A957F.5010102@oracle.com> References: <555A957F.5010102@oracle.com> Message-ID: <555CCAFB.4090805@oracle.com> On 05/18/2015 06:44 PM, Staffan Friberg wrote: > Hi, > > Wanted to get reviews and feedback on this performance improvement for reading from JAR/ZIP files during classloading by reducing unnecessary copying and reading the entry in one go instead of in small portions. This shows a significant improvement when reading a single entry and for a large application with 10k classes and 500+ JAR files it improved the startup time by 4%. > > For more details on the background and performance results please see the RFE entry. > > RFE - https://bugs.openjdk.java.net/browse/JDK-8080640 > WEBREV - http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.0 > > Cheers, > Staffan Hi Staffan, If I did not miss something here, from your use scenario it appears to me the only thing you really need here to help boost your performance is byte[] ZipFile.getAllBytes(ZipEntry ze); You are allocating a byte[] at use side and wrapping it with a ByteBuffer if the size is small enough, otherwise, you letting the ZipFile to allocate a big enough one for you. It does not look like you can re-use that byte[] (has to be wrapped by the ByteArrayInputStream and return), why do you need two different methods here? The logic would be much easier to simply let the ZipFile to allocate the needed buffer with appropriate size, fill the bytes and return, with a "OOME" if the entry size is bigger than 2g. The only thing we use from the input ze is its name, get the size/csize from the jzentry, I don't think jzentry.csize/size can be "unknown", they are from the "cen" table. If the real/final use of the bytes is to wrap it with a ByteArrayInputStream,why bother using ByteBuffer here? Shouldn't a direct byte[] with exactly the size of the entry server better. -Sherman From martinrb at google.com Wed May 20 19:57:21 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 20 May 2015 12:57:21 -0700 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: <555CC520.2070401@oracle.com> References: <555B91B9.80204@oracle.com> <6E1D96B2-8A0C-4CDF-91D1-1E8DE0916A95@oracle.com> <555CC520.2070401@oracle.com> Message-ID: I'd like to contribute (the start of) a test that checks that static HashMaps are not oversized. I suggest using that consistently for static HashMaps (and ArrayLists?) throughout the JDK: import java.lang.reflect.*; import java.util.*; @SuppressWarnings({"unchecked", "rawtypes"}) public class StaticMapSize { static int tableLength(HashMap map) throws Throwable { Field tableField = HashMap.class.getDeclaredField("table"); tableField.setAccessible(true); return ((Object[]) tableField.get(map)).length; } public static void main(String[] args) throws Throwable { Class[] klazzes = Class.forName("java.lang.Character").getDeclaredClasses(); for (Class klazz : klazzes) { for (Field field : klazz.getDeclaredFields()) { field.setAccessible(true); if (Modifier.isStatic(field.getModifiers())) { Object x = field.get(null); if (x instanceof HashMap) { System.out.println(field); HashMap map = (HashMap) x; HashMap copy = new HashMap(map); if (tableLength(map) != tableLength(copy)) { String msg = String.format ("map %s has excess capacity: need %d; use %d%n", field.toString(), tableLength(copy), tableLength(map)); throw new AssertionError(msg); } } } } } } } From mandy.chung at oracle.com Wed May 20 23:07:21 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 20 May 2015 16:07:21 -0700 Subject: RFR(M, v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <555C2EEB.1050505@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> Message-ID: <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> > On May 19, 2015, at 11:51 PM, Dmitry Samersoff wrote: > > Other alternatives could be to do all hashing/sorting/printing on native > layer i.e. implement printFinalizationQueue inside VM. > > Both options has pros and cons - Java based solution requires less JNI > calls and better readable but takes more memory. > > It might be better to return an array of Map.Entry > objects to VM rather than one huge string. The output and formatting should be done by jcmd. What you really need to get a peek on the finalizer queue and print the histogram. The VM has the heap histogram implementation. Have you considered leveraging that? 5: 1012 40480 java.lang.ref.Finalizer You can find the registered Finalizer instances. The downside is that icmd -finalizerinfo stops the world. I think it?s not unreasonable for this diagnostic command to be expensive like -heap command. Mandy From mandy.chung at oracle.com Thu May 21 00:09:12 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 20 May 2015 17:09:12 -0700 Subject: RFR: 8080608: Missing archive name from jdeps -v -e output if no dependency on other JAR In-Reply-To: <555C5D4B.6080503@oracle.com> References: <555B6CC0.5070000@oracle.com> <555BCAD8.1080500@oracle.com> <555C5D4B.6080503@oracle.com> Message-ID: <98BC6E6B-5E66-4931-955B-02A94F5A3533@oracle.com> > On May 20, 2015, at 3:09 AM, Daniel Fuchs wrote: > > On 20/05/15 01:44, Mandy Chung wrote: >> >> A dependency from unsafe.jar to itself is redundant and thus was >> excluded from the returned value of the requires method. Maybe better >> just to output without any dependence like this: >> >> unsafe.jar >> use.unsafe.UseClassWithUnsafe -> use.unsafe.UseUnsafeClass unsafe.jar > > I'm not sure it's redundant because the dependency written > > -> > > This is the only place were the path to the archive appears - and > I believe it's good to keep it (+ it makes the output more regular > and thus easier to parse with simple greps etc?). Good point. Let?s keep the dependency output consistent format. > >> >> Analyzer.java >> >> 147 if (result.requires.isEmpty() && type == Type.VERBOSE && >> hasDependences(source)) { >> Is type == Type.VERBOSE necessary? If hasDependences(source) >> returns true, >> "unsafe.jar" is missing for non-verbose mode I assume. > > Yes - for summary mode, having a line that tells you > unsafe.jar -> dist/unsafe.jar > and nothing else is not very helpful. > > Actually - I think the test should be type != Type.SUMMARY rather > than type == Type.VERBOSE. jdeps has -filter:none option. $ jdeps -s -filter:none -e use.unsafe.UseUnsafeClass *.jar When -filter:none is used, I think it?s right for the summary page should include unsafe.jar in that case. The default will filter out same package dependency and hasDependency returns false in that case. > > > New webrev: > http://cr.openjdk.java.net/~dfuchs/webrev_8080608/webrev.01/ Analyzer.java looks good except that I think it doesn?t need type != Type.SUMMARY check. Thanks for adding the great tests. The test can be extracted as a jdeps test library. Do you have the cycle to refactor it so that it can be used in future jdeps tests? TestCaseData now takes 3 String[][] to list classes, dependencies and archives. You can consider making it a jdeps data Builder that will make the data more explicit expected dependencies of each class. Can you run all test cases in the same VM? The test calls com.sun.tools.jdeps.Main directly and it?d be good to avoid running each test case as a separate VM unless it?s necessary. Can you also add @modules jdk.dev/com.sun.tools.jdeps following @summary as it uses internal API. Mandy From mandy.chung at oracle.com Thu May 21 00:57:23 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 20 May 2015 17:57:23 -0700 Subject: Review Request: 8080815: Update 8u jdeps list of internal APIs Message-ID: <0FCB7135-B53C-4B57-9480-610A7C437BE4@oracle.com> This is 8u only fix. https://bugs.openjdk.java.net/browse/JDK-8080815 Webrev: http://cr.openjdk.java.net/~mchung/jdk8u/webrevs/8080815/webrev.00/ jdeps in 8u has to special case a few org.w3c.dom.* packages and javafx.* packages as exported APIs. JDK 9 jdeps looks at the module definition to determine the exported APIs and handles that properly. thanks Mandy From daniel.fuchs at oracle.com Thu May 21 08:28:11 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Thu, 21 May 2015 10:28:11 +0200 Subject: Review Request: 8080815: Update 8u jdeps list of internal APIs In-Reply-To: <0FCB7135-B53C-4B57-9480-610A7C437BE4@oracle.com> References: <0FCB7135-B53C-4B57-9480-610A7C437BE4@oracle.com> Message-ID: <555D971B.20107@oracle.com> On 21/05/15 02:57, Mandy Chung wrote: > This is 8u only fix. > https://bugs.openjdk.java.net/browse/JDK-8080815 > > Webrev: > http://cr.openjdk.java.net/~mchung/jdk8u/webrevs/8080815/webrev.00/ > > jdeps in 8u has to special case a few org.w3c.dom.* packages and javafx.* packages as exported APIs. JDK 9 jdeps looks at the module definition to determine the exported APIs and handles that properly. > > thanks > Mandy > Hi Mandy, The changes in the code look reasonable to me. I haven't looked too much at the test changes - but I didn't see anything surprising there either. best regards, -- daniel From paul.sandoz at oracle.com Thu May 21 08:51:50 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 21 May 2015 10:51:50 +0200 Subject: RFR (XXS) 8080535: (ch) Expected size of Character.UnicodeBlock.map is not optimal In-Reply-To: <555CC520.2070401@oracle.com> References: <555B91B9.80204@oracle.com> <6E1D96B2-8A0C-4CDF-91D1-1E8DE0916A95@oracle.com> <555CC520.2070401@oracle.com> Message-ID: <02B39CB7-ADBA-47C4-AE49-88AA844D11D7@oracle.com> On May 20, 2015, at 7:32 PM, Ivan Gerasimov wrote: >> Just had an idea... I believe static intializers are executed in textual order. So you could have a static code block after all static UnicodeBlock instances have been defined that asserts the size == 510 (or is <= 1024 * 0.75). In that case i would argue a static final representing the expected size is justified. >> Then your test can derive the initial capacity from mapSize. > > I've just checked www.unicode.org to see how many new entries we can expect in the nearest future. > Unicode 7 will add 32 new blocks (96 with aliases): http://www.unicode.org/versions/Unicode7.0.0/ > Unicode 8 will add 10 more blocks (30 with aliases): http://www.unicode.org/versions/beta-8.0.0.html > > So, after implementing Unicode 7 and 8 in java we're going to have 510+96+30 = 636 entries in the map. > The internal array of size 1024 (as it will be, if (510/.75 + 1) is used for the initial capacity), is going to be sufficient to hold all these. > Nice investigation. What you have written above would be useful in a comment on the map. Paul. > So, I think we're going to be good for a few next years. > And once the number of entries exceeds 768, the resgression test will warn us. > > > Here's the update with the corrections to the test as you suggested: > http://cr.openjdk.java.net/~igerasim/8080535/03/webrev/ > > Sincerely yours, > Ivan From Alan.Bateman at oracle.com Thu May 21 12:34:23 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 21 May 2015 13:34:23 +0100 Subject: RFR [9] 8080502: Changing accessing module resources In-Reply-To: <555B04AE.8040009@oracle.com> References: <555B04AE.8040009@oracle.com> Message-ID: <555DD0CF.8060407@oracle.com> On 19/05/2015 10:38, Miroslav Kos wrote: > : > > JBS: https://bugs.openjdk.java.net/browse/JDK-8080502 > webrev: http://cr.openjdk.java.net/~mkos/8080502/jaxws.01/index.html > testing: JAX-WS unit test; basically it is fix for existing tests > (JCK, ...) One thing that isn't obvious in this code is where the input streams are closed? Are they closed by whoever is consuming the input stream? Otherwise I don't see any issues. -Alan From daniel.fuchs at oracle.com Thu May 21 14:25:26 2015 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Thu, 21 May 2015 16:25:26 +0200 Subject: RFR: 8080608: Missing archive name from jdeps -v -e output if no dependency on other JAR In-Reply-To: <98BC6E6B-5E66-4931-955B-02A94F5A3533@oracle.com> References: <555B6CC0.5070000@oracle.com> <555BCAD8.1080500@oracle.com> <555C5D4B.6080503@oracle.com> <98BC6E6B-5E66-4931-955B-02A94F5A3533@oracle.com> Message-ID: <555DEAD6.4010408@oracle.com> On 21/05/15 02:09, Mandy Chung wrote: >> Actually - I think the test should be type != Type.SUMMARY rather >> than type == Type.VERBOSE. > > jdeps has -filter:none option. > > $ jdeps -s -filter:none -e use.unsafe.UseUnsafeClass *.jar > > When -filter:none is used, I think it?s right for the summary page > should include unsafe.jar in that case. The default will filter out > same package dependency and hasDependency returns false in that case. Ah - I understand your point now. >> New webrev: >> http://cr.openjdk.java.net/~dfuchs/webrev_8080608/webrev.01/ > > > Analyzer.java looks good except that I think it doesn?t need type != > Type.SUMMARY check. OK done. > Thanks for adding the great tests. The test can be extracted as a jdeps > test library. Do you have the cycle to refactor it so that it can be > used in future jdeps tests? Maybe we should wait a bit and see what is generic enough to be extracted. There are a few things that the test expects and which are verified by the inputs & classes to be analyzed. For instance - the pattern given to -e must match only one class name. The test depends on this. > TestCaseData now takes 3 String[][] to list classes, dependencies and > archives. You can consider making it a jdeps data Builder that will > make the data more explicit expected dependencies of each class. OK - Let's consider doing this when we extract the test to put in the library. In the mean time I have added some javadoc comments to the static TestCaseData.make() method which should hopefully better clarify what the String[][] arrays should contain. > Can you run all test cases in the same VM? The test calls > com.sun.tools.jdeps.Main directly and it?d be good to avoid running each > test case as a separate VM unless it?s necessary. Done. I lazily used /othervm at first because I was resetting the default locale to Locale.ENGLISH to make sure we get a canonical output. I have now added a runWithLocale method that should make it possible to run the test in same VM mode. > Can you also add > @modules jdk.dev/com.sun.tools.jdeps following @summary as it uses > internal API. done. http://cr.openjdk.java.net/~dfuchs/webrev_8080608/webrev.02/ best regards, -- daniel > > Mandy > From ivan.gerasimov at oracle.com Thu May 21 16:04:14 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 21 May 2015 19:04:14 +0300 Subject: RFR: 7011441: ./jndi/ldap/Connection.java needs to avoid spurious wakeup Message-ID: <555E01FE.9070009@oracle.com> Hello! This is a simple fix, which should prevent from early timeout in sun.jndi.ldap.Connection.readReply(). Would you please help review it? BUG: https://bugs.openjdk.java.net/browse/JDK-7011441 WEBREV: http://cr.openjdk.java.net/~igerasim/7011441/00/webrev/ Sincerely yours, Ivan From paul.sandoz at oracle.com Thu May 21 16:42:31 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 21 May 2015 18:42:31 +0200 Subject: Patch to improve primitives Array.sort() In-Reply-To: <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> Message-ID: <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> Hi, I finally got some time to better understand the patch and more generally this area of code. I applied the patch and ran the existing sorting test [1] for both short and long runs and there was no issue. SortingPrimitiveTest -- I think this test should be placed under java/util/Arrays directory and renamed to better indicate that it's aim is to test partially sorted arrays. There is probably some overlap with the existing sorting test, which is quite complicated and it might be tricky to merge in. I cannot say if the new test is redundant without looking more closely at the data sets and code coverage results, but i am ok with this additional test. DualPivotQuicksort -- 118 for (int k = left; k <= right; run[count] = k) { 119 while (k < right && a[k] == a[++k]); //Equal items in the beginning of the sequence 120 k--; 121 if (run[count] < k || a[k] < a[k + 1]) { // ascending 122 while (++k <= right && a[k - 1] <= a[k]); That first condition at line 121 ("run[count] < k") threw me for a bit, it's a rather sneaky way of incrementing k and continuing through the loop. I am wondering if we can make checking of equal runs a little clearer (k is incremented, decremented then incremented again). What if we could do: for (int k = left; k < right; run[count] = k) { while (k < right && a[k] == a[k + 1]) k++; if (k == right) break; if (a[k] < a[k + 1]) { // ascending If i have that correct right i believe it will allow for a run of equals+ascending or equals+descending. Since a descending+equals run results in the swapping of elements to transform into an equals+ascending run, then it seems ok to transform a equals+descending run into an ascending+equals. That requires a slight tweak after the main loop since the count can be zero if all elements are equal: if (run[count] == right++) { run[++count] = right; } if (count <= 1) { // The array is already sorted return; } I ran the long run version of sorting test against such changes and it passed. I dunno if i have perturbed the performance though... Paul. [1] http://hg.openjdk.java.net/jdk9/dev/jdk/file/72fdb709f356/test/java/util/Arrays/Sorting.java On May 19, 2015, at 10:48 AM, "Chan, Sunny" wrote: > An updated patch has been published to cr.openjdk via Paul: http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.2/ > > Updates: > The testcase has been updated to clone the array > The redundant constant MAX_RUN_LENGTH has been removed. > > From: Paul Sandoz [mailto:paul.sandoz at oracle.com] > Sent: 16 May 2015 00:13 > To: Chan, Sunny [Tech] > Cc: O'Leary, Kristen [Tech]; 'Alan Bateman'; 'core-libs-dev at openjdk.java.net'; Rezaei, Mohammad A. [Tech] > Subject: Re: Patch to improve primitives Array.sort() > > > On May 15, 2015, at 11:48 AM, "Chan, Sunny" wrote: > > > I have provided Paul with an updated patch: > > > Here it is: > > http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.1/ > > In DualPivotQuicksort > > 63 /** > 64 * The maximum length of run in merge sort. > 65 */ > 66 private static final int MAX_RUN_LENGTH = 33; > You can remove this constant. > > > > * The test has been updated using data provider and reduce as much repetition as possible. > > Looking much better. Convention-wise if you don't have to deal with any check exceptions using a Supplier is more preferable to Callable. Up to you. > > 56 @Test(dataProvider = "arrays") > 57 public void runTests(String testName, Callable dataMethod) throws Exception > 58 { > 59 int[] array = dataMethod.call(); > 60 this.sortAndAssert(array); > 61 this.sortAndAssert(this.floatCopyFromInt(array)); > 62 this.sortAndAssert(this.doubleCopyFromInt(array)); > 63 this.sortAndAssert(this.longCopyFromInt(array)); > 64 this.sortAndAssert(this.shortCopyFromInt(array)); > 65 this.sortAndAssert(this.charCopyFromInt(array)); > > At line 60 should you clone the array? otherwise, if i have looked correctly, that sorted result will be tested for other values. > > > > * The GS copyright notice from the main JDK patch. However we retain it on our test cases as we developed ourselves. In our previous contributions where we provided new tests we have put our copyright along with oracle copyright and it was accepted (see:http://hg.openjdk.java.net/jdk9/dev/jdk/file/ed94f3e7ba6b/test/java/lang/instrument/DaemonThread/TestDaemonThread.java) > > Ok. It was more query on my part. I believe it's ok for you to add copyright on both files if you wish. > > > > * Alan has commented that there were older benchmark but searching through the archive I can see it mention "BentleyBasher" I cannot find the actual code that Vladimir used (thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2009-September/002633.html). Is there anywhere I can get hold of it? > > > I tried looking, but i cannot find any. > > Paul. From staffan.friberg at oracle.com Thu May 21 16:48:34 2015 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Thu, 21 May 2015 09:48:34 -0700 Subject: RFR 8080640: Reduce copying when reading JAR/ZIP entries In-Reply-To: <555CCAFB.4090805@oracle.com> References: <555A957F.5010102@oracle.com> <555CCAFB.4090805@oracle.com> Message-ID: <555E0C62.9090406@oracle.com> On 05/20/2015 10:57 AM, Xueming Shen wrote: > On 05/18/2015 06:44 PM, Staffan Friberg wrote: >> Hi, >> >> Wanted to get reviews and feedback on this performance improvement >> for reading from JAR/ZIP files during classloading by reducing >> unnecessary copying and reading the entry in one go instead of in >> small portions. This shows a significant improvement when reading a >> single entry and for a large application with 10k classes and 500+ >> JAR files it improved the startup time by 4%. >> >> For more details on the background and performance results please see >> the RFE entry. >> >> RFE - https://bugs.openjdk.java.net/browse/JDK-8080640 >> WEBREV - http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.0 >> >> Cheers, >> Staffan > > Hi Staffan, > > If I did not miss something here, from your use scenario it appears to > me the only thing you really > need here to help boost your performance is > > byte[] ZipFile.getAllBytes(ZipEntry ze); > > You are allocating a byte[] at use side and wrapping it with a > ByteBuffer if the size is small enough, > otherwise, you letting the ZipFile to allocate a big enough one for > you. It does not look like you > can re-use that byte[] (has to be wrapped by the ByteArrayInputStream > and return), why do you > need two different methods here? The logic would be much easier to > simply let the ZipFile to allocate > the needed buffer with appropriate size, fill the bytes and return, > with a "OOME" if the entry size > is bigger than 2g. > > The only thing we use from the input ze is its name, get the > size/csize from the jzentry, I don't think > jzentry.csize/size can be "unknown", they are from the "cen" table. > > If the real/final use of the bytes is to wrap it with a > ByteArrayInputStream,why bother using ByteBuffer > here? Shouldn't a direct byte[] with exactly the size of the entry > server better. > > -Sherman > Hi Sherman, Thanks for the comments. I agree, was starting out with bytebuffer because I was hoping to be able to cache things where the buffer was being used, but since the buffer is past along further I couldn't figure out a clean way to do it. Will rewrite it to simply just return a buffer, and only wrap it in the Resource class getByteBuffer. What would be your thought on updating the ZipFile.getInputStream to return ByteArrayInputStream for small entries? Currently I do that work outside in two places and moving it would potentially speed up others reading small entries as well. Thanks, Staffan From mandy.chung at oracle.com Thu May 21 17:50:33 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Thu, 21 May 2015 10:50:33 -0700 Subject: RFR: 8080608: Missing archive name from jdeps -v -e output if no dependency on other JAR In-Reply-To: <555DEAD6.4010408@oracle.com> References: <555B6CC0.5070000@oracle.com> <555BCAD8.1080500@oracle.com> <555C5D4B.6080503@oracle.com> <98BC6E6B-5E66-4931-955B-02A94F5A3533@oracle.com> <555DEAD6.4010408@oracle.com> Message-ID: <555E1AE9.9010006@oracle.com> On 05/21/2015 07:25 AM, Daniel Fuchs wrote: > > http://cr.openjdk.java.net/~dfuchs/webrev_8080608/webrev.02/ Looks good. It's fine to consider refactoring out the test library later on. Thanks Mandy From staffan.friberg at oracle.com Thu May 21 18:00:41 2015 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Thu, 21 May 2015 11:00:41 -0700 Subject: RFR 8080640: Reduce copying when reading JAR/ZIP entries In-Reply-To: <555E0C62.9090406@oracle.com> References: <555A957F.5010102@oracle.com> <555CCAFB.4090805@oracle.com> <555E0C62.9090406@oracle.com> Message-ID: <555E1D49.9000707@oracle.com> On 05/21/2015 09:48 AM, Staffan Friberg wrote: > > On 05/20/2015 10:57 AM, Xueming Shen wrote: >> On 05/18/2015 06:44 PM, Staffan Friberg wrote: >>> Hi, >>> >>> Wanted to get reviews and feedback on this performance improvement >>> for reading from JAR/ZIP files during classloading by reducing >>> unnecessary copying and reading the entry in one go instead of in >>> small portions. This shows a significant improvement when reading a >>> single entry and for a large application with 10k classes and 500+ >>> JAR files it improved the startup time by 4%. >>> >>> For more details on the background and performance results please >>> see the RFE entry. >>> >>> RFE - https://bugs.openjdk.java.net/browse/JDK-8080640 >>> WEBREV - http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.0 >>> >>> Cheers, >>> Staffan >> >> Hi Staffan, >> >> If I did not miss something here, from your use scenario it appears >> to me the only thing you really >> need here to help boost your performance is >> >> byte[] ZipFile.getAllBytes(ZipEntry ze); >> >> You are allocating a byte[] at use side and wrapping it with a >> ByteBuffer if the size is small enough, >> otherwise, you letting the ZipFile to allocate a big enough one for >> you. It does not look like you >> can re-use that byte[] (has to be wrapped by the ByteArrayInputStream >> and return), why do you >> need two different methods here? The logic would be much easier to >> simply let the ZipFile to allocate >> the needed buffer with appropriate size, fill the bytes and return, >> with a "OOME" if the entry size >> is bigger than 2g. >> >> The only thing we use from the input ze is its name, get the >> size/csize from the jzentry, I don't think >> jzentry.csize/size can be "unknown", they are from the "cen" table. >> >> If the real/final use of the bytes is to wrap it with a >> ByteArrayInputStream,why bother using ByteBuffer >> here? Shouldn't a direct byte[] with exactly the size of the entry >> server better. >> >> -Sherman >> > Hi Sherman, > > Thanks for the comments. I agree, was starting out with bytebuffer > because I was hoping to be able to cache things where the buffer was > being used, but since the buffer is past along further I couldn't > figure out a clean way to do it. > Will rewrite it to simply just return a buffer, and only wrap it in > the Resource class getByteBuffer. > > What would be your thought on updating the ZipFile.getInputStream to > return ByteArrayInputStream for small entries? Currently I do that > work outside in two places and moving it would potentially speed up > others reading small entries as well. > > Thanks, > Staffan Just realized that my use of ByteArrayInputStream would miss Jar verification if enabled so the way to go hear would be to add it if possible to the ZipFile.getInputStream. //Staffan From xueming.shen at oracle.com Thu May 21 19:51:43 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 21 May 2015 12:51:43 -0700 Subject: RFR: JDK-8080248 Coding regression in HKSCS charsets Message-ID: <555E374F.1030501@oracle.com> Hi Martin, Would you please help review this change ? Issue: https://bugs.openjdk.java.net/browse/JDK-8080248 webrev: http://cr.openjdk.java.net/~sherman/8080248/ Thanks! -Sherman From Roger.Riggs at Oracle.com Thu May 21 21:09:48 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 21 May 2015 17:09:48 -0400 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava Message-ID: <555E499C.6020300@Oracle.com> Please review these native code and build changes to clear compilation warnings. Most are due to mixing unsigned types with signed types or providing the correct type to an invoked function. Webrev: http://bussund0416.us.oracle.com/~rriggs/webrev/webrev-fix-all-warnings-8074818/ Issues: 8074818: Resolve disabled warnings for libjava 8080007: Stop ignoring warnings for libjava JPRT in progress for product and fastdebug builds on solaris, linux, macosx, windows, and embedded. Thanks, Roger From martinrb at google.com Thu May 21 21:46:47 2015 From: martinrb at google.com (Martin Buchholz) Date: Thu, 21 May 2015 14:46:47 -0700 Subject: RFR: JDK-8080248 Coding regression in HKSCS charsets In-Reply-To: <555E374F.1030501@oracle.com> References: <555E374F.1030501@oracle.com> Message-ID: Looks good! I might add another sweeping random-based test to FindEncoderBugs like this: try to encode A + B where A and B are randomly chosen single chars or surrogate pairs, and check that encode(A + B) == encode(A) + encode(B) On Thu, May 21, 2015 at 12:51 PM, Xueming Shen wrote: > Hi Martin, > > Would you please help review this change ? > > Issue: https://bugs.openjdk.java.net/browse/JDK-8080248 > webrev: http://cr.openjdk.java.net/~sherman/8080248/ > > Thanks! > -Sherman > From mark.reinhold at oracle.com Thu May 21 22:29:02 2015 From: mark.reinhold at oracle.com (mark.reinhold at oracle.com) Date: Thu, 21 May 2015 15:29:02 -0700 (PDT) Subject: JEP 255: Merge Selected Xerces 2.11.0 Updates into JAXP Message-ID: <20150521222902.C58BD63B7F@eggemoggin.niobe.net> New JEP Candidate: http://openjdk.java.net/jeps/255 - Mark From joe.darcy at oracle.com Thu May 21 22:57:36 2015 From: joe.darcy at oracle.com (joe darcy) Date: Thu, 21 May 2015 15:57:36 -0700 Subject: JDK 9 RFR of JDK-8080901: Replace package.html files with package-info.java in the java.base module Message-ID: <555E62E0.5070000@oracle.com> Hello, Please review these changes to replace old-style package.html files with package-info.java files in the base module: JDK-8080901: Replace package.html files with package-info.java in the java.base module http://cr.openjdk.java.net/~darcy/8080901.0/ (The package.html file for src/java.base/share/classes/sun/reflect is just removed rather than replaced since it contains "new" porting information that was current as of 2001.) Thanks, -Joe From Lance.Andersen at oracle.com Thu May 21 23:11:37 2015 From: Lance.Andersen at oracle.com (Lance Andersen) Date: Thu, 21 May 2015 19:11:37 -0400 Subject: JDK 9 RFR of JDK-8080901: Replace package.html files with package-info.java in the java.base module In-Reply-To: <555E62E0.5070000@oracle.com> References: <555E62E0.5070000@oracle.com> Message-ID: <64F19C34-A3FF-482E-ADC6-1F43A72D2F3F@oracle.com> Hi Joe, I think this is OK. Best Lance On May 21, 2015, at 6:57 PM, joe darcy wrote: > Hello, > > Please review these changes to replace old-style package.html files with package-info.java files in the base module: > > JDK-8080901: Replace package.html files with package-info.java in the java.base module > http://cr.openjdk.java.net/~darcy/8080901.0/ > > (The package.html file for src/java.base/share/classes/sun/reflect is just removed rather than replaced since it contains "new" porting information that was current as of 2001.) > > Thanks, > > -Joe Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From xueming.shen at oracle.com Thu May 21 23:24:46 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 21 May 2015 16:24:46 -0700 Subject: RFR: 8080803: sun/nio/cs/FindEncoderBugs.java failing intermittently Message-ID: <555E693E.8020609@oracle.com> Martin, Alan, Joe, Would you please help review the change (as a workaround) for this "intermittently" problem? https://bugs.openjdk.java.net/browse/JDK-8080803 http://cr.openjdk.java.net/~sherman/8080803 It appears the trigger might be that ByteBuffer.get(byte[]) fails to get the bytes from the buffer "intermittently". Interestingly this one is always reproducible on my local linux build (very old os), in which I have to update couple hotspot headfile to make the build going recently. I filed the bug#8080904 to let the vm guy take a look. Meanwhile the proposed change here is just to "optimized" the ISO2022 code a little to simple workaround this issue. I hope this can make the "intermittent failure" go away in our nightly build. If have time, we definitely should re-visit the implementation of these ISO2022 :-) Thanks, -Sherman From Mohammad.Rezaei at gs.com Thu May 21 23:52:43 2015 From: Mohammad.Rezaei at gs.com (Rezaei, Mohammad A.) Date: Thu, 21 May 2015 19:52:43 -0400 Subject: Patch to improve primitives Array.sort() In-Reply-To: <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> Message-ID: <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> Thanks Paul. Your proposed changes make sense to us and they have no discernable impact on the performance. Thanks Moh >-----Original Message----- >From: Paul Sandoz [mailto:paul.sandoz at oracle.com] >Sent: Thursday, May 21, 2015 12:43 PM >To: core-libs-dev at openjdk.java.net Libs >Cc: Chan, Sunny [Tech]; O'Leary, Kristen [Tech]; Rezaei, Mohammad A. [Tech] >Subject: Re: Patch to improve primitives Array.sort() > >Hi, > >I finally got some time to better understand the patch and more generally this >area of code. > >I applied the patch and ran the existing sorting test [1] for both short and >long runs and there was no issue. > >SortingPrimitiveTest >-- > >I think this test should be placed under java/util/Arrays directory and >renamed to better indicate that it's aim is to test partially sorted arrays. >There is probably some overlap with the existing sorting test, which is quite >complicated and it might be tricky to merge in. I cannot say if the new test >is redundant without looking more closely at the data sets and code coverage >results, but i am ok with this additional test. > > >DualPivotQuicksort >-- > > 118 for (int k = left; k <= right; run[count] = k) { > 119 while (k < right && a[k] == a[++k]); //Equal items in the >beginning of the sequence > 120 k--; > 121 if (run[count] < k || a[k] < a[k + 1]) { // ascending > 122 while (++k <= right && a[k - 1] <= a[k]); > >That first condition at line 121 ("run[count] < k") threw me for a bit, it's a >rather sneaky way of incrementing k and continuing through the loop. > >I am wondering if we can make checking of equal runs a little clearer (k is >incremented, decremented then incremented again). What if we could do: > >for (int k = left; k < right; run[count] = k) { > while (k < right && a[k] == a[k + 1]) > k++; > if (k == right) break; > if (a[k] < a[k + 1]) { // ascending > >If i have that correct right i believe it will allow for a run of >equals+ascending or equals+descending. > >Since a descending+equals run results in the swapping of elements to transform >into an equals+ascending run, then it seems ok to transform a >equals+descending run into an ascending+equals. > >That requires a slight tweak after the main loop since the count can be zero >if all elements are equal: > >if (run[count] == right++) { > run[++count] = right; >} if (count <= 1) { // The array is already sorted > return; >} > >I ran the long run version of sorting test against such changes and it passed. >I dunno if i have perturbed the performance though... > >Paul. > >[1] >http://hg.openjdk.java.net/jdk9/dev/jdk/file/72fdb709f356/test/java/util/Array >s/Sorting.java > >On May 19, 2015, at 10:48 AM, "Chan, Sunny" wrote: > >> An updated patch has been published to cr.openjdk via Paul: >http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.2/ >> >> Updates: >> The testcase has been updated to clone the array >> The redundant constant MAX_RUN_LENGTH has been removed. >> >> From: Paul Sandoz [mailto:paul.sandoz at oracle.com] >> Sent: 16 May 2015 00:13 >> To: Chan, Sunny [Tech] >> Cc: O'Leary, Kristen [Tech]; 'Alan Bateman'; 'core-libs- >dev at openjdk.java.net'; Rezaei, Mohammad A. [Tech] >> Subject: Re: Patch to improve primitives Array.sort() >> >> >> On May 15, 2015, at 11:48 AM, "Chan, Sunny" wrote: >> >> >> I have provided Paul with an updated patch: >> >> >> Here it is: >> >> http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.1/ >> >> In DualPivotQuicksort >> >> 63 /** >> 64 * The maximum length of run in merge sort. >> 65 */ >> 66 private static final int MAX_RUN_LENGTH = 33; >> You can remove this constant. >> >> >> >> * The test has been updated using data provider and reduce as much >repetition as possible. >> >> Looking much better. Convention-wise if you don't have to deal with any >check exceptions using a Supplier is more preferable to Callable. Up to you. >> >> 56 @Test(dataProvider = "arrays") >> 57 public void runTests(String testName, Callable dataMethod) >throws Exception >> 58 { >> 59 int[] array = dataMethod.call(); >> 60 this.sortAndAssert(array); >> 61 this.sortAndAssert(this.floatCopyFromInt(array)); >> 62 this.sortAndAssert(this.doubleCopyFromInt(array)); >> 63 this.sortAndAssert(this.longCopyFromInt(array)); >> 64 this.sortAndAssert(this.shortCopyFromInt(array)); >> 65 this.sortAndAssert(this.charCopyFromInt(array)); >> >> At line 60 should you clone the array? otherwise, if i have looked >correctly, that sorted result will be tested for other values. >> >> >> >> * The GS copyright notice from the main JDK patch. However we retain it on >our test cases as we developed ourselves. In our previous contributions where >we provided new tests we have put our copyright along with oracle copyright >and it was accepted >(see:http://hg.openjdk.java.net/jdk9/dev/jdk/file/ed94f3e7ba6b/test/java/lang/ >instrument/DaemonThread/TestDaemonThread.java) >> >> Ok. It was more query on my part. I believe it's ok for you to add copyright >on both files if you wish. >> >> >> >> * Alan has commented that there were older benchmark but searching through >the archive I can see it mention "BentleyBasher" I cannot find the actual code >that Vladimir used (thread: http://mail.openjdk.java.net/pipermail/core-libs- >dev/2009-September/002633.html). Is there anywhere I can get hold of it? >> >> >> I tried looking, but i cannot find any. >> >> Paul. From ivan.gerasimov at oracle.com Fri May 22 00:34:33 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 22 May 2015 03:34:33 +0300 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <555E499C.6020300@Oracle.com> References: <555E499C.6020300@Oracle.com> Message-ID: <555E7999.8000207@oracle.com> Hi Roger On 22.05.2015 0:09, Roger Riggs wrote: > Please review these native code and build changes to clear compilation > warnings. > Most are due to mixing unsigned types with signed types or providing > the correct type to an invoked function. > The code changes look good! > Webrev: > http://bussund0416.us.oracle.com/~rriggs/webrev/webrev-fix-all-warnings-8074818/ > > I guess, this link may not be accessible from outside Oracle. Sincerely yours, Ivan > Issues: > 8074818: Resolve disabled warnings for libjava > 8080007: Stop ignoring warnings for libjava > > JPRT in progress for product and fastdebug builds on solaris, linux, > macosx, windows, > and embedded. > > Thanks, Roger > > > From Roger.Riggs at Oracle.com Fri May 22 00:42:04 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 21 May 2015 20:42:04 -0400 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <555E7999.8000207@oracle.com> References: <555E499C.6020300@Oracle.com> <555E7999.8000207@oracle.com> Message-ID: <555E7B5C.6020603@Oracle.com> Oops, got the wrong host: Webrev: http://cr.openjdk.java.net/~rriggs/webrev-fix-all-warnings-8074818/ Issues: 8074818: Resolve disabled warnings for libjava 8080007: Stop ignoring warnings for libjava Thanks, Roger On 5/21/15 8:34 PM, Ivan Gerasimov wrote: > Hi Roger > > On 22.05.2015 0:09, Roger Riggs wrote: >> Please review these native code and build changes to clear >> compilation warnings. >> Most are due to mixing unsigned types with signed types or providing >> the correct type to an invoked function. >> > The code changes look good! > >> Webrev: >> http://bussund0416.us.oracle.com/~rriggs/webrev/webrev-fix-all-warnings-8074818/ >> >> > I guess, this link may not be accessible from outside Oracle. > > Sincerely yours, > Ivan > >> Issues: >> 8074818: Resolve disabled warnings for libjava >> 8080007: Stop ignoring warnings for libjava >> >> JPRT in progress for product and fastdebug builds on solaris, linux, >> macosx, windows, >> and embedded. >> >> Thanks, Roger >> >> >> > From xueming.shen at oracle.com Fri May 22 06:38:59 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 21 May 2015 23:38:59 -0700 Subject: RFR: JDK-8064736: Part of java.util.jar.JarFile spec looks confusing with references to Zip Message-ID: <555ECF03.4050509@oracle.com> Hi Some doc update/typo fixes. issue: https://bugs.openjdk.java.net/browse/JDK-8064736 webrev: http://cr.openjdk.java.net/~sherman/8064736 Thanks, -Sherman From Alan.Bateman at oracle.com Fri May 22 06:45:41 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 22 May 2015 07:45:41 +0100 Subject: JDK 9 RFR of JDK-8080901: Replace package.html files with package-info.java in the java.base module In-Reply-To: <555E62E0.5070000@oracle.com> References: <555E62E0.5070000@oracle.com> Message-ID: <555ED095.4050107@oracle.com> On 21/05/2015 23:57, joe darcy wrote: > Hello, > > Please review these changes to replace old-style package.html files > with package-info.java files in the base module: > > JDK-8080901: Replace package.html files with package-info.java in > the java.base module > http://cr.openjdk.java.net/~darcy/8080901.0/ > > (The package.html file for src/java.base/share/classes/sun/reflect is > just removed rather than replaced since it contains "new" porting > information that was current as of 2001.) Good to see this happening, hopefully it wouldn't be too disruptive to pending changes that have update the package description. -Alan From erik.joelsson at oracle.com Fri May 22 06:52:23 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Fri, 22 May 2015 08:52:23 +0200 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <555E7B5C.6020603@Oracle.com> References: <555E499C.6020300@Oracle.com> <555E7999.8000207@oracle.com> <555E7B5C.6020603@Oracle.com> Message-ID: <555ED227.3060905@oracle.com> The build change looks fine, thanks for fixing this! /Erik On 2015-05-22 02:42, Roger Riggs wrote: > Oops, got the wrong host: > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-fix-all-warnings-8074818/ > > Issues: > 8074818: Resolve disabled warnings for libjava > 8080007: Stop ignoring warnings for libjava > > Thanks, Roger > > > > > On 5/21/15 8:34 PM, Ivan Gerasimov wrote: >> Hi Roger >> >> On 22.05.2015 0:09, Roger Riggs wrote: >>> Please review these native code and build changes to clear >>> compilation warnings. >>> Most are due to mixing unsigned types with signed types or providing >>> the correct type to an invoked function. >>> >> The code changes look good! >> >>> Webrev: >>> http://bussund0416.us.oracle.com/~rriggs/webrev/webrev-fix-all-warnings-8074818/ >>> >>> >> I guess, this link may not be accessible from outside Oracle. >> >> Sincerely yours, >> Ivan >> >>> Issues: >>> 8074818: Resolve disabled warnings for libjava >>> 8080007: Stop ignoring warnings for libjava >>> >>> JPRT in progress for product and fastdebug builds on solaris, linux, >>> macosx, windows, >>> and embedded. >>> >>> Thanks, Roger >>> >>> >>> >> > From Alan.Bateman at oracle.com Fri May 22 06:55:08 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 22 May 2015 07:55:08 +0100 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <555E7B5C.6020603@Oracle.com> References: <555E499C.6020300@Oracle.com> <555E7999.8000207@oracle.com> <555E7B5C.6020603@Oracle.com> Message-ID: <555ED2CC.3080308@oracle.com> On 22/05/2015 01:42, Roger Riggs wrote: > Oops, got the wrong host: > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-fix-all-warnings-8074818/ > > Issues: > 8074818: Resolve disabled warnings for libjava > 8080007: Stop ignoring warnings for libjava > > Thanks, Roger In JDK_GetVersionInfo0 then I wonder if we should change this assert to be a fatal error on product builds. Periodically people set the build to numbers > 255 and often only see issues when they use a fastdebug build. Th rest looks okay to me. I don't particularly like the IOE_FORMAT in ProcessImpl.c but I think other areas have done similar to deal with this warning. ConcurrentPReader_md.c is being removed in another patch under review at the moment so might be gone before you push. -Alan. From Alan.Bateman at oracle.com Fri May 22 06:57:33 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 22 May 2015 07:57:33 +0100 Subject: RFR: JDK-8064736: Part of java.util.jar.JarFile spec looks confusing with references to Zip In-Reply-To: <555ECF03.4050509@oracle.com> References: <555ECF03.4050509@oracle.com> Message-ID: <555ED35D.9030807@oracle.com> On 22/05/2015 07:38, Xueming Shen wrote: > Hi > > Some doc update/typo fixes. > > issue: https://bugs.openjdk.java.net/browse/JDK-8064736 > webrev: http://cr.openjdk.java.net/~sherman/8064736 This looks okay to me, @inheritDoc with replace :-) -Alan From paul.sandoz at oracle.com Fri May 22 08:01:48 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 22 May 2015 10:01:48 +0200 Subject: Patch to improve primitives Array.sort() In-Reply-To: <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> Message-ID: <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> On May 22, 2015, at 1:52 AM, "Rezaei, Mohammad A." wrote: > Thanks Paul. Your proposed changes make sense to us and they have no discernable impact on the performance. > Great, thanks. I am happy to update the current webrev (and also create an associated issue). Sorry to drag this out a little more, but i am still curious as to why MAX_RUN_LENGTH was ever there in the first place. AFAICT it was empirically derived: http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-February/005821.html http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-January/005713.html But there is no further information as to why this particular behaviour was required. Is there something about an equals-run > MAX_RUN_LENGTH (33) where an optimized merge sort performs poorly? I could have missed something but i don't see any data in either of the sorting tests that would exercise this case. Perhaps we need to performance test against a data set of + [+ ] for a total number of runs < MAX_RUN_COUNT (67) ? More generally it's probably worth investing in a set of related JMH tests based on Sorting test combinations and data shapes, as we don't currently have easy visibility into performance regressions due to code changes or perhaps due to changes in hotspot. Paul. From david.holmes at oracle.com Fri May 22 11:37:19 2015 From: david.holmes at oracle.com (David Holmes) Date: Fri, 22 May 2015 21:37:19 +1000 Subject: RFR: 7011441: ./jndi/ldap/Connection.java needs to avoid spurious wakeup In-Reply-To: <555E01FE.9070009@oracle.com> References: <555E01FE.9070009@oracle.com> Message-ID: <555F14EF.4020805@oracle.com> Hi Ivan, On 22/05/2015 2:04 AM, Ivan Gerasimov wrote: > Hello! > > This is a simple fix, which should prevent from early timeout in > sun.jndi.ldap.Connection.readReply(). > Would you please help review it? > > BUG: https://bugs.openjdk.java.net/browse/JDK-7011441 > WEBREV: http://cr.openjdk.java.net/~igerasim/7011441/00/webrev/ Seems okay but I'm wondering if the problem has been a spurious wakeup or a short timeout? (Not that you can readily tell the difference.) David > Sincerely yours, > Ivan From ivan.gerasimov at oracle.com Fri May 22 12:46:11 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 22 May 2015 15:46:11 +0300 Subject: RFR: 7011441: ./jndi/ldap/Connection.java needs to avoid spurious wakeup In-Reply-To: <555F14EF.4020805@oracle.com> References: <555E01FE.9070009@oracle.com> <555F14EF.4020805@oracle.com> Message-ID: <555F2513.7020008@oracle.com> Thank you David! I guess that the original report might have been filed based on the code analysis rather than because of really observed spurious wakeups. Sincerely yours, Ivan On 22.05.2015 14:37, David Holmes wrote: > Hi Ivan, > > On 22/05/2015 2:04 AM, Ivan Gerasimov wrote: >> Hello! >> >> This is a simple fix, which should prevent from early timeout in >> sun.jndi.ldap.Connection.readReply(). >> Would you please help review it? >> >> BUG: https://bugs.openjdk.java.net/browse/JDK-7011441 >> WEBREV: http://cr.openjdk.java.net/~igerasim/7011441/00/webrev/ > > Seems okay but I'm wondering if the problem has been a spurious wakeup > or a short timeout? (Not that you can readily tell the difference.) > > David > >> Sincerely yours, >> Ivan > > From Mohammad.Rezaei at gs.com Fri May 22 13:55:00 2015 From: Mohammad.Rezaei at gs.com (Rezaei, Mohammad A.) Date: Fri, 22 May 2015 09:55:00 -0400 Subject: Patch to improve primitives Array.sort() In-Reply-To: <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> Message-ID: <6882C9A35DFB9B4FA2779F7BF5B9757D2076116796@GSCMAMP06EX.firmwide.corp.gs.com> We have a set of JMH tests. We'll work with Sunny to make those part of the webrev (where do they go?) and the specific test you suggested below. Thanks Moh >-----Original Message----- >From: Paul Sandoz [mailto:paul.sandoz at oracle.com] >Sent: Friday, May 22, 2015 4:02 AM >To: Rezaei, Mohammad A. [Tech] >Cc: 'core-libs-dev at openjdk.java.net Libs'; Chan, Sunny [Tech]; O'Leary, >Kristen [Tech] >Subject: Re: Patch to improve primitives Array.sort() > >On May 22, 2015, at 1:52 AM, "Rezaei, Mohammad A." >wrote: >> Thanks Paul. Your proposed changes make sense to us and they have no >discernable impact on the performance. >> > >Great, thanks. I am happy to update the current webrev (and also create an >associated issue). > > >Sorry to drag this out a little more, but i am still curious as to why >MAX_RUN_LENGTH was ever there in the first place. AFAICT it was empirically >derived: > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2011- >February/005821.html > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2011- >January/005713.html > >But there is no further information as to why this particular behaviour was >required. > >Is there something about an equals-run > MAX_RUN_LENGTH (33) where an >optimized merge sort performs poorly? > >I could have missed something but i don't see any data in either of the >sorting tests that would exercise this case. Perhaps we need to performance >test against a data set of + [+ ] for a total >number of runs < MAX_RUN_COUNT (67) ? > > >More generally it's probably worth investing in a set of related JMH tests >based on Sorting test combinations and data shapes, as we don't currently have >easy visibility into performance regressions due to code changes or perhaps >due to changes in hotspot. > >Paul. From Roger.Riggs at Oracle.com Fri May 22 14:02:47 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 22 May 2015 10:02:47 -0400 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <555ED2CC.3080308@oracle.com> References: <555E499C.6020300@Oracle.com> <555E7999.8000207@oracle.com> <555E7B5C.6020603@Oracle.com> <555ED2CC.3080308@oracle.com> Message-ID: <555F3707.1030003@Oracle.com> Hi Alan, The change to make the assert about the build numbers in getVersionInfo should be a different issue. Perhaps it makes sense to do that as part of the JEP 223: New Version-String Scheme that is specific to the Oracle JDK. Thanks, Roger On 5/22/2015 2:55 AM, Alan Bateman wrote: > > > On 22/05/2015 01:42, Roger Riggs wrote: >> Oops, got the wrong host: >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-fix-all-warnings-8074818/ >> >> Issues: >> 8074818: Resolve disabled warnings for libjava >> 8080007: Stop ignoring warnings for libjava >> >> Thanks, Roger > In JDK_GetVersionInfo0 then I wonder if we should change this assert > to be a fatal error on product builds. Periodically people set the > build to numbers > 255 and often only see issues when they use a > fastdebug build. > > Th rest looks okay to me. I don't particularly like the IOE_FORMAT in > ProcessImpl.c but I think other areas have done similar to deal with > this warning. ConcurrentPReader_md.c is being removed in another patch > under review at the moment so might be gone before you push. > > -Alan. From paul.sandoz at oracle.com Fri May 22 14:23:38 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 22 May 2015 16:23:38 +0200 Subject: Patch to improve primitives Array.sort() In-Reply-To: <6882C9A35DFB9B4FA2779F7BF5B9757D2076116796@GSCMAMP06EX.firmwide.corp.gs.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D2076116796@GSCMAMP06EX.firmwide.corp.gs.com> Message-ID: <67BF3338-6879-445D-AA62-624D2C94B615@oracle.com> On May 22, 2015, at 3:55 PM, "Rezaei, Mohammad A." wrote: > We have a set of JMH tests. Great. I created a bug for this issue: https://bugs.openjdk.java.net/browse/JDK-8080945 > We'll work with Sunny to make those part of the webrev (where do they go?) and the specific test you suggested below. > Not actually sure, for now let's keep 'em with the unit test. I seem to recall a there was a "space" being arranged for benchmarks but i have forgotten if any progress has been made on that. Paul. From martinrb at google.com Fri May 22 16:14:25 2015 From: martinrb at google.com (Martin Buchholz) Date: Fri, 22 May 2015 09:14:25 -0700 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <555E499C.6020300@Oracle.com> References: <555E499C.6020300@Oracle.com> Message-ID: I plan to have review comments later today. On Thu, May 21, 2015 at 2:09 PM, Roger Riggs wrote: > Please review these native code and build changes to clear compilation > warnings. > Most are due to mixing unsigned types with signed types or providing > the correct type to an invoked function. > > Webrev: > > http://bussund0416.us.oracle.com/~rriggs/webrev/webrev-fix-all-warnings-8074818/ > > Issues: > 8074818: Resolve disabled warnings for libjava > 8080007: Stop ignoring warnings for libjava > > JPRT in progress for product and fastdebug builds on solaris, linux, > macosx, windows, > and embedded. > > Thanks, Roger > > From xueming.shen at oracle.com Fri May 22 16:16:41 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 22 May 2015 09:16:41 -0700 Subject: RFR JDK-8060161: re-examine sun/nio/cs/Test4200310.sh, test is invalid for modular image Message-ID: <555F5669.8090409@oracle.com> Alan, I agree that we should just remove this old regression test. It does not server an purpose after those jar files are gone. Please help review. issue: https://bugs.openjdk.java.net/browse/JDK-8060161 webrev: http://cr.openjdk.java.net/~sherman/8060161/ -Sherman From joe.darcy at oracle.com Fri May 22 16:39:28 2015 From: joe.darcy at oracle.com (joe darcy) Date: Fri, 22 May 2015 09:39:28 -0700 Subject: RFR: 8080803: sun/nio/cs/FindEncoderBugs.java failing intermittently In-Reply-To: <555E693E.8020609@oracle.com> References: <555E693E.8020609@oracle.com> Message-ID: <555F5BC0.9070407@oracle.com> Hi Sherman, The changes look fine, but the underlying cause of this will still needs to be investigated on the vm side. Thanks, -Joe On 5/21/2015 4:24 PM, Xueming Shen wrote: > Martin, Alan, Joe, > > Would you please help review the change (as a workaround) for this > "intermittently" problem? > > https://bugs.openjdk.java.net/browse/JDK-8080803 > http://cr.openjdk.java.net/~sherman/8080803 > > It appears the trigger might be that ByteBuffer.get(byte[]) fails to > get the bytes from the buffer "intermittently". > Interestingly this one is always reproducible on my local linux build > (very old os), in which I have to update > couple hotspot headfile to make the build going recently. I filed the > bug#8080904 to let the vm guy take a look. > > Meanwhile the proposed change here is just to "optimized" the ISO2022 > code a little to simple workaround > this issue. I hope this can make the "intermittent failure" go away in > our nightly build. If have time, we definitely > should re-visit the implementation of these ISO2022 :-) > > Thanks, > -Sherman From Alan.Bateman at oracle.com Fri May 22 16:55:23 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 22 May 2015 17:55:23 +0100 Subject: RFR: 8080803: sun/nio/cs/FindEncoderBugs.java failing intermittently In-Reply-To: <555E693E.8020609@oracle.com> References: <555E693E.8020609@oracle.com> Message-ID: <555F5F7B.1080403@oracle.com> On 22/05/2015 00:24, Xueming Shen wrote: > Martin, Alan, Joe, > > Would you please help review the change (as a workaround) for this > "intermittently" problem? > > https://bugs.openjdk.java.net/browse/JDK-8080803 > http://cr.openjdk.java.net/~sherman/8080803 > > It appears the trigger might be that ByteBuffer.get(byte[]) fails to > get the bytes from the buffer "intermittently". > Interestingly this one is always reproducible on my local linux build > (very old os), in which I have to update > couple hotspot headfile to make the build going recently. I filed the > bug#8080904 to let the vm guy take a look. > > Meanwhile the proposed change here is just to "optimized" the ISO2022 > code a little to simple workaround > this issue. I hope this can make the "intermittent failure" go away in > our nightly build. If have time, we definitely > should re-visit the implementation of these ISO2022 :-) Hopefully the compiler issue (assuming it is a compile issue) will get fixed soon. In the mean-time then this looks okay and an extra byte buffer and copy. -Alan From martinrb at google.com Fri May 22 17:47:54 2015 From: martinrb at google.com (Martin Buchholz) Date: Fri, 22 May 2015 10:47:54 -0700 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: References: <555E499C.6020300@Oracle.com> Message-ID: It's a good idea to order include statements by system dependencies, jdk dependencies, implementation helpers, BUT order of include statements should never ever matter. If it does, then we have a bug that should be fixed. Every header file should be independently includable, and C files should only Include What They Use. It would be good for us to test some of that, e.g. can you compile each .h file as its own translation unit? +#include +#include + #include "jni.h" #include "jni_util.h" #include "jlong.h" @@ -32,9 +35,6 @@ #include "java_io_FileInputStream.h" -#include -#include - From martinrb at google.com Fri May 22 17:54:47 2015 From: martinrb at google.com (Martin Buchholz) Date: Fri, 22 May 2015 10:54:47 -0700 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: References: <555E499C.6020300@Oracle.com> Message-ID: I agree it's a good idea to increase safety by replacing calls to *printf with calls to *nprintf, BUT when we do so we should also add debugging assertions that the message fits into the buffer. - sprintf(errmsg, format, errnum, detail); + snprintf(errmsg, fmtsize, IOE_FORMAT, errnum, detail); How about int needed = snprintf(...) assert(needed <= fmtsize); From martinrb at google.com Fri May 22 18:00:52 2015 From: martinrb at google.com (Martin Buchholz) Date: Fri, 22 May 2015 11:00:52 -0700 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: References: <555E499C.6020300@Oracle.com> Message-ID: The double assignment to i is stupid (a "dead store") - remove one of them. 63 size_t i = 0; 64 for (i = 1; i < len; i++) { From christos at zoulas.com Fri May 22 18:03:24 2015 From: christos at zoulas.com (Christos Zoulas) Date: Fri, 22 May 2015 14:03:24 -0400 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: from Martin Buchholz (May 22, 10:54am) Message-ID: <20150522180324.3909D17FDA8@rebar.astron.com> On May 22, 10:54am, martinrb at google.com (Martin Buchholz) wrote: -- Subject: Re: RFR 9: 8074818: Resolve disabled warnings for libjava | I agree it's a good idea to increase safety by replacing calls to *printf | with calls to *nprintf, BUT when we do so we should also add debugging | assertions that the message fits into the buffer. | | - sprintf(errmsg, format, errnum, detail); | + snprintf(errmsg, fmtsize, IOE_FORMAT, errnum, detail); | | How about | | int needed = snprintf(...) | assert(needed <= fmtsize); This only works if fmtsize is unsigned (which I hope it is) when snprintf returns < 0. It will also produce a warning with -Wsign-compare. For safety you could do: assert((size_t)needed <= fmtsize) christos From staffan.friberg at oracle.com Fri May 22 18:41:38 2015 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 22 May 2015 11:41:38 -0700 Subject: RFR 8080640: Reduce copying when reading JAR/ZIP entries In-Reply-To: <555E1D49.9000707@oracle.com> References: <555A957F.5010102@oracle.com> <555CCAFB.4090805@oracle.com> <555E0C62.9090406@oracle.com> <555E1D49.9000707@oracle.com> Message-ID: <555F7862.9030307@oracle.com> On 05/21/2015 11:00 AM, Staffan Friberg wrote: > > On 05/21/2015 09:48 AM, Staffan Friberg wrote: >> >> On 05/20/2015 10:57 AM, Xueming Shen wrote: >>> On 05/18/2015 06:44 PM, Staffan Friberg wrote: >>>> Hi, >>>> >>>> Wanted to get reviews and feedback on this performance improvement >>>> for reading from JAR/ZIP files during classloading by reducing >>>> unnecessary copying and reading the entry in one go instead of in >>>> small portions. This shows a significant improvement when reading a >>>> single entry and for a large application with 10k classes and 500+ >>>> JAR files it improved the startup time by 4%. >>>> >>>> For more details on the background and performance results please >>>> see the RFE entry. >>>> >>>> RFE - https://bugs.openjdk.java.net/browse/JDK-8080640 >>>> WEBREV - http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.0 >>>> >>>> Cheers, >>>> Staffan >>> >>> Hi Staffan, >>> >>> If I did not miss something here, from your use scenario it appears >>> to me the only thing you really >>> need here to help boost your performance is >>> >>> byte[] ZipFile.getAllBytes(ZipEntry ze); >>> >>> You are allocating a byte[] at use side and wrapping it with a >>> ByteBuffer if the size is small enough, >>> otherwise, you letting the ZipFile to allocate a big enough one for >>> you. It does not look like you >>> can re-use that byte[] (has to be wrapped by the >>> ByteArrayInputStream and return), why do you >>> need two different methods here? The logic would be much easier to >>> simply let the ZipFile to allocate >>> the needed buffer with appropriate size, fill the bytes and return, >>> with a "OOME" if the entry size >>> is bigger than 2g. >>> >>> The only thing we use from the input ze is its name, get the >>> size/csize from the jzentry, I don't think >>> jzentry.csize/size can be "unknown", they are from the "cen" table. >>> >>> If the real/final use of the bytes is to wrap it with a >>> ByteArrayInputStream,why bother using ByteBuffer >>> here? Shouldn't a direct byte[] with exactly the size of the entry >>> server better. >>> >>> -Sherman >>> >> Hi Sherman, >> >> Thanks for the comments. I agree, was starting out with bytebuffer >> because I was hoping to be able to cache things where the buffer was >> being used, but since the buffer is past along further I couldn't >> figure out a clean way to do it. >> Will rewrite it to simply just return a buffer, and only wrap it in >> the Resource class getByteBuffer. >> >> What would be your thought on updating the ZipFile.getInputStream to >> return ByteArrayInputStream for small entries? Currently I do that >> work outside in two places and moving it would potentially speed up >> others reading small entries as well. >> >> Thanks, >> Staffan > Just realized that my use of ByteArrayInputStream would miss Jar > verification if enabled so the way to go hear would be to add it if > possible to the ZipFile.getInputStream. > > //Staffan Hi, Here is an updated webrev which uses a byte[] directly and also uses ByteArrayInputStream in ZipFile for small entries below 128k. http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.1 //Staffan From xueming.shen at oracle.com Fri May 22 18:51:36 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 22 May 2015 11:51:36 -0700 Subject: RFR 8080640: Reduce copying when reading JAR/ZIP entries In-Reply-To: <555F7862.9030307@oracle.com> References: <555A957F.5010102@oracle.com> <555CCAFB.4090805@oracle.com> <555E0C62.9090406@oracle.com> <555E1D49.9000707@oracle.com> <555F7862.9030307@oracle.com> Message-ID: <555F7AB8.1050202@oracle.com> On 05/22/2015 11:41 AM, Staffan Friberg wrote: > > On 05/21/2015 11:00 AM, Staffan Friberg wrote: >> >> On 05/21/2015 09:48 AM, Staffan Friberg wrote: >>> >>> On 05/20/2015 10:57 AM, Xueming Shen wrote: >>>> On 05/18/2015 06:44 PM, Staffan Friberg wrote: >>>>> Hi, >>>>> >>>>> Wanted to get reviews and feedback on this performance improvement for reading from JAR/ZIP files during classloading by reducing unnecessary copying and reading the entry in one go instead of in small portions. This shows a significant improvement when reading a single entry and for a large application with 10k classes and 500+ JAR files it improved the startup time by 4%. >>>>> >>>>> For more details on the background and performance results please see the RFE entry. >>>>> >>>>> RFE - https://bugs.openjdk.java.net/browse/JDK-8080640 >>>>> WEBREV - http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.0 >>>>> >>>>> Cheers, >>>>> Staffan >>>> >>>> Hi Staffan, >>>> >>>> If I did not miss something here, from your use scenario it appears to me the only thing you really >>>> need here to help boost your performance is >>>> >>>> byte[] ZipFile.getAllBytes(ZipEntry ze); >>>> >>>> You are allocating a byte[] at use side and wrapping it with a ByteBuffer if the size is small enough, >>>> otherwise, you letting the ZipFile to allocate a big enough one for you. It does not look like you >>>> can re-use that byte[] (has to be wrapped by the ByteArrayInputStream and return), why do you >>>> need two different methods here? The logic would be much easier to simply let the ZipFile to allocate >>>> the needed buffer with appropriate size, fill the bytes and return, with a "OOME" if the entry size >>>> is bigger than 2g. >>>> >>>> The only thing we use from the input ze is its name, get the size/csize from the jzentry, I don't think >>>> jzentry.csize/size can be "unknown", they are from the "cen" table. >>>> >>>> If the real/final use of the bytes is to wrap it with a ByteArrayInputStream,why bother using ByteBuffer >>>> here? Shouldn't a direct byte[] with exactly the size of the entry server better. >>>> >>>> -Sherman >>>> >>> Hi Sherman, >>> >>> Thanks for the comments. I agree, was starting out with bytebuffer because I was hoping to be able to cache things where the buffer was being used, but since the buffer is past along further I couldn't figure out a clean way to do it. >>> Will rewrite it to simply just return a buffer, and only wrap it in the Resource class getByteBuffer. >>> >>> What would be your thought on updating the ZipFile.getInputStream to return ByteArrayInputStream for small entries? Currently I do that work outside in two places and moving it would potentially speed up others reading small entries as well. >>> >>> Thanks, >>> Staffan >> Just realized that my use of ByteArrayInputStream would miss Jar verification if enabled so the way to go hear would be to add it if possible to the ZipFile.getInputStream. >> >> //Staffan > Hi, > > Here is an updated webrev which uses a byte[] directly and also uses ByteArrayInputStream in ZipFile for small entries below 128k. > I'm not sure about the benefit of doing the ByteArrayInputStream in ZipFile.getInputStream. It has the consequence of changing the "expected" behavior of getInputStream() (instead of return an input stream waiting for reading, it now reads all bytes in advance), something we might not want to do in a performance tuning. Though it might be reasonable to guess everyone get an input stream is to read all bytes from it later. -Sherman > http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.1 > > //Staffan From staffan.friberg at oracle.com Fri May 22 20:15:52 2015 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 22 May 2015 13:15:52 -0700 Subject: RFR 8080640: Reduce copying when reading JAR/ZIP entries In-Reply-To: <555F7AB8.1050202@oracle.com> References: <555A957F.5010102@oracle.com> <555CCAFB.4090805@oracle.com> <555E0C62.9090406@oracle.com> <555E1D49.9000707@oracle.com> <555F7862.9030307@oracle.com> <555F7AB8.1050202@oracle.com> Message-ID: <555F8E78.40404@oracle.com> On 05/22/2015 11:51 AM, Xueming Shen wrote: > On 05/22/2015 11:41 AM, Staffan Friberg wrote: >> >> On 05/21/2015 11:00 AM, Staffan Friberg wrote: >>> >>> On 05/21/2015 09:48 AM, Staffan Friberg wrote: >>>> >>>> On 05/20/2015 10:57 AM, Xueming Shen wrote: >>>>> On 05/18/2015 06:44 PM, Staffan Friberg wrote: >>>>>> Hi, >>>>>> >>>>>> Wanted to get reviews and feedback on this performance >>>>>> improvement for reading from JAR/ZIP files during classloading by >>>>>> reducing unnecessary copying and reading the entry in one go >>>>>> instead of in small portions. This shows a significant >>>>>> improvement when reading a single entry and for a large >>>>>> application with 10k classes and 500+ JAR files it improved the >>>>>> startup time by 4%. >>>>>> >>>>>> For more details on the background and performance results please >>>>>> see the RFE entry. >>>>>> >>>>>> RFE - https://bugs.openjdk.java.net/browse/JDK-8080640 >>>>>> WEBREV - http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.0 >>>>>> >>>>>> Cheers, >>>>>> Staffan >>>>> >>>>> Hi Staffan, >>>>> >>>>> If I did not miss something here, from your use scenario it >>>>> appears to me the only thing you really >>>>> need here to help boost your performance is >>>>> >>>>> byte[] ZipFile.getAllBytes(ZipEntry ze); >>>>> >>>>> You are allocating a byte[] at use side and wrapping it with a >>>>> ByteBuffer if the size is small enough, >>>>> otherwise, you letting the ZipFile to allocate a big enough one >>>>> for you. It does not look like you >>>>> can re-use that byte[] (has to be wrapped by the >>>>> ByteArrayInputStream and return), why do you >>>>> need two different methods here? The logic would be much easier to >>>>> simply let the ZipFile to allocate >>>>> the needed buffer with appropriate size, fill the bytes and >>>>> return, with a "OOME" if the entry size >>>>> is bigger than 2g. >>>>> >>>>> The only thing we use from the input ze is its name, get the >>>>> size/csize from the jzentry, I don't think >>>>> jzentry.csize/size can be "unknown", they are from the "cen" table. >>>>> >>>>> If the real/final use of the bytes is to wrap it with a >>>>> ByteArrayInputStream,why bother using ByteBuffer >>>>> here? Shouldn't a direct byte[] with exactly the size of the entry >>>>> server better. >>>>> >>>>> -Sherman >>>>> >>>> Hi Sherman, >>>> >>>> Thanks for the comments. I agree, was starting out with bytebuffer >>>> because I was hoping to be able to cache things where the buffer >>>> was being used, but since the buffer is past along further I >>>> couldn't figure out a clean way to do it. >>>> Will rewrite it to simply just return a buffer, and only wrap it in >>>> the Resource class getByteBuffer. >>>> >>>> What would be your thought on updating the ZipFile.getInputStream >>>> to return ByteArrayInputStream for small entries? Currently I do >>>> that work outside in two places and moving it would potentially >>>> speed up others reading small entries as well. >>>> >>>> Thanks, >>>> Staffan >>> Just realized that my use of ByteArrayInputStream would miss Jar >>> verification if enabled so the way to go hear would be to add it if >>> possible to the ZipFile.getInputStream. >>> >>> //Staffan >> Hi, >> >> Here is an updated webrev which uses a byte[] directly and also uses >> ByteArrayInputStream in ZipFile for small entries below 128k. >> > > I'm not sure about the benefit of doing the ByteArrayInputStream in > ZipFile.getInputStream. It has > the consequence of changing the "expected" behavior of > getInputStream() (instead of return an > input stream waiting for reading, it now reads all bytes in advance), > something we might not want > to do in a performance tuning. Though it might be reasonable to guess > everyone get an input stream > is to read all bytes from it later. > > -Sherman > > >> http://cr.openjdk.java.net/~sfriberg/JDK-8080640/webrev.1 >> >> //Staffan > Agree that it will change the behavior slightly, but as you said it is probably expected that some one will read the stream eventually. We could reduce the size further if that makes a difference, if the size is below 65k we would not use more memory than the buffer allocated for the InflaterStream today. The total allocation would be slightly larger for deflated entries as we would allocate a byte[] for the compressed bytes, but it would be GC:able and not kept alive. So from a memory perspective the difference is very limited. //Staffan From xueming.shen at oracle.com Sun May 24 00:26:40 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Sat, 23 May 2015 17:26:40 -0700 Subject: RFR JDK-8042125: Japanese character converters incompatible between Java 7 and Java 8 Message-ID: <55611AC0.8090803@oracle.com> Hi Please help the change for 8042125 issue: https://bugs.openjdk.java.net/browse/JDK-8042125 webrev: http://cr.openjdk.java.net/~sherman/8042125 It's a regression caused by the changes of JDK-6653797. The direct triggers are (1) the .c2b mapping table for ms932/0208is missing (regardless the comment in JIS_X_0208_MS932.map says we need one) (2) mapping entry for those non-roundtrip code points are mistakenly commented out in jis_x_0212_solaris.map and jis_x_0208_ms932.map. thanks! -Sherman From mandy.chung at oracle.com Sun May 24 04:00:18 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Sat, 23 May 2015 21:00:18 -0700 Subject: Review Request 8074432: Move jdeps to jdk.compiler module Message-ID: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> This will move jdeps to the same module as other langtools javac and javap. Webrev at: http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074432/webrev.00/ This is the final change to resolve the open issue JDK-8072601 (Re-examine jdk.runtime and jdk.dev modules) for JEP 200. Mandy From ivan.gerasimov at oracle.com Sun May 24 20:17:02 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sun, 24 May 2015 23:17:02 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) Message-ID: <556231BE.9050703@oracle.com> Hello everybody! I know many people here like it when the performance is getting better. It was suggested to make the literal variant of String.replace() faster. Currently, this method is implemented as a few calls to regexp API, so that the whole implementation takes only two lines of code. I've created two versions of the fix. In the first one, we scan the string and store indices of the found substrings in an array. Then, we allocate the precisely sized char array and fill it it. The case with the empty target has to be handled separately. BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ The second variant is much less verbose, however it's less efficient too. Here the StringJoiner is used as an intermediate storage. WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ Here are the micro-benchmark results (in a string of ~300 chars do ~15 replacements). 0) Baseline MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s 1) Heavy-duty +308% MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s 2) StringJoiner +190% MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s Personally, I like my first variant better, even though it adds almost 300 lines of code. But I'd like to hear what people think of it. Sincerely yours, Ivan From forax at univ-mlv.fr Sun May 24 21:23:18 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sun, 24 May 2015 23:23:18 +0200 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556231BE.9050703@oracle.com> References: <556231BE.9050703@oracle.com> Message-ID: <55624146.7050104@univ-mlv.fr> Hi Ivan, I will let people to comment on your first version but your second version uses a Stream and some lambdas which is in my opinion not a good idea in term of dependencies (Stream will be loaded too soon by example) and it may create some trouble in the future because lambdas depends on some classes of java.lang.invoke that are initialized late in the boot process while java.lang.String is initialized early. cheers, R?mi On 05/24/2015 10:17 PM, Ivan Gerasimov wrote: > Hello everybody! > > I know many people here like it when the performance is getting better. > It was suggested to make the literal variant of String.replace() faster. > Currently, this method is implemented as a few calls to regexp API, so > that the whole implementation takes only two lines of code. > > I've created two versions of the fix. > In the first one, we scan the string and store indices of the found > substrings in an array. > Then, we allocate the precisely sized char array and fill it it. > The case with the empty target has to be handled separately. > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 > WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ > > The second variant is much less verbose, however it's less efficient too. > Here the StringJoiner is used as an intermediate storage. > > WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ > > > Here are the micro-benchmark results (in a string of ~300 chars do ~15 > replacements). > 0) Baseline > MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s > > 1) Heavy-duty +308% > MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s > > 2) StringJoiner +190% > MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s > > > Personally, I like my first variant better, even though it adds almost > 300 lines of code. > But I'd like to hear what people think of it. > > Sincerely yours, > Ivan From ivan.gerasimov at oracle.com Sun May 24 21:50:46 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 25 May 2015 00:50:46 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <55624146.7050104@univ-mlv.fr> References: <556231BE.9050703@oracle.com> <55624146.7050104@univ-mlv.fr> Message-ID: <556247B6.6020302@oracle.com> Hi R?mi! On 25.05.2015 0:23, Remi Forax wrote: > Hi Ivan, > I will let people to comment on your first version but your second > version uses a Stream and some lambdas which is in my opinion not a > good idea in term of dependencies (Stream will be loaded too soon by > example) and it may create some trouble in the future because lambdas > depends on some classes of java.lang.invoke that are initialized late > in the boot process while java.lang.String is initialized early. > Good point. It could be rewritten using anonymous class instead. Though, I still like the first version better :-) Sincerely yours, Ivan > cheers, > R?mi > > On 05/24/2015 10:17 PM, Ivan Gerasimov wrote: >> Hello everybody! >> >> I know many people here like it when the performance is getting better. >> It was suggested to make the literal variant of String.replace() faster. >> Currently, this method is implemented as a few calls to regexp API, >> so that the whole implementation takes only two lines of code. >> >> I've created two versions of the fix. >> In the first one, we scan the string and store indices of the found >> substrings in an array. >> Then, we allocate the precisely sized char array and fill it it. >> The case with the empty target has to be handled separately. >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >> >> The second variant is much less verbose, however it's less efficient >> too. >> Here the StringJoiner is used as an intermediate storage. >> >> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >> >> >> Here are the micro-benchmark results (in a string of ~300 chars do >> ~15 replacements). >> 0) Baseline >> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >> >> 1) Heavy-duty +308% >> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >> >> 2) StringJoiner +190% >> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >> >> >> Personally, I like my first variant better, even though it adds >> almost 300 lines of code. >> But I'd like to hear what people think of it. >> >> Sincerely yours, >> Ivan > > > From Alan.Bateman at oracle.com Mon May 25 07:16:49 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 25 May 2015 08:16:49 +0100 Subject: Review Request 8074432: Move jdeps to jdk.compiler module In-Reply-To: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> References: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> Message-ID: <5562CC61.30603@oracle.com> On 24/05/2015 05:00, Mandy Chung wrote: > This will move jdeps to the same module as other langtools javac and javap. > > Webrev at: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074432/webrev.00/ > > This is the final change to resolve the open issue JDK-8072601 (Re-examine jdk.runtime and jdk.dev modules) for JEP 200. > > Mandy I don't see any issues with the patch but I wonder if this is a case where we should introduce jdk.jdeps rather than putting the tool in the jdk.compile module. A passing comment is that I see we run these tools with -Xms8m, we should re-visit that some day. -Alan. From magnus.ihse.bursie at oracle.com Mon May 25 07:52:58 2015 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Mon, 25 May 2015 09:52:58 +0200 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <555F3707.1030003@Oracle.com> References: <555E499C.6020300@Oracle.com> <555E7999.8000207@oracle.com> <555E7B5C.6020603@Oracle.com> <555ED2CC.3080308@oracle.com> <555F3707.1030003@Oracle.com> Message-ID: <5562D4DA.1010607@oracle.com> On 2015-05-22 16:02, Roger Riggs wrote: > Hi Alan, > > The change to make the assert about the build numbers in > getVersionInfo should be a different issue. > Perhaps it makes sense to do that as part of the JEP 223: New > Version-String Scheme > that is specific to the Oracle JDK. The current JEP-223 sandbox does indeed have a check in configure that build numbers cannot exceed 255. /Magnus > > Thanks, Roger > > > > On 5/22/2015 2:55 AM, Alan Bateman wrote: >> >> >> On 22/05/2015 01:42, Roger Riggs wrote: >>> Oops, got the wrong host: >>> >>> Webrev: >>> http://cr.openjdk.java.net/~rriggs/webrev-fix-all-warnings-8074818/ >>> >>> Issues: >>> 8074818: Resolve disabled warnings for libjava >>> 8080007: Stop ignoring warnings for libjava >>> >>> Thanks, Roger >> In JDK_GetVersionInfo0 then I wonder if we should change this assert >> to be a fatal error on product builds. Periodically people set the >> build to numbers > 255 and often only see issues when they use a >> fastdebug build. >> >> Th rest looks okay to me. I don't particularly like the IOE_FORMAT in >> ProcessImpl.c but I think other areas have done similar to deal with >> this warning. ConcurrentPReader_md.c is being removed in another >> patch under review at the moment so might be gone before you push. >> >> -Alan. > From masayoshi.okutsu at oracle.com Mon May 25 09:38:12 2015 From: masayoshi.okutsu at oracle.com (Masayoshi Okutsu) Date: Mon, 25 May 2015 18:38:12 +0900 Subject: RFR JDK-8042125: Japanese character converters incompatible between Java 7 and Java 8 In-Reply-To: <55611AC0.8090803@oracle.com> References: <55611AC0.8090803@oracle.com> Message-ID: <5562ED84.3070204@oracle.com> Looks good to me. Masayoshi On 5/24/2015 9:26 AM, Xueming Shen wrote: > Hi > > Please help the change for 8042125 > > issue: https://bugs.openjdk.java.net/browse/JDK-8042125 > webrev: http://cr.openjdk.java.net/~sherman/8042125 > > It's a regression caused by the changes of JDK-6653797. The direct > triggers are > (1) the .c2b mapping table for ms932/0208is missing (regardless the > comment in > JIS_X_0208_MS932.map says we need one) > (2) mapping entry for those non-roundtrip code points are mistakenly > commented > out in jis_x_0212_solaris.map and jis_x_0208_ms932.map. > > thanks! > -Sherman > > > From alexander.v.stepanov at oracle.com Mon May 25 09:40:30 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Mon, 25 May 2015 12:40:30 +0300 Subject: RFR [9] 8040147: minor cleanup for docs In-Reply-To: <554264A5.1010700@oracle.com> References: <554264A5.1010700@oracle.com> Message-ID: <5562EE0E.2060203@oracle.com> Hello, Could you please review the fix http://cr.openjdk.java.net/~avstepan/8040147/webrev.02/ for https://bugs.openjdk.java.net/browse/JDK-8040147 Just a minor fix for docs (some tidy warnings + misprints). Thanks, Alexander From sundararajan.athijegannathan at oracle.com Mon May 25 12:54:45 2015 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Mon, 25 May 2015 18:24:45 +0530 Subject: RFR 8068978: All versions of javax.script.ScriptEngine.eval(...) method may clarify ScriptException throwing Message-ID: <55631B95.5070200@oracle.com> Please review http://cr.openjdk.java.net/~sundar/8068978/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8068978 Thanks, -Sundar From attila.szegedi at oracle.com Mon May 25 13:29:08 2015 From: attila.szegedi at oracle.com (Attila Szegedi) Date: Mon, 25 May 2015 15:29:08 +0200 Subject: RFR 8068978: All versions of javax.script.ScriptEngine.eval(...) method may clarify ScriptException throwing In-Reply-To: <55631B95.5070200@oracle.com> References: <55631B95.5070200@oracle.com> Message-ID: +1 > On May 25, 2015, at 2:54 PM, A. Sundararajan wrote: > > Please review http://cr.openjdk.java.net/~sundar/8068978/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8068978 > > Thanks, > -Sundar From spliterator at gmail.com Mon May 25 15:23:05 2015 From: spliterator at gmail.com (Stefan Zobel) Date: Mon, 25 May 2015 17:23:05 +0200 Subject: DualPivotQuicksort webrev for JDK-8080945 Message-ID: Hi all, Unless I'm doing something immensely stupid, the DualPivotQuicksort proposal in http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.2/ doesn't work for me. This little program public static void main(String[] args) { int[] a = new int[287]; for (int i = 0; i < a.length; i++) { a[i] = -((i % 143) + 1); } System.out.println(Arrays.toString(a)); DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); } sends the sort into an infinite loop. Something wrong with the test?? Stefan From Lance.Andersen at oracle.com Mon May 25 15:53:16 2015 From: Lance.Andersen at oracle.com (Lance Andersen) Date: Mon, 25 May 2015 11:53:16 -0400 Subject: RFR [9] 8040147: minor cleanup for docs In-Reply-To: <5562EE0E.2060203@oracle.com> References: <554264A5.1010700@oracle.com> <5562EE0E.2060203@oracle.com> Message-ID: <4B6A88A8-9627-4FCE-AEEE-93A726818118@oracle.com> Hi Alexander, Overal this looks OK. One suggestion for webrevs is to change to {@code} while you are updating specific comments (not the entire file, but at least the lines you are touching). Thank you for making the changes. Best Lance On May 25, 2015, at 5:40 AM, alexander stepanov wrote: > Hello, > > Could you please review the fix > http://cr.openjdk.java.net/~avstepan/8040147/webrev.02/ > for > https://bugs.openjdk.java.net/browse/JDK-8040147 > > Just a minor fix for docs (some tidy warnings + misprints). > > Thanks, > Alexander > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From mandy.chung at oracle.com Mon May 25 19:28:12 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 25 May 2015 12:28:12 -0700 Subject: Review Request 8074432: Move jdeps to jdk.compiler module In-Reply-To: <5562CC61.30603@oracle.com> References: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> <5562CC61.30603@oracle.com> Message-ID: Meant to include jigsaw-dev in the initial post. > On May 25, 2015, at 12:16 AM, Alan Bateman wrote: > > On 24/05/2015 05:00, Mandy Chung wrote: >> This will move jdeps to the same module as other langtools javac and javap. >> >> Webrev at: >> http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074432/webrev.00/ >> >> This is the final change to resolve the open issue JDK-8072601 (Re-examine jdk.runtime and jdk.dev modules) for JEP 200. >> >> Mandy > I don't see any issues with the patch but I wonder if this is a case where we should introduce jdk.jdeps rather than putting the tool in the jdk.compile module. > serialver and javap are in jdk.compiler that is an appropriate home for jdeps while I don?t particularly like it since it isn?t clear to tell from jdk.compiler module name where jdeps is there. The tool modules have been evolved a bit and some tools are put in its own module such as jdk.pack200, jdk.policytool, jdk.javadoc, jdk.jconsole, jdk.rmic etc. that are organized around its primary tool which is easy to name, document, and understand. Putting jdeps in jdk.jdeps module makes it easy where to find jdeps that is an attractive option. This also opens up the option to move jdeps to jdk repo in the future - it is just a side point and jdeps is currently being used as an interim solution to verify module boundaries until the module system is moving further along. I will post a revised webrev. > A passing comment is that I see we run these tools with -Xms8m, we should re-visit that some day. > Yes - we should re-visit this for the launchers we have. Mandy From ivan.gerasimov at oracle.com Mon May 25 23:07:05 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 26 May 2015 02:07:05 +0300 Subject: RFR 8081027: Create a common test to check adequacy of initial size of static HashMap/ArrayList fields Message-ID: <5563AB19.4060507@oracle.com> Hello! This is in some way continuation of JDK-8080535 (Expected size of Character.UnicodeBlock.map is not optimal). A new utility class OptimalCapacity was added to jdk.testlibrary package. The test NonOptimalMapSize.java that had been added with JDK-8080535, was rewritten with use of this new class. A couple more tests were added, which utilize methods of OptimalCapacity for checking sizes of ArrayList and IdentityHashMap static variables. Optimization of initial sizes of two more variables saves us one reallocation during java start-time and a few more bytes of memory. Would you please help review this fix? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8081027 WEBREV: http://cr.openjdk.java.net/~igerasim/8081027/00/webrev/ Sincerely yours, Ivan From Mohammad.Rezaei at gs.com Tue May 26 01:32:11 2015 From: Mohammad.Rezaei at gs.com (Rezaei, Mohammad A.) Date: Mon, 25 May 2015 21:32:11 -0400 Subject: DualPivotQuicksort webrev for JDK-8080945 In-Reply-To: References: Message-ID: <6882C9A35DFB9B4FA2779F7BF5B9757D20761167DE@GSCMAMP06EX.firmwide.corp.gs.com> Stefan, you're looking at an older version of the code. If you apply Paul's suggestions from http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-May/033640.html the code works as expected. Thanks Moh >-----Original Message----- >From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] On Behalf >Of Stefan Zobel >Sent: Monday, May 25, 2015 11:23 AM >To: core-libs-dev at openjdk.java.net >Subject: DualPivotQuicksort webrev for JDK-8080945 > >Hi all, > > >Unless I'm doing something immensely stupid, the DualPivotQuicksort >proposal in http://cr.openjdk.java.net/~psandoz/tmp/gs/sort/webrev.2/ >doesn't work for me. > > >This little program > > >public static void main(String[] args) { >int[] a = new int[287]; > >for (int i = 0; i < a.length; i++) { >a[i] = -((i % 143) + 1); >} > >System.out.println(Arrays.toString(a)); > >DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); >} > > > >sends the sort into an infinite loop. Something wrong with the test?? > > >Stefan From Sunny.Chan at gs.com Tue May 26 02:19:11 2015 From: Sunny.Chan at gs.com (Chan, Sunny) Date: Tue, 26 May 2015 10:19:11 +0800 Subject: Patch to improve primitives Array.sort() In-Reply-To: <67BF3338-6879-445D-AA62-624D2C94B615@oracle.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D2076116796@GSCMAMP06EX.firmwide.corp.gs.com> <67BF3338-6879-445D-AA62-624D2C94B615@oracle.com> Message-ID: <1CF6FDFD0639DF478B44651D79ECE7040116F6824F@GSCMHKP12EX.firmwide.corp.gs.com> I have looked at the mailing list archive and so far I haven't identify any progress on the "space for benchmark" - so we could include the performance test as a part of the patch but it will required JMH access somehow. From: Paul Sandoz [mailto:paul.sandoz at oracle.com] Sent: 22 May 2015 22:24 To: Rezaei, Mohammad A. [Tech] Cc: 'core-libs-dev at openjdk.java.net Libs'; Chan, Sunny [Tech]; O'Leary, Kristen [Tech] Subject: Re: Patch to improve primitives Array.sort() On May 22, 2015, at 3:55 PM, "Rezaei, Mohammad A." > wrote: We have a set of JMH tests. Great. I created a bug for this issue: https://bugs.openjdk.java.net/browse/JDK-8080945 We'll work with Sunny to make those part of the webrev (where do they go?) and the specific test you suggested below. Not actually sure, for now let's keep 'em with the unit test. I seem to recall a there was a "space" being arranged for benchmarks but i have forgotten if any progress has been made on that. Paul. From mail at florian-schoppmann.net Tue May 26 02:57:14 2015 From: mail at florian-schoppmann.net (Florian Schoppmann) Date: Mon, 25 May 2015 19:57:14 -0700 Subject: JEP 119 / Implementation of javax.lang.model.util.Types Message-ID: <1m4zti6.p7nsvt115i3i8N%mail@florian-schoppmann.net> Hi all, This Github repository of mine provides an abstract skeletal implementation of the type-system related methods of interface javax.lang.model.util.Types, plus a concrete realization backed by the core Java Reflection API, akin to JEP 119 by Joe Darcy. Obviously, there also exists an official JEP 119 implementation, so far in proof-of-concept state: In their current states, the two projects have slightly different goals: E.g., CoreReflectionFactory.java in the official JEP 119 implementation does not yet implement all subtyping-related relations like, e.g., JLS ?4.5.1 "contains", whereas my project is so far only concerned with subtyping but does not implement any Element-subinterfaces except TypeElement). Moreover, JEP 119 is only concerned with backing javax.lang.model by Core Reflection, whereas the goal of my project is to allow arbitrary backing (say, e.g., by the domain model of some DSL that needs to support the Java type system). If there should be any interest in using my code or parts of it for the JDK, I would be happy to help with any necessary adjustments. Florian PS: X-post to core-libs.devel and compiler.devel. Follow-up to core-libs suggested. From paul.sandoz at oracle.com Tue May 26 07:49:12 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 26 May 2015 09:49:12 +0200 Subject: Patch to improve primitives Array.sort() In-Reply-To: <1CF6FDFD0639DF478B44651D79ECE7040116F6824F@GSCMHKP12EX.firmwide.corp.gs.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D2076116796@GSCMAMP06EX.firmwide.corp.gs.com> <67BF3338-6879-445D-AA62-624D2C94B615@oracle.com> <1CF6FDFD0639DF478B44651D79ECE7040116F6824F@GSCMHKP12EX.firmwide.corp.gs.com> Message-ID: On May 26, 2015, at 4:19 AM, "Chan, Sunny" wrote: > I have looked at the mailing list archive and so far I haven?t identify any progress on the ?space for benchmark? ? so we could include the performance test as a part of the patch but it will required JMH access somehow. I think that's ok for now, even if there is no easy way to directly run them. They are still valuable since next time we want to enhance or fix sorting the tests will be easy to find. For many tests we often require jtreg or testng, so it's kind of another dependency which is actively maintained and developed by the overall JDK team. Granted it's one that currently requires more work to execute. It might be interesting to investigate if jtreg could be enhanced to build and run JMH tests, or even a separate harness would be useful, most probably leveraging maven. Paul. From paul.sandoz at oracle.com Tue May 26 07:49:51 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 26 May 2015 09:49:51 +0200 Subject: Patch to improve primitives Array.sort() In-Reply-To: <4725EC08FFA7B84AB611B2463BDA97ED1BC3DF5E1C@GSCMAMP30EX.firmwide.corp.gs.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1BC3DF5E1C@GSCMAMP30EX.firmwide.corp.gs.com> Message-ID: <33F5CD5E-5BA8-486B-8269-B7D8875B0DA1@oracle.com> On May 22, 2015, at 9:56 PM, "O'Leary, Kristen" wrote: > Hi Paul, > > We've created an additional test based on your suggestion: an array of size 10,000,000, 32 pair flips, a run of zeroes in the middle, and 32 pair flips at the end. Here are the results for int: > Benchmark (listType) Mode Cnt Score Error Units > SortingIntTestJMH.sortCurrentWay pairFlipZeroPairFlip thrpt 10 4.886 ? 0.031 ops/s > SortingIntTestJMH.sortNewWay pairFlipZeroPairFlip thrpt 10 14.793 ? 0.217 ops/s > > We also created a similar test which is 10, 5 repeated 32 times, a run of 100 in the middle, and 10, 5 repeated 32 times at the end. Here are the results again for int: > Benchmark (listType) Mode Cnt Score Error Units > SortingIntTestJMH.sortCurrentWay pairFlipOneHundredPairFlip thrpt 10 4.936 ? 0.040 ops/s > SortingIntTestJMH.sortNewWay pairFlipOneHundredPairFlip thrpt 10 18.472 ? 0.217 ops/s > > As Moh mentioned on a different thread, we will work with Sunny on getting the tests to you. > Thanks those number look good. Paul. From aph at redhat.com Tue May 26 09:29:20 2015 From: aph at redhat.com (Andrew Haley) Date: Tue, 26 May 2015 10:29:20 +0100 Subject: Protection of RSA from timing and cache-flushing attacks [Was: RFR(L): 8069539: RSA acceleration] In-Reply-To: <5550CCC0.6000502@redhat.com> References: <02FCFB8477C4EF43A2AD8E0C60F3DA2B63321E33@FMSMSX112.amr.corp.intel.com> <5502E67C.8080208@oracle.com> <02FCFB8477C4EF43A2AD8E0C60F3DA2B63322AB0@FMSMSX112.amr.corp.intel.com> <02FCFB8477C4EF43A2AD8E0C60F3DA2B63323E86@FMSMSX112.amr.corp.intel.com> <550C004D.1060501@redhat.com> <02FCFB8477C4EF43A2AD8E0C60F3DA2B633245C8@FMSMSX112.amr.corp.intel.com> <55101C52.1090506@redhat.com> <5548193E.7060803@oracle.com> <55488803.4020802@redhat.com> <554CDD48.8080500@redhat.com> <554CE68F.20509@redhat.com> <554CF00B.6000508@redhat.com> <5550CCC0.6000502@redhat.com> Message-ID: <55643CF0.8090100@redhat.com> On 05/11/2015 04:37 PM, Florian Weimer wrote: > On 05/08/2015 07:19 PM, Andrew Haley wrote: > >>> Do we want to add side-channel protection as part of this effort >>> (against timing attacks and cache-flushing attacks)? >> >> I wouldn't have thought so. It might make sense to add an optional >> path without key-dependent branches, but not as a part of this effort: >> the goals are completely orthogonal. > > I'm not well-versed in this kind of side-channel protection for RSA > implementations, but my impression that algorithm changes are needed to > mitigate the impact of data-dependent memory fetches (see fixed-width > modular exponentiation). But maybe the necessary changes materialize at > a higher level, beyond the operation which you proposed to intrinsify. By the way: there is quite a bit of code in sun/security/rsa/RSACore.java to protect against timing attacks. In particular, the patch for "8031346: Enhance RSA key handling" looks quite thorough and there is also extra care taken to make padding operations execute in constant time. Andrew. From paul.sandoz at oracle.com Tue May 26 09:54:57 2015 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 26 May 2015 11:54:57 +0200 Subject: Patch to improve primitives Array.sort() In-Reply-To: <67BF3338-6879-445D-AA62-624D2C94B615@oracle.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D2076116796@GSCMAMP06EX.firmwide.corp.gs.com> <67BF3338-6879-445D-AA62-624D2C94B615@oracle.com> Message-ID: <53868C2C-52D1-4D0C-8E7B-BEF86E467983@oracle.com> Here is an updated webrev: http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080945-nearly-sorted-primitives/webrev/ I took the liberty of: - in DualPivotQuicksort sprinkling some more comments; and - moving and renaming the test. Code was also reformatted to better fit the JDK style. I reduced the size array, otherwise it uses a lot of memory and to further reduce memory the runTests method does not create all arrays upfront. Kristen, unfortunately the ' character in your name and email addresses causes some issues with the jcheck tool, which only supports a subset of valid characters [1], so for now i have removed that character from the your name and email address, sorry about that, it's not personal :-) I hope we can get that tool and infrastructure updated before we push. Paul. [1] http://hg.openjdk.java.net/code-tools/jcheck/file/196ab0ad64ad/jcheck.py#l156 On May 22, 2015, at 4:23 PM, Paul Sandoz wrote: > On May 22, 2015, at 3:55 PM, "Rezaei, Mohammad A." wrote: >> We have a set of JMH tests. > > Great. > > I created a bug for this issue: > > https://bugs.openjdk.java.net/browse/JDK-8080945 > > >> We'll work with Sunny to make those part of the webrev (where do they go?) and the specific test you suggested below. >> > > Not actually sure, for now let's keep 'em with the unit test. > > I seem to recall a there was a "space" being arranged for benchmarks but i have forgotten if any progress has been made on that. > > Paul. From alexander.v.stepanov at oracle.com Tue May 26 11:45:01 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Tue, 26 May 2015 14:45:01 +0300 Subject: RFR [9] 8040147: minor cleanup for docs In-Reply-To: <4B6A88A8-9627-4FCE-AEEE-93A726818118@oracle.com> References: <554264A5.1010700@oracle.com> <5562EE0E.2060203@oracle.com> <4B6A88A8-9627-4FCE-AEEE-93A726818118@oracle.com> Message-ID: <55645CBD.9080204@oracle.com> Hello Lance, Thank you. > One suggestion for webrevs is to change to {@code} Please see the updated webrev (Blob.java and Clob.java were changed): http://cr.openjdk.java.net/~avstepan/8040147/webrev.02/jdk.upd01/ Regards, Alexander On 25.05.2015 18:53, Lance Andersen wrote: > Hi Alexander, > > Overal this looks OK. One suggestion for webrevs is to change > to {@code} while you are updating specific comments (not > the entire file, but at least the lines you are touching). > > Thank you for making the changes. > > Best > Lance > On May 25, 2015, at 5:40 AM, alexander stepanov > > wrote: > >> Hello, >> >> Could you please review the fix >> http://cr.openjdk.java.net/~avstepan/8040147/webrev.02/ >> >> for >> https://bugs.openjdk.java.net/browse/JDK-8040147 >> >> Just a minor fix for docs (some tidy warnings + misprints). >> >> Thanks, >> Alexander >> > > > > 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 miroslav.kos at oracle.com Tue May 26 12:24:45 2015 From: miroslav.kos at oracle.com (Miroslav Kos) Date: Tue, 26 May 2015 14:24:45 +0200 Subject: RFR [9] 8080502: Changing accessing module resources In-Reply-To: <555DD0CF.8060407@oracle.com> References: <555B04AE.8040009@oracle.com> <555DD0CF.8060407@oracle.com> Message-ID: <5564660D.3030703@oracle.com> On 21/05/15 14:34, Alan Bateman wrote: > On 19/05/2015 10:38, Miroslav Kos wrote: >> : >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8080502 >> webrev: http://cr.openjdk.java.net/~mkos/8080502/jaxws.01/index.html >> testing: JAX-WS unit test; basically it is fix for existing tests >> (JCK, ...) > One thing that isn't obvious in this code is where the input streams > are closed? Are they closed by whoever is consuming the input stream? > Otherwise I don't see any issues. > > -Alan Thanks, you are correct. Changed to try-catch with resources, the some code moved to SchemaCache. Refernced resources found by com.sun.tools.internal.xjc.SchemaCache.ResourceResolver added to collection and closed after parsing. updated webrev: http://cr.openjdk.java.net/~mkos/8080502/jaxws.02/ tests: rerun standalone tests for bot standalone build and for JDK. Thanks Miran From Lance.Andersen at oracle.com Tue May 26 12:30:24 2015 From: Lance.Andersen at oracle.com (Lance Andersen) Date: Tue, 26 May 2015 08:30:24 -0400 Subject: RFR [9] 8040147: minor cleanup for docs In-Reply-To: <55645CBD.9080204@oracle.com> References: <554264A5.1010700@oracle.com> <5562EE0E.2060203@oracle.com> <4B6A88A8-9627-4FCE-AEEE-93A726818118@oracle.com> <55645CBD.9080204@oracle.com> Message-ID: <783FE606-D4D4-4552-B2C6-B06F5F0D1671@oracle.com> Hi Alexander, the updates look fine as well Best Lance On May 26, 2015, at 7:45 AM, alexander stepanov wrote: > Hello Lance, > > Thank you. > > One suggestion for webrevs is to change to {@code} > Please see the updated webrev (Blob.java and Clob.java were changed): > http://cr.openjdk.java.net/~avstepan/8040147/webrev.02/jdk.upd01/ > > Regards, > Alexander > > On 25.05.2015 18:53, Lance Andersen wrote: >> Hi Alexander, >> >> Overal this looks OK. One suggestion for webrevs is to change to {@code} while you are updating specific comments (not the entire file, but at least the lines you are touching). >> >> Thank you for making the changes. >> >> Best >> Lance >> On May 25, 2015, at 5:40 AM, alexander stepanov > wrote: >> >>> Hello, >>> >>> Could you please review the fix >>> http://cr.openjdk.java.net/~avstepan/8040147/webrev.02/ >>> for >>> https://bugs.openjdk.java.net/browse/JDK-8040147 >>> >>> Just a minor fix for docs (some tidy warnings + misprints). >>> >>> Thanks, >>> Alexander >>> >> >> >> >> 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 alexander.v.stepanov at oracle.com Tue May 26 12:39:32 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Tue, 26 May 2015 15:39:32 +0300 Subject: RFR [9] 8040147: minor cleanup for docs In-Reply-To: <783FE606-D4D4-4552-B2C6-B06F5F0D1671@oracle.com> References: <554264A5.1010700@oracle.com> <5562EE0E.2060203@oracle.com> <4B6A88A8-9627-4FCE-AEEE-93A726818118@oracle.com> <55645CBD.9080204@oracle.com> <783FE606-D4D4-4552-B2C6-B06F5F0D1671@oracle.com> Message-ID: <55646984.7050808@oracle.com> Thanks! On 26.05.2015 15:30, Lance Andersen wrote: > Hi Alexander, > > the updates look fine as well > > Best > Lance > On May 26, 2015, at 7:45 AM, alexander stepanov > > wrote: > >> Hello Lance, >> >> Thank you. >> > One suggestion for webrevs is to change to {@code} >> Please see the updated webrev (Blob.java and Clob.java were changed): >> http://cr.openjdk.java.net/~avstepan/8040147/webrev.02/jdk.upd01/ >> >> >> Regards, >> Alexander >> >> On 25.05.2015 18:53, Lance Andersen wrote: >>> Hi Alexander, >>> >>> Overal this looks OK. One suggestion for webrevs is to change >>> to {@code} while you are updating specific comments >>> (not the entire file, but at least the lines you are touching). >>> >>> Thank you for making the changes. >>> >>> Best >>> Lance >>> On May 25, 2015, at 5:40 AM, alexander stepanov >>> >> > wrote: >>> >>>> Hello, >>>> >>>> Could you please review the fix >>>> http://cr.openjdk.java.net/~avstepan/8040147/webrev.02/ >>>> >>>> for >>>> https://bugs.openjdk.java.net/browse/JDK-8040147 >>>> >>>> Just a minor fix for docs (some tidy warnings + misprints). >>>> >>>> Thanks, >>>> Alexander >>>> >>> >>> >>> >>> 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 dmitry.samersoff at oracle.com Tue May 26 14:14:24 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Tue, 26 May 2015 17:14:24 +0300 Subject: RFR(M,v7): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> Message-ID: <55647FC0.7050901@oracle.com> On 2015-05-21 02:07, Mandy Chung wrote: > >> On May 19, 2015, at 11:51 PM, Dmitry Samersoff >> > wrote: >> >> Other alternatives could be to do all hashing/sorting/printing on native >> layer i.e. implement printFinalizationQueue inside VM. >> >> Both options has pros and cons - Java based solution requires less JNI >> calls and better readable but takes more memory. >> >> It might be better to return an array of Map.Entry >> objects to VM rather than one huge string. > > The output and formatting should be done by jcmd. done. > What you really need > to get a peek on the finalizer queue and print the histogram. The VM > has the heap histogram implementation. Have you considered leveraging > that? > > 5: 1012 40480 java.lang.ref.Finalizer One of previous versions count total a number of instances registered for finalization but then we decided that number of unreachable instances awaiting finalization has more value for customer. > You can find the registered Finalizer instances. The downside is that > icmd -finalizerinfo stops the world. I think it?s not unreasonable for > this diagnostic command to be expensive like -heap command. Current implementation is lock-free and don't stop the world, we decided to make it less expensive at the cost of less accurate results. -Dmitry -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From dmitry.samersoff at oracle.com Tue May 26 14:16:10 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Tue, 26 May 2015 17:16:10 +0300 Subject: RFR(M,v9): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> Message-ID: <5564802A.2010403@oracle.com> Hi Everybody, http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.09/ Please review updated webrev - printFinalizationQueue now returns and array of Map.Entry >> On May 19, 2015, at 11:51 PM, Dmitry Samersoff >> > wrote: >> >> Other alternatives could be to do all hashing/sorting/printing on native >> layer i.e. implement printFinalizationQueue inside VM. >> >> Both options has pros and cons - Java based solution requires less JNI >> calls and better readable but takes more memory. >> >> It might be better to return an array of Map.Entry >> objects to VM rather than one huge string. > > The output and formatting should be done by jcmd. What you really need > to get a peek on the finalizer queue and print the histogram. The VM > has the heap histogram implementation. Have you considered leveraging > that? > > 5: 1012 40480 java.lang.ref.Finalizer > > You can find the registered Finalizer instances. The downside is that > icmd -finalizerinfo stops the world. I think it?s not unreasonable for > this diagnostic command to be expensive like -heap command. > > Mandy -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From mark.reinhold at oracle.com Tue May 26 15:39:09 2015 From: mark.reinhold at oracle.com (mark.reinhold at oracle.com) Date: Tue, 26 May 2015 08:39:09 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556231BE.9050703@oracle.com> References: <556231BE.9050703@oracle.com> Message-ID: <20150526083909.396455@eggemoggin.niobe.net> Your micro-benchmark improvements are significant, but do you have evidence to suggest that the performance of this method is actually critical to real applications? In other words, is the added code complexity really worth it? - Mark From chris.hegarty at oracle.com Tue May 26 15:45:41 2015 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 26 May 2015 16:45:41 +0100 Subject: RFR 8080835 [9] Add blocking bulk read to java.io.InputStream In-Reply-To: <555C9B3D.9000201@oracle.com> References: <55395551.1070100@Oracle.com> <55396320.2070307@Oracle.com> <31EC1590-B334-4154-8981-125542ACA37B@oracle.com> <55434D4E.1080305@oracle.com> <55438B92.4080701@Oracle.com> <7370B278-7F53-42B7-8CD2-38F4005BD6A2@oracle.com> <55489355.9010601@oracle.com> <05BA5AC3-3492-4D4C-B751-0F86EE9DB432@oracle.com> <555C976E.4050604@oracle.com> <555C9B3D.9000201@oracle.com> Message-ID: <26FA9DBC-E200-4572-A528-A131CBC16ECB@oracle.com> The spec changes have been finalised and agreed. This is a final review call, for implementation and test coverage. http://cr.openjdk.java.net/~chegar/8080835/webrev.00/ -Chris. On 20 May 2015, at 15:33, Chris Hegarty wrote: > On 20/05/15 15:17, Alan Bateman wrote: >> On 14/05/2015 09:26, Chris Hegarty wrote: >>> I think we?ve agreed that we are not going to attempt to re-introduce >>> the problematic interruptible I/O mechanism. These new methods are >>> targeted at specific use-cases and common patterns found in code. I?d >>> like to do a final review of the spec before finalising it. >>> >>> http://cr.openjdk.java.net/~chegar/readBytes/webrev.00 >> I read through the javadoc and it looks good. > > Thanks Alan. > >> A passing comment is that the areas of the byte array that aren't >> touched by readNBytes seems a bit much and a distraction to have it >> covered in two paragraphs. > > Roger made the very same comment. I justified the duplication as the paragraphs are covering potentially two different cases. One where some data is read, and the other when no data is read. > > Given this has some up twice now, I'll just remove the second paragraph. > >> In @param b then it says "buffer" when I assume it should be "byte >> array" to be consistent with the method description. > > Fixed. > > Thanks, > -Chris. > >> -Alan >> From ivan.gerasimov at oracle.com Tue May 26 16:36:06 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 26 May 2015 19:36:06 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <20150526083909.396455@eggemoggin.niobe.net> References: <556231BE.9050703@oracle.com> <20150526083909.396455@eggemoggin.niobe.net> Message-ID: <5564A0F6.9020808@oracle.com> Thank you Mark for looking at this! On 26.05.2015 18:39, mark.reinhold at oracle.com wrote: > Your micro-benchmark improvements are significant, but do you have > evidence to suggest that the performance of this method is actually > critical to real applications? > > In other words, is the added code complexity really worth it? The enhancement request contains a few links to the discussions of this method's performance at open forums. The most frequent suggestion is to use alternatives from 3rd party libraries. That should prove the benefits of this fix -- by improving performance we can keep some users from moving away from JDK :) grep shows that langtools would also benefit from making replace() faster. Sincerely yours, Ivan > - Mark > > From Roger.Riggs at Oracle.com Tue May 26 16:40:21 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 26 May 2015 12:40:21 -0400 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5564A0F6.9020808@oracle.com> References: <556231BE.9050703@oracle.com> <20150526083909.396455@eggemoggin.niobe.net> <5564A0F6.9020808@oracle.com> Message-ID: <5564A1F5.1020109@Oracle.com> Hi Ivan, Did you consider doing the optimization inside of Pattern.compile/replaceAll. That would have a broader impact and benefit. Roger On 5/26/2015 12:36 PM, Ivan Gerasimov wrote: > Thank you Mark for looking at this! > > On 26.05.2015 18:39, mark.reinhold at oracle.com wrote: >> Your micro-benchmark improvements are significant, but do you have >> evidence to suggest that the performance of this method is actually >> critical to real applications? >> >> In other words, is the added code complexity really worth it? > > The enhancement request contains a few links to the discussions of > this method's performance at open forums. > The most frequent suggestion is to use alternatives from 3rd party > libraries. > > That should prove the benefits of this fix -- by improving performance > we can keep some users from moving away from JDK :) > > grep shows that langtools would also benefit from making replace() > faster. > > Sincerely yours, > Ivan > >> - Mark >> >> > From Kristen.O'Leary at gs.com Fri May 22 19:56:02 2015 From: Kristen.O'Leary at gs.com (O'Leary, Kristen) Date: Fri, 22 May 2015 15:56:02 -0400 Subject: Patch to improve primitives Array.sort() In-Reply-To: <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> References: <1CF6FDFD0639DF478B44651D79ECE70401104C1917@GSCMHKP12EX.firmwide.corp.gs.com> <4911D592-3065-4416-A683-6B80275B4173@oracle.com> <553A0832.7070702@oracle.com> <4725EC08FFA7B84AB611B2463BDA97ED1B3F978D2D@GSCMAMP30EX.firmwide.corp.gs.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4F10@GSCMHKP12EX.firmwide.corp.gs.com> <24BCB588-1A4F-4419-81A4-CD947828E5C2@oracle.com> <1CF6FDFD0639DF478B44651D79ECE70401146C4FB7@GSCMHKP12EX.firmwide.corp.gs.com> <2090E8E4-4AD4-4F7C-84AB-A77625FE221B@oracle.com> <6882C9A35DFB9B4FA2779F7BF5B9757D207611678C@GSCMAMP06EX.firmwide.corp.gs.com> <3251F9D5-C128-4C12-A514-803A17B65190@oracle.com> Message-ID: <4725EC08FFA7B84AB611B2463BDA97ED1BC3DF5E1C@GSCMAMP30EX.firmwide.corp.gs.com> Hi Paul, We've created an additional test based on your suggestion: an array of size 10,000,000, 32 pair flips, a run of zeroes in the middle, and 32 pair flips at the end. Here are the results for int: Benchmark (listType) Mode Cnt Score Error Units SortingIntTestJMH.sortCurrentWay pairFlipZeroPairFlip thrpt 10 4.886 ? 0.031 ops/s SortingIntTestJMH.sortNewWay pairFlipZeroPairFlip thrpt 10 14.793 ? 0.217 ops/s We also created a similar test which is 10, 5 repeated 32 times, a run of 100 in the middle, and 10, 5 repeated 32 times at the end. Here are the results again for int: Benchmark (listType) Mode Cnt Score Error Units SortingIntTestJMH.sortCurrentWay pairFlipOneHundredPairFlip thrpt 10 4.936 ? 0.040 ops/s SortingIntTestJMH.sortNewWay pairFlipOneHundredPairFlip thrpt 10 18.472 ? 0.217 ops/s As Moh mentioned on a different thread, we will work with Sunny on getting the tests to you. Thanks, Kristen -----Original Message----- From: Paul Sandoz [mailto:paul.sandoz at oracle.com] Sent: Friday, May 22, 2015 4:02 AM To: Rezaei, Mohammad A. [Tech] Cc: 'core-libs-dev at openjdk.java.net Libs'; Chan, Sunny [Tech]; O'Leary, Kristen [Tech] Subject: Re: Patch to improve primitives Array.sort() On May 22, 2015, at 1:52 AM, "Rezaei, Mohammad A." wrote: > Thanks Paul. Your proposed changes make sense to us and they have no discernable impact on the performance. > Great, thanks. I am happy to update the current webrev (and also create an associated issue). Sorry to drag this out a little more, but i am still curious as to why MAX_RUN_LENGTH was ever there in the first place. AFAICT it was empirically derived: http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-February/005821.html http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-January/005713.html But there is no further information as to why this particular behaviour was required. Is there something about an equals-run > MAX_RUN_LENGTH (33) where an optimized merge sort performs poorly? I could have missed something but i don't see any data in either of the sorting tests that would exercise this case. Perhaps we need to performance test against a data set of + [+ ] for a total number of runs < MAX_RUN_COUNT (67) ? More generally it's probably worth investing in a set of related JMH tests based on Sorting test combinations and data shapes, as we don't currently have easy visibility into performance regressions due to code changes or perhaps due to changes in hotspot. Paul. From ivan.gerasimov at oracle.com Tue May 26 17:08:54 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 26 May 2015 20:08:54 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5564A1F5.1020109@Oracle.com> References: <556231BE.9050703@oracle.com> <20150526083909.396455@eggemoggin.niobe.net> <5564A0F6.9020808@oracle.com> <5564A1F5.1020109@Oracle.com> Message-ID: <5564A8A6.7070009@oracle.com> Thank you Roger for looking at this! On 26.05.2015 19:40, Roger Riggs wrote: > Hi Ivan, > > Did you consider doing the optimization inside of > Pattern.compile/replaceAll. > That would have a broader impact and benefit. > In Pattern.compile the flag LITERAL can be combined with several other flags, which makes things more complex. However, in String.replace we've got a special case, which can be optimized in a straight-forward (though a little bit verbose) way. Sincerely yours, Ivan > Roger > > > On 5/26/2015 12:36 PM, Ivan Gerasimov wrote: >> Thank you Mark for looking at this! >> >> On 26.05.2015 18:39, mark.reinhold at oracle.com wrote: >>> Your micro-benchmark improvements are significant, but do you have >>> evidence to suggest that the performance of this method is actually >>> critical to real applications? >>> >>> In other words, is the added code complexity really worth it? >> >> The enhancement request contains a few links to the discussions of >> this method's performance at open forums. >> The most frequent suggestion is to use alternatives from 3rd party >> libraries. >> >> That should prove the benefits of this fix -- by improving >> performance we can keep some users from moving away from JDK :) >> >> grep shows that langtools would also benefit from making replace() >> faster. >> >> Sincerely yours, >> Ivan >> >>> - Mark >>> >>> >> > > > From xueming.shen at oracle.com Tue May 26 17:17:16 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 26 May 2015 10:17:16 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5564A8A6.7070009@oracle.com> References: <556231BE.9050703@oracle.com> <20150526083909.396455@eggemoggin.niobe.net> <5564A0F6.9020808@oracle.com> <5564A1F5.1020109@Oracle.com> <5564A8A6.7070009@oracle.com> Message-ID: <5564AA9C.1090100@oracle.com> On 5/26/15 10:08 AM, Ivan Gerasimov wrote: > Thank you Roger for looking at this! > > On 26.05.2015 19:40, Roger Riggs wrote: >> Hi Ivan, >> >> Did you consider doing the optimization inside of >> Pattern.compile/replaceAll. >> That would have a broader impact and benefit. >> > > In Pattern.compile the flag LITERAL can be combined with several other > flags, which makes things more complex. > However, in String.replace we've got a special case, which can be > optimized in a straight-forward (though a little bit verbose) way. It probably makes big difference to access those characters via CharSequence.charAt() and the direct internal char[] access. Though avoiding allocating those objects created by Pattern/Matcher/SB definitely helps. -Sherman > > Sincerely yours, > Ivan > >> Roger >> >> >> On 5/26/2015 12:36 PM, Ivan Gerasimov wrote: >>> Thank you Mark for looking at this! >>> >>> On 26.05.2015 18:39, mark.reinhold at oracle.com wrote: >>>> Your micro-benchmark improvements are significant, but do you have >>>> evidence to suggest that the performance of this method is actually >>>> critical to real applications? >>>> >>>> In other words, is the added code complexity really worth it? >>> >>> The enhancement request contains a few links to the discussions of >>> this method's performance at open forums. >>> The most frequent suggestion is to use alternatives from 3rd party >>> libraries. >>> >>> That should prove the benefits of this fix -- by improving >>> performance we can keep some users from moving away from JDK :) >>> >>> grep shows that langtools would also benefit from making replace() >>> faster. >>> >>> Sincerely yours, >>> Ivan >>> >>>> - Mark >>>> >>>> >>> >> >> >> > From tomasz.kowalczewski at gmail.com Tue May 26 17:26:55 2015 From: tomasz.kowalczewski at gmail.com (Tomasz Kowalczewski) Date: Tue, 26 May 2015 19:26:55 +0200 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5564AA9C.1090100@oracle.com> References: <556231BE.9050703@oracle.com> <20150526083909.396455@eggemoggin.niobe.net> <5564A0F6.9020808@oracle.com> <5564A1F5.1020109@Oracle.com> <5564A8A6.7070009@oracle.com> <5564AA9C.1090100@oracle.com> Message-ID: I second that. API accepts CharSequence for a reason. The benchmarks might look a little different if you pass StringBuilder in a call to replace. It looks like removing toString() call on CharSequences will be easy with one drawback of loosing the benefit of System.arraycopy call. Note that String.indexOf requires String argument but that can also be fixed. -- Tomasz On Tue, May 26, 2015 at 7:17 PM, Xueming Shen wrote: > On 5/26/15 10:08 AM, Ivan Gerasimov wrote: > >> Thank you Roger for looking at this! >> >> On 26.05.2015 19:40, Roger Riggs wrote: >> >>> Hi Ivan, >>> >>> Did you consider doing the optimization inside of >>> Pattern.compile/replaceAll. >>> That would have a broader impact and benefit. >>> >>> >> In Pattern.compile the flag LITERAL can be combined with several other >> flags, which makes things more complex. >> However, in String.replace we've got a special case, which can be >> optimized in a straight-forward (though a little bit verbose) way. >> > > It probably makes big difference to access those characters via > CharSequence.charAt() > and the direct internal char[] access. Though avoiding allocating those > objects created > by Pattern/Matcher/SB definitely helps. > > -Sherman > > > >> Sincerely yours, >> Ivan >> >> Roger >>> >>> >>> On 5/26/2015 12:36 PM, Ivan Gerasimov wrote: >>> >>>> Thank you Mark for looking at this! >>>> >>>> On 26.05.2015 18:39, mark.reinhold at oracle.com wrote: >>>> >>>>> Your micro-benchmark improvements are significant, but do you have >>>>> evidence to suggest that the performance of this method is actually >>>>> critical to real applications? >>>>> >>>>> In other words, is the added code complexity really worth it? >>>>> >>>> >>>> The enhancement request contains a few links to the discussions of this >>>> method's performance at open forums. >>>> The most frequent suggestion is to use alternatives from 3rd party >>>> libraries. >>>> >>>> That should prove the benefits of this fix -- by improving performance >>>> we can keep some users from moving away from JDK :) >>>> >>>> grep shows that langtools would also benefit from making replace() >>>> faster. >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>> - Mark >>>>> >>>>> >>>>> >>>> >>> >>> >>> >> > -- Tomasz Kowalczewski From ivan.gerasimov at oracle.com Tue May 26 17:39:22 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 26 May 2015 20:39:22 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: References: <556231BE.9050703@oracle.com> <20150526083909.396455@eggemoggin.niobe.net> <5564A0F6.9020808@oracle.com> <5564A1F5.1020109@Oracle.com> <5564A8A6.7070009@oracle.com> <5564AA9C.1090100@oracle.com> Message-ID: <5564AFCA.2040909@oracle.com> But the current implementation converts the argument to String in the first place too: return Pattern.compile(*target.toString()*, Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(*replacement.toString()*)); So I didn't introduce this conversion :-) When browsing the source code, looking for usages of this method, I only saw Strings passed as the parameters. Thus, I guess it is reasonable to have the variant which works best in this case. Sincerely yours, Ivan On 26.05.2015 20:26, Tomasz Kowalczewski wrote: > I second that. API accepts CharSequence for a reason. The benchmarks might > look a little different if you pass StringBuilder in a call to replace. It > looks like removing toString() call on CharSequences will be easy with one > drawback of loosing the benefit of System.arraycopy call. Note that > String.indexOf requires String argument but that can also be fixed. > > -- > Tomasz > > On Tue, May 26, 2015 at 7:17 PM, Xueming Shen > wrote: > >> On 5/26/15 10:08 AM, Ivan Gerasimov wrote: >> >>> Thank you Roger for looking at this! >>> >>> On 26.05.2015 19:40, Roger Riggs wrote: >>> >>>> Hi Ivan, >>>> >>>> Did you consider doing the optimization inside of >>>> Pattern.compile/replaceAll. >>>> That would have a broader impact and benefit. >>>> >>>> >>> In Pattern.compile the flag LITERAL can be combined with several other >>> flags, which makes things more complex. >>> However, in String.replace we've got a special case, which can be >>> optimized in a straight-forward (though a little bit verbose) way. >>> >> It probably makes big difference to access those characters via >> CharSequence.charAt() >> and the direct internal char[] access. Though avoiding allocating those >> objects created >> by Pattern/Matcher/SB definitely helps. >> >> -Sherman >> >> >> >>> Sincerely yours, >>> Ivan >>> >>> Roger >>>> >>>> On 5/26/2015 12:36 PM, Ivan Gerasimov wrote: >>>> >>>>> Thank you Mark for looking at this! >>>>> >>>>> On 26.05.2015 18:39, mark.reinhold at oracle.com wrote: >>>>> >>>>>> Your micro-benchmark improvements are significant, but do you have >>>>>> evidence to suggest that the performance of this method is actually >>>>>> critical to real applications? >>>>>> >>>>>> In other words, is the added code complexity really worth it? >>>>>> >>>>> The enhancement request contains a few links to the discussions of this >>>>> method's performance at open forums. >>>>> The most frequent suggestion is to use alternatives from 3rd party >>>>> libraries. >>>>> >>>>> That should prove the benefits of this fix -- by improving performance >>>>> we can keep some users from moving away from JDK :) >>>>> >>>>> grep shows that langtools would also benefit from making replace() >>>>> faster. >>>>> >>>>> Sincerely yours, >>>>> Ivan >>>>> >>>>> - Mark >>>>>> >>>>>> >>>> >>>> > From tomasz.kowalczewski at gmail.com Tue May 26 18:19:25 2015 From: tomasz.kowalczewski at gmail.com (Tomasz Kowalczewski) Date: Tue, 26 May 2015 20:19:25 +0200 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5564AFCA.2040909@oracle.com> References: <556231BE.9050703@oracle.com> <20150526083909.396455@eggemoggin.niobe.net> <5564A0F6.9020808@oracle.com> <5564A1F5.1020109@Oracle.com> <5564A8A6.7070009@oracle.com> <5564AA9C.1090100@oracle.com> <5564AFCA.2040909@oracle.com> Message-ID: I know it was like that before :) I asked similar question about fixing String.contains to not call toString on it's CharSequence argument ( http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-March/032394.html). Responses were generally encouraging. Regards, Tomasz On Tue, May 26, 2015 at 7:39 PM, Ivan Gerasimov wrote: > But the current implementation converts the argument to String in the > first place too: > > return Pattern.compile(*target.toString()*, > Pattern.LITERAL).matcher( > this).replaceAll(Matcher.quoteReplacement( > *replacement.toString()*)); > > So I didn't introduce this conversion :-) > > When browsing the source code, looking for usages of this method, I only > saw Strings passed as the parameters. > Thus, I guess it is reasonable to have the variant which works best in > this case. > > Sincerely yours, > Ivan > > > On 26.05.2015 20:26, Tomasz Kowalczewski wrote: > > I second that. API accepts CharSequence for a reason. The benchmarks might > look a little different if you pass StringBuilder in a call to replace. It > looks like removing toString() call on CharSequences will be easy with one > drawback of loosing the benefit of System.arraycopy call. Note that > String.indexOf requires String argument but that can also be fixed. > > -- > Tomasz > > On Tue, May 26, 2015 at 7:17 PM, Xueming Shen > wrote: > > > On 5/26/15 10:08 AM, Ivan Gerasimov wrote: > > > Thank you Roger for looking at this! > > On 26.05.2015 19:40, Roger Riggs wrote: > > > Hi Ivan, > > Did you consider doing the optimization inside of > Pattern.compile/replaceAll. > That would have a broader impact and benefit. > > > > In Pattern.compile the flag LITERAL can be combined with several other > flags, which makes things more complex. > However, in String.replace we've got a special case, which can be > optimized in a straight-forward (though a little bit verbose) way. > > > It probably makes big difference to access those characters via > CharSequence.charAt() > and the direct internal char[] access. Though avoiding allocating those > objects created > by Pattern/Matcher/SB definitely helps. > > -Sherman > > > > > Sincerely yours, > Ivan > > Roger > > > On 5/26/2015 12:36 PM, Ivan Gerasimov wrote: > > > Thank you Mark for looking at this! > > On 26.05.2015 18:39, mark.reinhold at oracle.com wrote: > > > Your micro-benchmark improvements are significant, but do you have > evidence to suggest that the performance of this method is actually > critical to real applications? > > In other words, is the added code complexity really worth it? > > > The enhancement request contains a few links to the discussions of this > method's performance at open forums. > The most frequent suggestion is to use alternatives from 3rd party > libraries. > > That should prove the benefits of this fix -- by improving performance > we can keep some users from moving away from JDK :) > > grep shows that langtools would also benefit from making replace() > faster. > > Sincerely yours, > Ivan > > - Mark > > > > > -- Tomasz Kowalczewski From derek.white at oracle.com Tue May 26 18:43:46 2015 From: derek.white at oracle.com (Derek White) Date: Tue, 26 May 2015 14:43:46 -0400 Subject: RFR(M,v9): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5564802A.2010403@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> <5564802A.2010403@oracle.com> Message-ID: <5564BEE2.7020105@oracle.com> On 5/26/15 10:16 AM, Dmitry Samersoff wrote: > Hi Everybody, > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.09/ > > Please review updated webrev - > > printFinalizationQueue now returns and array of Map.Entry and all formatting is done on VM side. > > -Dmitry Hi Dmitry, I looked at the jdk_webrev. Everything looks great except the spacing looks off in line 124 of Finalizer.java. My JNI is too rusty to provide a quick opinion on the hotspot_webrev portion. - Derek > > On 2015-05-21 02:07, Mandy Chung wrote: >>> On May 19, 2015, at 11:51 PM, Dmitry Samersoff >>> > wrote: >>> >>> Other alternatives could be to do all hashing/sorting/printing on native >>> layer i.e. implement printFinalizationQueue inside VM. >>> >>> Both options has pros and cons - Java based solution requires less JNI >>> calls and better readable but takes more memory. >>> >>> It might be better to return an array of Map.Entry >>> objects to VM rather than one huge string. >> The output and formatting should be done by jcmd. What you really need >> to get a peek on the finalizer queue and print the histogram. The VM >> has the heap histogram implementation. Have you considered leveraging >> that? >> >> 5: 1012 40480 java.lang.ref.Finalizer >> >> You can find the registered Finalizer instances. The downside is that >> icmd -finalizerinfo stops the world. I think it?s not unreasonable for >> this diagnostic command to be expensive like -heap command. >> >> Mandy > From xueming.shen at oracle.com Tue May 26 19:23:09 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 26 May 2015 12:23:09 -0700 Subject: RFR JDK-8028480: (zipfs) NoSuchFileException on creating a file in ZipFileSystem with CREATE and WRITE Message-ID: <5564C81D.7050403@oracle.com> Hi, Please help review the changes for JDK-8028480 and JDK-8034773 issues: https://bugs.openjdk.java.net/browse/JDK-8028480 https://bugs.openjdk.java.net/browse/JDK-8034773 webrev: http://cr.openjdk.java.net/~sherman/8028480_8034773/ Thanks, -Sherman From Alan.Bateman at oracle.com Tue May 26 19:33:03 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 26 May 2015 20:33:03 +0100 Subject: RFR JDK-8060161: re-examine sun/nio/cs/Test4200310.sh, test is invalid for modular image In-Reply-To: <555F5669.8090409@oracle.com> References: <555F5669.8090409@oracle.com> Message-ID: <5564CA6F.80808@oracle.com> On 22/05/2015 17:16, Xueming Shen wrote: > Alan, I agree that we should just remove this old regression test. It > does not server an purpose after those jar files are gone. > Please help review. > > issue: https://bugs.openjdk.java.net/browse/JDK-8060161 > webrev: http://cr.openjdk.java.net/~sherman/8060161/ Looks good. -Alan From mandy.chung at oracle.com Tue May 26 20:56:18 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 26 May 2015 13:56:18 -0700 Subject: RFR JDK-8060161: re-examine sun/nio/cs/Test4200310.sh, test is invalid for modular image In-Reply-To: <555F5669.8090409@oracle.com> References: <555F5669.8090409@oracle.com> Message-ID: <5564DDF2.5040705@oracle.com> Looks fine. Mandy On 05/22/2015 09:16 AM, Xueming Shen wrote: > Alan, I agree that we should just remove this old regression test. It > does not server an purpose after those jar files are gone. > Please help review. > > issue: https://bugs.openjdk.java.net/browse/JDK-8060161 > webrev: http://cr.openjdk.java.net/~sherman/8060161/ > > -Sherman From miroslav.kos at oracle.com Tue May 26 22:50:12 2015 From: miroslav.kos at oracle.com (Miroslav Kos) Date: Wed, 27 May 2015 00:50:12 +0200 Subject: RFR [9] 8072839: JAX-B Plugability Layer: using java.util.ServiceLoader In-Reply-To: <555C8C7B.7060801@oracle.com> References: <55560D2B.3040400@oracle.com> <555C8C7B.7060801@oracle.com> Message-ID: <5564F8A4.5050602@oracle.com> On 20/05/15 15:30, Daniel Fuchs wrote: > Hi Miroslav, > > I haven't looked in all details, but this text in JAXBContext.java looks > odd to me - it seems that the bullet is repeated twice (or if they > differ - the diff must be subtle): > > lines 241-257 seem identical to lines 259-275 > > 241 *
  • > 242 * Look for resource > /META-INF/services/javax.xml.bind.JAXBContext using provided > class loader. > 243 * Methods without class loader parameter use {@code > Thread.currentThread().getContextClassLoader()}. > 244 * If such a resource exists, its content is assumed to be the > provider factory class and must supply > 245 * an implementation class containing the following method > signatures: > 246 * > 247 *
    >  248  *
    >  249  * public static JAXBContext createContext(
    >  250  *                                      String contextPath,
    >  251  *                                      ClassLoader classLoader,
    >  252  * Map<String,Object> properties throws JAXBException
    >  253  *
    >  254  * public static JAXBContext createContext(
    >  255  *                                      Class[] classes,
    >  256  * Map<String,Object> properties ) throws JAXBException
    >  257  * 
    > 258 * > 259 *
  • > 260 * Look for resource > /META-INF/services/javax.xml.bind.JAXBContext using provided > class loader. > 261 * Methods without class loader parameter use {@code > Thread.currentThread().getContextClassLoader()}. > 262 * If such a resource exists, its content is assumed to be the > provider factory class and must supply > 263 * an implementation class containing the following method > signatures: > 264 * > 265 *
    >  266  *
    >  267  * public static JAXBContext createContext(
    >  268  *                                      String contextPath,
    >  269  *                                      ClassLoader classLoader,
    >  270  * Map<String,Object> properties throws JAXBException
    >  271  *
    >  272  * public static JAXBContext createContext(
    >  273  *                                      Class[] classes,
    >  274  * Map<String,Object> properties ) throws JAXBException
    >  275  * 
    Hi Daniel, thanks for catching this - obviously incorrectly applied patch. > > So if I understand well - this is somewhat similar to what > ServiceLoader does in terms of lookup, except that the > mechanism defined here does not use an instance of the > declared class, nor require that the class declared in > /META-INF/services/javax.xml.bind.JAXBContext > is a subclass of JAXBContext - but simply that it defines > the appropriate static factory methods... Yes, exactly. It is "ServiceLoader like" implementation from times when ServiceLoader wasn't in jdk yet (jdk5). > > Maybe the fact that this step is deprecated should be noted more > prominently in the bullet itself. I added a note mentioning that the step is deprecated. Corrected version: http://cr.openjdk.java.net/~mkos/8072839/jaxws.03/ I also came over the changed files and added new lines to make lines shorter. Thanks Miran > > best regards, > > -- daniel > > On 15/05/15 17:13, Miroslav Kos wrote: >> Hi everybody, >> >> this is review request for: 8072839: JAX-B Plugability Layer: using >> java.util.ServiceLoader >> The JAX-B API changed a little bit - proprietary ServiceLoader-like code >> has been replaced by java.util.ServiceLoader. This change is required by >> Jigsaw, old configuration way still supported. >> >> JBS:https://bugs.openjdk.java.net/browse/JDK-8072839 >> webrev: http://cr.openjdk.java.net/~mkos/8072839/jaxws.02/index.html >> CCC: http://ccc.us.oracle.com/8072839 >> >> Testing: JAX-WS (standalone) unit tests, no, jtreg tests available now, >> TCK/JCK tests will require new tests. >> >> Thanks >> Miran >> > From ivan.gerasimov at oracle.com Tue May 26 23:11:14 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 27 May 2015 02:11:14 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556231BE.9050703@oracle.com> References: <556231BE.9050703@oracle.com> Message-ID: <5564FD92.2050408@oracle.com> I updated the webrev: http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE with Integer.MAX_VALUE, which seems to be more accurate here. And I want to add that this proposed implementation is not only faster, but also more memory efficient. The following simple stress-test shows that the proposed version is able to handle twice larger strings, comparing to the current implementation. ---------------------------------------- public class C { public static void main(String[] args) throws Throwable { String s = "string"; for (int i = 1; i < Integer.MAX_VALUE; ++i) { try { s = s.replace("string", "stringstring"); } catch (OutOfMemoryError o) { System.out.println(i + ") " + s.length()); break; } } } } ---------------------------------------- $ time ~/java9/jdk/bin/java -showversion -Xmx1g C java version "1.9.0-ea" Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) 25) 100663296 real 0m4.525s user 0m4.402s sys 0m1.189s $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C java version "1.9.0-internal" Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_23_19_25-b00) Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) 26) 201326592 real 0m2.139s user 0m1.960s sys 0m0.461s Sincerely yours, Ivan On 24.05.2015 23:17, Ivan Gerasimov wrote: > Hello everybody! > > I know many people here like it when the performance is getting better. > It was suggested to make the literal variant of String.replace() faster. > Currently, this method is implemented as a few calls to regexp API, so > that the whole implementation takes only two lines of code. > > I've created two versions of the fix. > In the first one, we scan the string and store indices of the found > substrings in an array. > Then, we allocate the precisely sized char array and fill it it. > The case with the empty target has to be handled separately. > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 > WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ > > The second variant is much less verbose, however it's less efficient too. > Here the StringJoiner is used as an intermediate storage. > > WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ > > > Here are the micro-benchmark results (in a string of ~300 chars do ~15 > replacements). > 0) Baseline > MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s > > 1) Heavy-duty +308% > MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s > > 2) StringJoiner +190% > MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s > > > Personally, I like my first variant better, even though it adds almost > 300 lines of code. > But I'd like to hear what people think of it. > > Sincerely yours, > Ivan > > From xueming.shen at oracle.com Tue May 26 23:38:00 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 26 May 2015 16:38:00 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5564FD92.2050408@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> Message-ID: <556503D8.6000303@oracle.com> Ivan, It might be worth trying String.index + StringBuilder, instead of writing/handling everything yourself. Yes, it inevitably adds an arraycopy at the end to convert the StrinbBuilder to String, but it might have better balance between performance and code complexity. The regex is probably a little heavy for literal string replacement, but StringBuilder should not be that bad ... -Sherman On 5/26/15 4:11 PM, Ivan Gerasimov wrote: > I updated the webrev: > http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ > > In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE with > Integer.MAX_VALUE, which seems to be more accurate here. > > And I want to add that this proposed implementation is not only > faster, but also more memory efficient. > The following simple stress-test shows that the proposed version is > able to handle twice larger strings, comparing to the current > implementation. > > ---------------------------------------- > public class C { > public static void main(String[] args) throws Throwable { > String s = "string"; > for (int i = 1; i < Integer.MAX_VALUE; ++i) { > try { > s = s.replace("string", "stringstring"); > } catch (OutOfMemoryError o) { > System.out.println(i + ") " + s.length()); > break; > } > } > } > } > ---------------------------------------- > > $ time ~/java9/jdk/bin/java -showversion -Xmx1g C > java version "1.9.0-ea" > Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) > Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) > > 25) 100663296 > > real 0m4.525s > user 0m4.402s > sys 0m1.189s > > $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C > java version "1.9.0-internal" > Java(TM) SE Runtime Environment (build > 1.9.0-internal-igerasim_2015_05_23_19_25-b00) > Java HotSpot(TM) 64-Bit Server VM (build > 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) > > 26) 201326592 > > real 0m2.139s > user 0m1.960s > sys 0m0.461s > > Sincerely yours, > Ivan > > On 24.05.2015 23:17, Ivan Gerasimov wrote: >> Hello everybody! >> >> I know many people here like it when the performance is getting better. >> It was suggested to make the literal variant of String.replace() faster. >> Currently, this method is implemented as a few calls to regexp API, >> so that the whole implementation takes only two lines of code. >> >> I've created two versions of the fix. >> In the first one, we scan the string and store indices of the found >> substrings in an array. >> Then, we allocate the precisely sized char array and fill it it. >> The case with the empty target has to be handled separately. >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >> >> The second variant is much less verbose, however it's less efficient >> too. >> Here the StringJoiner is used as an intermediate storage. >> >> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >> >> >> Here are the micro-benchmark results (in a string of ~300 chars do >> ~15 replacements). >> 0) Baseline >> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >> >> 1) Heavy-duty +308% >> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >> >> 2) StringJoiner +190% >> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >> >> >> Personally, I like my first variant better, even though it adds >> almost 300 lines of code. >> But I'd like to hear what people think of it. >> >> Sincerely yours, >> Ivan >> >> > From Roger.Riggs at Oracle.com Wed May 27 02:52:07 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Tue, 26 May 2015 22:52:07 -0400 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: References: <555E499C.6020300@Oracle.com> Message-ID: <55653157.1040202@Oracle.com> Hi, Sadly, but not entirely unexpectedly there is an anomaly in the include files: It seems that Windows does not define O_SYNC and O_DSYNC. To make up for the absence jdk/src/java.base/share/native/libjava/io_util.h conditionally defines them. There is no problem if the system include files appear first, but in the other order, fcntl.h tries to re-define it. In the recommended order, there is no issue. Roger On 5/22/15 1:47 PM, Martin Buchholz wrote: > It's a good idea to order include statements by system dependencies, > jdk dependencies, implementation helpers, BUT order of include > statements should never ever matter. If it does, then we have a bug > that should be fixed. Every header file should be independently > includable, and C files should only Include What They Use. It would > be good for us to test some of that, e.g. can you compile each .h file > as its own translation unit? > > +#include > +#include > + > #include "jni.h" > #include "jni_util.h" > #include "jlong.h" > @@ -32,9 +35,6 @@ > #include "java_io_FileInputStream.h" > -#include > -#include > - > From mandy.chung at oracle.com Wed May 27 06:00:52 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 26 May 2015 23:00:52 -0700 Subject: Review Request 8074432: Move jdeps to jdk.compiler module In-Reply-To: References: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> <5562CC61.30603@oracle.com> Message-ID: <15282D68-346E-4569-A356-2266C1A28CD9@oracle.com> We discussed this offline and revised the proposal to group javap and classfile library together with jdeps in jdk.jdeps module for static analysis tools to live. The jdk.compiler module will contain the compiler and a couple of small tools. Moving out javap and classfile library save about 1.2M uncompressed from jdk.compiler (~11%). The module is named after the primary tool, jdeps in this case. Tools are in JAVA_HOME/bin directory of idk image and so which module jdeps and javap are transparent in the idk image. Revised webrev: http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074432/webrev.01/ This touches many langtools tests to update @modules but should be easy to review. $ du -s -h jdk.jdeps/com/sun/tools/* 816K jdk.jdeps/com/sun/tools/classfile 468K jdk.jdeps/com/sun/tools/javap 400K jdk.jdeps/com/sun/tools/jdeps $ du -s -h jdk.compiler/ 9.1M jdk.compiler/ Mandy From martinrb at google.com Wed May 27 06:50:30 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 26 May 2015 23:50:30 -0700 Subject: RFR: 8080803: sun/nio/cs/FindEncoderBugs.java failing intermittently In-Reply-To: <555E693E.8020609@oracle.com> References: <555E693E.8020609@oracle.com> Message-ID: Not really a review ... but ... if this is really catching a hotspot bug, I would be tempted to leave the test failing to make it more likely that the hotspot bug fix is not swept under the rug and forgotten. On Thu, May 21, 2015 at 4:24 PM, Xueming Shen wrote: > Martin, Alan, Joe, > > Would you please help review the change (as a workaround) for this > "intermittently" problem? > > https://bugs.openjdk.java.net/browse/JDK-8080803 > http://cr.openjdk.java.net/~sherman/8080803 > > It appears the trigger might be that ByteBuffer.get(byte[]) fails to get > the bytes from the buffer "intermittently". > Interestingly this one is always reproducible on my local linux build > (very old os), in which I have to update > couple hotspot headfile to make the build going recently. I filed the > bug#8080904 to let the vm guy take a look. > > Meanwhile the proposed change here is just to "optimized" the ISO2022 code > a little to simple workaround > this issue. I hope this can make the "intermittent failure" go away in our > nightly build. If have time, we definitely > should re-visit the implementation of these ISO2022 :-) > > Thanks, > -Sherman > From martinrb at google.com Wed May 27 06:59:29 2015 From: martinrb at google.com (Martin Buchholz) Date: Tue, 26 May 2015 23:59:29 -0700 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <55653157.1040202@Oracle.com> References: <555E499C.6020300@Oracle.com> <55653157.1040202@Oracle.com> Message-ID: On Tue, May 26, 2015 at 7:52 PM, Roger Riggs wrote: > Hi, > > Sadly, but not entirely unexpectedly there is an anomaly in the include > files: > It seems that Windows does not define O_SYNC and O_DSYNC. > To make up for the absence > jdk/src/java.base/share/native/libjava/io_util.h > conditionally defines them. There is no problem if the system include > files appear > first, but in the other order, fcntl.h tries to re-define it. > In the recommended order, there is no issue. > We should work hard to remove order dependencies in include files. I see that io_util.h includes , but only on BSD. Why not include it wherever it is available, (which may be all supported platforms!) before trying to define O_SYNC and D_SYNC? From Alan.Bateman at oracle.com Wed May 27 07:34:04 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 27 May 2015 08:34:04 +0100 Subject: RFR: 8080803: sun/nio/cs/FindEncoderBugs.java failing intermittently In-Reply-To: References: <555E693E.8020609@oracle.com> Message-ID: <5565736C.3040809@oracle.com> On 27/05/2015 07:50, Martin Buchholz wrote: > Not really a review ... but ... if this is really catching a hotspot bug, I > would be tempted to leave the test failing to make it more likely that the > hotspot bug fix is not swept under the rug and forgotten. I would agree except that there is a reproducer for the hotspot issue [1]. Also the patch to ISO2022 is an improvement (maybe clean-up/re-write some day if someone gets cycles). -Alan [1] https://bugs.openjdk.java.net/browse/JDK-8080904 From peter.levart at gmail.com Wed May 27 07:34:34 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 27 May 2015 09:34:34 +0200 Subject: RFR(M,v9): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5564802A.2010403@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> <5564802A.2010403@oracle.com> Message-ID: <5565738A.4040109@gmail.com> Hi Dmitry, The jdk part looks OK (no great changes on this side from last webrev). Is there a particular reason why the return type of printFinalizayionQueue() method is Object[] and not Map.Entry[] ? For the hotspot part, I have a few reservations. You expect that the type of array elements will be HashMap.Node and that the key/value fields will be at fixed offsets. Is this even true for all architectures (32bit, 64bit +-UseCompressedOops)? The type of HashMap entry is controlled by code in HashMap which has a long history of changes. Next time the implementation of HashMap changes, your code could break. Would it be possible to only use public API? To invoke methods on Map.Entry interface to obtain the key and value? Regards, Peter On 05/26/2015 04:16 PM, Dmitry Samersoff wrote: > Hi Everybody, > > http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.09/ > > Please review updated webrev - > > printFinalizationQueue now returns and array of Map.Entry and all formatting is done on VM side. > > -Dmitry > > On 2015-05-21 02:07, Mandy Chung wrote: >>> On May 19, 2015, at 11:51 PM, Dmitry Samersoff >>> > wrote: >>> >>> Other alternatives could be to do all hashing/sorting/printing on native >>> layer i.e. implement printFinalizationQueue inside VM. >>> >>> Both options has pros and cons - Java based solution requires less JNI >>> calls and better readable but takes more memory. >>> >>> It might be better to return an array of Map.Entry >>> objects to VM rather than one huge string. >> The output and formatting should be done by jcmd. What you really need >> to get a peek on the finalizer queue and print the histogram. The VM >> has the heap histogram implementation. Have you considered leveraging >> that? >> >> 5: 1012 40480 java.lang.ref.Finalizer >> >> You can find the registered Finalizer instances. The downside is that >> icmd -finalizerinfo stops the world. I think it?s not unreasonable for >> this diagnostic command to be expensive like -heap command. >> >> Mandy > From erik.joelsson at oracle.com Wed May 27 07:48:46 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Wed, 27 May 2015 09:48:46 +0200 Subject: Review Request 8074432: Move jdeps to jdk.compiler module In-Reply-To: <15282D68-346E-4569-A356-2266C1A28CD9@oracle.com> References: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> <5562CC61.30603@oracle.com> <15282D68-346E-4569-A356-2266C1A28CD9@oracle.com> Message-ID: <556576DE.4060806@oracle.com> Hello Mandy, I don't see a Launcher-jdk.jdeps.gmk. Should there be one? /Erik On 2015-05-27 08:00, Mandy Chung wrote: > We discussed this offline and revised the proposal to group javap and classfile library together with jdeps in jdk.jdeps module for static analysis tools to live. The jdk.compiler module will contain the compiler and a couple of small tools. Moving out javap and classfile library save about 1.2M uncompressed from jdk.compiler (~11%). > > The module is named after the primary tool, jdeps in this case. Tools are in JAVA_HOME/bin directory of idk image and so which module jdeps and javap are transparent in the idk image. > > Revised webrev: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074432/webrev.01/ > > This touches many langtools tests to update @modules but should be easy to review. > > $ du -s -h jdk.jdeps/com/sun/tools/* > 816K jdk.jdeps/com/sun/tools/classfile > 468K jdk.jdeps/com/sun/tools/javap > 400K jdk.jdeps/com/sun/tools/jdeps > $ du -s -h jdk.compiler/ > 9.1M jdk.compiler/ > > Mandy From ivan.gerasimov at oracle.com Wed May 27 09:36:14 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 27 May 2015 12:36:14 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556503D8.6000303@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> Message-ID: <5565900E.9050305@oracle.com> Hi Sherman! Please take a look at my other webrev, that I provided in the first message. WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ I used StringJoiner there, which in some aspects seems to fit better here, comparing to StringBuilder. It does reduce the code, but of course runs slower. In that version every part of the source string had to be converted to a separate String, which add another redundant copying. I still prefer the version, which deals with arrays. I don't think it's too complex. It surely adds some complexity to the original code, but it's only 70 lines of code in total. Everything else are comments and empty lines. Sincerely yours, Ivan On 27.05.2015 2:38, Xueming Shen wrote: > Ivan, > > It might be worth trying String.index + StringBuilder, instead of > writing/handling everything yourself. > Yes, it inevitably adds an arraycopy at the end to convert the > StrinbBuilder to String, but it might have > better balance between performance and code complexity. The regex is > probably a little heavy for > literal string replacement, but StringBuilder should not be that bad ... > > -Sherman > > On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >> I updated the webrev: >> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >> >> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE >> with Integer.MAX_VALUE, which seems to be more accurate here. >> >> And I want to add that this proposed implementation is not only >> faster, but also more memory efficient. >> The following simple stress-test shows that the proposed version is >> able to handle twice larger strings, comparing to the current >> implementation. >> >> ---------------------------------------- >> public class C { >> public static void main(String[] args) throws Throwable { >> String s = "string"; >> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >> try { >> s = s.replace("string", "stringstring"); >> } catch (OutOfMemoryError o) { >> System.out.println(i + ") " + s.length()); >> break; >> } >> } >> } >> } >> ---------------------------------------- >> >> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >> java version "1.9.0-ea" >> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >> >> 25) 100663296 >> >> real 0m4.525s >> user 0m4.402s >> sys 0m1.189s >> >> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >> java version "1.9.0-internal" >> Java(TM) SE Runtime Environment (build >> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >> Java HotSpot(TM) 64-Bit Server VM (build >> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >> >> 26) 201326592 >> >> real 0m2.139s >> user 0m1.960s >> sys 0m0.461s >> >> Sincerely yours, >> Ivan >> >> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>> Hello everybody! >>> >>> I know many people here like it when the performance is getting better. >>> It was suggested to make the literal variant of String.replace() >>> faster. >>> Currently, this method is implemented as a few calls to regexp API, >>> so that the whole implementation takes only two lines of code. >>> >>> I've created two versions of the fix. >>> In the first one, we scan the string and store indices of the found >>> substrings in an array. >>> Then, we allocate the precisely sized char array and fill it it. >>> The case with the empty target has to be handled separately. >>> >>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>> >>> The second variant is much less verbose, however it's less efficient >>> too. >>> Here the StringJoiner is used as an intermediate storage. >>> >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>> >>> >>> Here are the micro-benchmark results (in a string of ~300 chars do >>> ~15 replacements). >>> 0) Baseline >>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>> >>> 1) Heavy-duty +308% >>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>> >>> 2) StringJoiner +190% >>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>> >>> >>> Personally, I like my first variant better, even though it adds >>> almost 300 lines of code. >>> But I'd like to hear what people think of it. >>> >>> Sincerely yours, >>> Ivan >>> >>> >> > > > From peter.levart at gmail.com Wed May 27 11:06:00 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 27 May 2015 13:06:00 +0200 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5565900E.9050305@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565900E.9050305@oracle.com> Message-ID: <5565A518.7020607@gmail.com> On 05/27/2015 11:36 AM, Ivan Gerasimov wrote: > Hi Sherman! > > Please take a look at my other webrev, that I provided in the first > message. > WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ > > I used StringJoiner there, which in some aspects seems to fit better > here, comparing to StringBuilder. > It does reduce the code, but of course runs slower. > In that version every part of the source string had to be converted to > a separate String, which add another redundant copying. > > I still prefer the version, which deals with arrays. I don't think > it's too complex. > It surely adds some complexity to the original code, but it's only 70 > lines of code in total. > Everything else are comments and empty lines. > > Sincerely yours, > Ivan Hi Ivan, If I was to choose, I would take the 1st variant (with index arrays) too. The speed does matter! But anyway, every now and then one would like to write an algorithm that gathers sub-strings and then either joins them or dumps them to some buffer that eventually becomes another string or array. Since String.substring() changed when offset/length fields were removed, there is no official way to handle sub-sequences as "vews" of underlying String. There was some debate in the past about using String's implementation of CharSequence.subSequence() for that purpose - to return a private CharSequence implementation that would represent a view of underlying String's array, but that was not pursued because of limiting API specification that says: "Returns a character sequence that is a subsequence of this sequence. An invocation of this method of the form str.subSequence(begin, end) behaves in exactly the same way as the invocation str.substring(begin, end)" My opinion is that this part of text did matter at the time when substring() did return a view over underlying array, but when the substring method changed, there was no reason to keep the specification bound to that text. It would have been wiser to keep the behavior unchanged and change the specification. Anyway, what's done is done. I don't know if String.subSequence can be changed now. Maybe? What could be done is introduce some new API. It could be in the form of a new class or just a static method (on CharSequence perhaps?) that would return a private implementation of CharSequence as a sub-sequence view over underlying CharSequence or String's array in case the passed-in argument is a String. With such API one could gather sub-sequence view objects into a LinkedList and then dump them into the correctly pre-sized StringBuilder. There could even be a String counstructor with the following signature: public String(Iterable sequences, int estimatedLength) { ... ..which would eliminate the last copying step too. Hopefully all temporary view objects would be found as method-local and would be allocated on stack / in registers by JIT (wishful thinking)... Regards, Peter > > On 27.05.2015 2:38, Xueming Shen wrote: >> Ivan, >> >> It might be worth trying String.index + StringBuilder, instead of >> writing/handling everything yourself. >> Yes, it inevitably adds an arraycopy at the end to convert the >> StrinbBuilder to String, but it might have >> better balance between performance and code complexity. The regex is >> probably a little heavy for >> literal string replacement, but StringBuilder should not be that bad ... >> >> -Sherman >> >> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>> I updated the webrev: >>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>> >>> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE >>> with Integer.MAX_VALUE, which seems to be more accurate here. >>> >>> And I want to add that this proposed implementation is not only >>> faster, but also more memory efficient. >>> The following simple stress-test shows that the proposed version is >>> able to handle twice larger strings, comparing to the current >>> implementation. >>> >>> ---------------------------------------- >>> public class C { >>> public static void main(String[] args) throws Throwable { >>> String s = "string"; >>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>> try { >>> s = s.replace("string", "stringstring"); >>> } catch (OutOfMemoryError o) { >>> System.out.println(i + ") " + s.length()); >>> break; >>> } >>> } >>> } >>> } >>> ---------------------------------------- >>> >>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>> java version "1.9.0-ea" >>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>> >>> 25) 100663296 >>> >>> real 0m4.525s >>> user 0m4.402s >>> sys 0m1.189s >>> >>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>> java version "1.9.0-internal" >>> Java(TM) SE Runtime Environment (build >>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>> Java HotSpot(TM) 64-Bit Server VM (build >>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>> >>> 26) 201326592 >>> >>> real 0m2.139s >>> user 0m1.960s >>> sys 0m0.461s >>> >>> Sincerely yours, >>> Ivan >>> >>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>> Hello everybody! >>>> >>>> I know many people here like it when the performance is getting >>>> better. >>>> It was suggested to make the literal variant of String.replace() >>>> faster. >>>> Currently, this method is implemented as a few calls to regexp API, >>>> so that the whole implementation takes only two lines of code. >>>> >>>> I've created two versions of the fix. >>>> In the first one, we scan the string and store indices of the found >>>> substrings in an array. >>>> Then, we allocate the precisely sized char array and fill it it. >>>> The case with the empty target has to be handled separately. >>>> >>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>> >>>> The second variant is much less verbose, however it's less >>>> efficient too. >>>> Here the StringJoiner is used as an intermediate storage. >>>> >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>> >>>> >>>> Here are the micro-benchmark results (in a string of ~300 chars do >>>> ~15 replacements). >>>> 0) Baseline >>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>> >>>> 1) Heavy-duty +308% >>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>> >>>> 2) StringJoiner +190% >>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>> >>>> >>>> Personally, I like my first variant better, even though it adds >>>> almost 300 lines of code. >>>> But I'd like to hear what people think of it. >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>> >>> >> >> >> > From peter.levart at gmail.com Wed May 27 13:15:26 2015 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 27 May 2015 15:15:26 +0200 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5565900E.9050305@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565900E.9050305@oracle.com> Message-ID: <5565C36E.8050101@gmail.com> Hi Ivan, How does this implementation compare to your's two regarding speed: http://cr.openjdk.java.net/~plevart/jdk9-dev/String.replace/webrev.01/ It is not much shorter than your's first, but more object oriented ;-) Regards, Peter On 05/27/2015 11:36 AM, Ivan Gerasimov wrote: > Hi Sherman! > > Please take a look at my other webrev, that I provided in the first > message. > WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ > > I used StringJoiner there, which in some aspects seems to fit better > here, comparing to StringBuilder. > It does reduce the code, but of course runs slower. > In that version every part of the source string had to be converted to > a separate String, which add another redundant copying. > > I still prefer the version, which deals with arrays. I don't think > it's too complex. > It surely adds some complexity to the original code, but it's only 70 > lines of code in total. > Everything else are comments and empty lines. > > Sincerely yours, > Ivan > > On 27.05.2015 2:38, Xueming Shen wrote: >> Ivan, >> >> It might be worth trying String.index + StringBuilder, instead of >> writing/handling everything yourself. >> Yes, it inevitably adds an arraycopy at the end to convert the >> StrinbBuilder to String, but it might have >> better balance between performance and code complexity. The regex is >> probably a little heavy for >> literal string replacement, but StringBuilder should not be that bad ... >> >> -Sherman >> >> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>> I updated the webrev: >>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>> >>> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE >>> with Integer.MAX_VALUE, which seems to be more accurate here. >>> >>> And I want to add that this proposed implementation is not only >>> faster, but also more memory efficient. >>> The following simple stress-test shows that the proposed version is >>> able to handle twice larger strings, comparing to the current >>> implementation. >>> >>> ---------------------------------------- >>> public class C { >>> public static void main(String[] args) throws Throwable { >>> String s = "string"; >>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>> try { >>> s = s.replace("string", "stringstring"); >>> } catch (OutOfMemoryError o) { >>> System.out.println(i + ") " + s.length()); >>> break; >>> } >>> } >>> } >>> } >>> ---------------------------------------- >>> >>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>> java version "1.9.0-ea" >>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>> >>> 25) 100663296 >>> >>> real 0m4.525s >>> user 0m4.402s >>> sys 0m1.189s >>> >>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>> java version "1.9.0-internal" >>> Java(TM) SE Runtime Environment (build >>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>> Java HotSpot(TM) 64-Bit Server VM (build >>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>> >>> 26) 201326592 >>> >>> real 0m2.139s >>> user 0m1.960s >>> sys 0m0.461s >>> >>> Sincerely yours, >>> Ivan >>> >>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>> Hello everybody! >>>> >>>> I know many people here like it when the performance is getting >>>> better. >>>> It was suggested to make the literal variant of String.replace() >>>> faster. >>>> Currently, this method is implemented as a few calls to regexp API, >>>> so that the whole implementation takes only two lines of code. >>>> >>>> I've created two versions of the fix. >>>> In the first one, we scan the string and store indices of the found >>>> substrings in an array. >>>> Then, we allocate the precisely sized char array and fill it it. >>>> The case with the empty target has to be handled separately. >>>> >>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>> >>>> The second variant is much less verbose, however it's less >>>> efficient too. >>>> Here the StringJoiner is used as an intermediate storage. >>>> >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>> >>>> >>>> Here are the micro-benchmark results (in a string of ~300 chars do >>>> ~15 replacements). >>>> 0) Baseline >>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>> >>>> 1) Heavy-duty +308% >>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>> >>>> 2) StringJoiner +190% >>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>> >>>> >>>> Personally, I like my first variant better, even though it adds >>>> almost 300 lines of code. >>>> But I'd like to hear what people think of it. >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>> >>> >> >> >> > From mandy.chung at oracle.com Wed May 27 13:32:38 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 27 May 2015 06:32:38 -0700 Subject: RFR(M, v9): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <5565738A.4040109@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> <5564802A.2010403@oracle.com> <5565738A.4040109@gmail.com> Message-ID: <7EB0BE71-1608-4047-B71D-1A9EAA9083BB@oracle.com> > On May 27, 2015, at 12:34 AM, Peter Levart wrote: > > Hi Dmitry, > > The jdk part looks OK (no great changes on this side from last webrev). Is there a particular reason why the return type of printFinalizayionQueue() method is Object[] and not Map.Entry[] ? > Taking it further - is it simpler to return String[] of all classnames including the duplicated ones and have the VM do the count? Are you concerned with the size of the String[]? > For the hotspot part, I have a few reservations. You expect that the type of array elements will be HashMap.Node and that the key/value fields will be at fixed offsets. Is this even true for all architectures (32bit, 64bit +-UseCompressedOops)? > > The type of HashMap entry is controlled by code in HashMap which has a long history of changes. Next time the implementation of HashMap changes, your code could break. Would it be possible to only use public API? To invoke methods on Map.Entry interface to obtain the key and value? > Indeed, depending on the HashMap internal implementation is a bad idea. Mandy > Regards, Peter > > On 05/26/2015 04:16 PM, Dmitry Samersoff wrote: >> Hi Everybody, >> >> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.09/ >> >> Please review updated webrev - >> >> printFinalizationQueue now returns and array of Map.Entry> and all formatting is done on VM side. >> >> -Dmitry >> >> On 2015-05-21 02:07, Mandy Chung wrote: >>>> On May 19, 2015, at 11:51 PM, Dmitry Samersoff >>>> > wrote: >>>> >>>> Other alternatives could be to do all hashing/sorting/printing on native >>>> layer i.e. implement printFinalizationQueue inside VM. >>>> >>>> Both options has pros and cons - Java based solution requires less JNI >>>> calls and better readable but takes more memory. >>>> >>>> It might be better to return an array of Map.Entry >>>> objects to VM rather than one huge string. >>> The output and formatting should be done by jcmd. What you really need >>> to get a peek on the finalizer queue and print the histogram. The VM >>> has the heap histogram implementation. Have you considered leveraging >>> that? >>> >>> 5: 1012 40480 java.lang.ref.Finalizer >>> >>> You can find the registered Finalizer instances. The downside is that >>> icmd -finalizerinfo stops the world. I think it?s not unreasonable for >>> this diagnostic command to be expensive like -heap command. >>> >>> Mandy >> > From mandy.chung at oracle.com Wed May 27 13:40:31 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 27 May 2015 06:40:31 -0700 Subject: Review Request 8074432: Move jdeps to jdk.compiler module In-Reply-To: <556576DE.4060806@oracle.com> References: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> <5562CC61.30603@oracle.com> <15282D68-346E-4569-A356-2266C1A28CD9@oracle.com> <556576DE.4060806@oracle.com> Message-ID: It?s in my repo but missing from the webrev. diff --git a/make/launcher/Launcher-jdk.jdeps.gmk b/make/launcher/Launcher-jdk.jdeps.gmk new file mode 100644 --- /dev/null +++ b/make/launcher/Launcher-jdk.jdeps.gmk @@ -0,0 +1,36 @@ +# +# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include LauncherCommon.gmk + +$(eval $(call SetupLauncher,javap, \ + -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ + -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }')) + +$(eval $(call SetupLauncher,jdeps, \ + -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ + -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }')) > On May 27, 2015, at 12:48 AM, Erik Joelsson wrote: > > Hello Mandy, > > I don't see a Launcher-jdk.jdeps.gmk. Should there be one? > > /Erik > > On 2015-05-27 08:00, Mandy Chung wrote: >> We discussed this offline and revised the proposal to group javap and classfile library together with jdeps in jdk.jdeps module for static analysis tools to live. The jdk.compiler module will contain the compiler and a couple of small tools. Moving out javap and classfile library save about 1.2M uncompressed from jdk.compiler (~11%). >> >> The module is named after the primary tool, jdeps in this case. Tools are in JAVA_HOME/bin directory of idk image and so which module jdeps and javap are transparent in the idk image. >> >> Revised webrev: >> http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074432/webrev.01/ >> >> This touches many langtools tests to update @modules but should be easy to review. >> >> $ du -s -h jdk.jdeps/com/sun/tools/* >> 816K jdk.jdeps/com/sun/tools/classfile >> 468K jdk.jdeps/com/sun/tools/javap >> 400K jdk.jdeps/com/sun/tools/jdeps >> $ du -s -h jdk.compiler/ >> 9.1M jdk.compiler/ >> >> Mandy > From erik.joelsson at oracle.com Wed May 27 14:12:44 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Wed, 27 May 2015 16:12:44 +0200 Subject: Review Request 8074432: Move jdeps to jdk.compiler module In-Reply-To: References: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> <5562CC61.30603@oracle.com> <15282D68-346E-4569-A356-2266C1A28CD9@oracle.com> <556576DE.4060806@oracle.com> Message-ID: <5565D0DC.7080508@oracle.com> Looks good to me. /Erik On 2015-05-27 15:40, Mandy Chung wrote: > It?s in my repo but missing from the webrev. > > diff --git a/make/launcher/Launcher-jdk.jdeps.gmk b/make/launcher/Launcher-jdk.jdeps.gmk > new file mode 100644 > --- /dev/null > +++ b/make/launcher/Launcher-jdk.jdeps.gmk > @@ -0,0 +1,36 @@ > +# > +# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. > +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > +# > +# This code is free software; you can redistribute it and/or modify it > +# under the terms of the GNU General Public License version 2 only, as > +# published by the Free Software Foundation. Oracle designates this > +# particular file as subject to the "Classpath" exception as provided > +# by Oracle in the LICENSE file that accompanied this code. > +# > +# This code is distributed in the hope that it will be useful, but WITHOUT > +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +# version 2 for more details (a copy is included in the LICENSE file that > +# accompanied this code). > +# > +# You should have received a copy of the GNU General Public License version > +# 2 along with this work; if not, write to the Free Software Foundation, > +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. > +# > +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA > +# or visit www.oracle.com if you need additional information or have any > +# questions. > +# > + > +include LauncherCommon.gmk > + > +$(eval $(call SetupLauncher,javap, \ > + -DEXPAND_CLASSPATH_WILDCARDS \ > + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ > + -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }')) > + > +$(eval $(call SetupLauncher,jdeps, \ > + -DEXPAND_CLASSPATH_WILDCARDS \ > + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \ > + -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }')) > >> On May 27, 2015, at 12:48 AM, Erik Joelsson wrote: >> >> Hello Mandy, >> >> I don't see a Launcher-jdk.jdeps.gmk. Should there be one? >> >> /Erik >> >> On 2015-05-27 08:00, Mandy Chung wrote: >>> We discussed this offline and revised the proposal to group javap and classfile library together with jdeps in jdk.jdeps module for static analysis tools to live. The jdk.compiler module will contain the compiler and a couple of small tools. Moving out javap and classfile library save about 1.2M uncompressed from jdk.compiler (~11%). >>> >>> The module is named after the primary tool, jdeps in this case. Tools are in JAVA_HOME/bin directory of idk image and so which module jdeps and javap are transparent in the idk image. >>> >>> Revised webrev: >>> http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074432/webrev.01/ >>> >>> This touches many langtools tests to update @modules but should be easy to review. >>> >>> $ du -s -h jdk.jdeps/com/sun/tools/* >>> 816K jdk.jdeps/com/sun/tools/classfile >>> 468K jdk.jdeps/com/sun/tools/javap >>> 400K jdk.jdeps/com/sun/tools/jdeps >>> $ du -s -h jdk.compiler/ >>> 9.1M jdk.compiler/ >>> >>> Mandy From Roger.Riggs at Oracle.com Wed May 27 14:24:21 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 27 May 2015 10:24:21 -0400 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: References: <555E499C.6020300@Oracle.com> <55653157.1040202@Oracle.com> Message-ID: <5565D395.5000902@Oracle.com> Hi Martin, Untangling the past a bit. Perhaps this code could be cleaner but priority-wise, I've got some other things to do first. The Windows fcntl.h does not define O_SYNC/O_DSYNC so its relative include order is not significant. The explicit define of O_SYNC and O_DSYNC make the API to the Unix and Windows file support APIs consistent. On Windows file access is done using CreateFileW to get the native Windows semantics. The O_SYNC/DSYNC flags are mapped to the corresponding flags/attributes to CreateFileW. Roger On 5/27/2015 2:59 AM, Martin Buchholz wrote: > > > On Tue, May 26, 2015 at 7:52 PM, Roger Riggs > wrote: > > Hi, > > Sadly, but not entirely unexpectedly there is an anomaly in the > include files: > It seems that Windows does not define O_SYNC and O_DSYNC. > To make up for the absence > jdk/src/java.base/share/native/libjava/io_util.h > conditionally defines them. There is no problem if the system > include files appear > first, but in the other order, fcntl.h tries to re-define it. > In the recommended order, there is no issue. > > > We should work hard to remove order dependencies in include files. > > I see that io_util.h includes , but only on BSD. Why not > include it wherever it is available, (which may be all supported > platforms!) before trying to define O_SYNC and D_SYNC? > From Alan.Bateman at oracle.com Wed May 27 14:26:55 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 27 May 2015 15:26:55 +0100 Subject: Review Request 8074432: Move jdeps to jdk.compiler module In-Reply-To: <15282D68-346E-4569-A356-2266C1A28CD9@oracle.com> References: <6C76C1E9-D4C0-4075-AD20-46CF8AAA1925@oracle.com> <5562CC61.30603@oracle.com> <15282D68-346E-4569-A356-2266C1A28CD9@oracle.com> Message-ID: <5565D42F.7030009@oracle.com> On 27/05/2015 07:00, Mandy Chung wrote: > We discussed this offline and revised the proposal to group javap and classfile library together with jdeps in jdk.jdeps module for static analysis tools to live. The jdk.compiler module will contain the compiler and a couple of small tools. Moving out javap and classfile library save about 1.2M uncompressed from jdk.compiler (~11%). > > The module is named after the primary tool, jdeps in this case. Tools are in JAVA_HOME/bin directory of idk image and so which module jdeps and javap are transparent in the idk image. > > Revised webrev: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8074432/webrev.01/ > > The internal classfile API, javap and jdeps in the jdk.jdeps module looks good to me. -Alan. From ivan.gerasimov at oracle.com Wed May 27 14:27:28 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 27 May 2015 17:27:28 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5565C36E.8050101@gmail.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565900E.9050305@oracle.com> <5565C36E.8050101@gmail.com> Message-ID: <5565D450.5060404@oracle.com> Thank you Peter for looking at this! On 27.05.2015 16:15, Peter Levart wrote: > Hi Ivan, > > How does this implementation compare to your's two regarding speed: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/String.replace/webrev.01/ > You need to check for possible overflow here: 2287 resLen += repLen + ss.length(); > It is not much shorter than your's first, but more object oriented ;-) > Well, the main difference is that you store the positions of substrings in a linked-list instead of an array. But arrays are more efficient. On small data the performance is almost the same as for the 'array' version: MyBenchmark.test thrpt 40 1'046'137.437 ? 13961.121 ops/s But on huge data the performance is much worse, comparing to even current implementation. Here are the results of running the stress test, I had posted earlier: ------------------------- time ~/java9/jdk-build/bin/java -showversion -Xmx1g C java version "1.9.0-internal" Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00) Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) 25) 100663296 real 0m12.945s user 0m15.670s sys 0m7.189s ------------------------- It took 6 times more time to complete, comparing to the current implementation, which uses regexp engine. Sincerely yours, Ivan > Regards, Peter > > On 05/27/2015 11:36 AM, Ivan Gerasimov wrote: >> Hi Sherman! >> >> Please take a look at my other webrev, that I provided in the first >> message. >> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >> >> I used StringJoiner there, which in some aspects seems to fit better >> here, comparing to StringBuilder. >> It does reduce the code, but of course runs slower. >> In that version every part of the source string had to be converted >> to a separate String, which add another redundant copying. >> >> I still prefer the version, which deals with arrays. I don't think >> it's too complex. >> It surely adds some complexity to the original code, but it's only 70 >> lines of code in total. >> Everything else are comments and empty lines. >> >> Sincerely yours, >> Ivan >> >> On 27.05.2015 2:38, Xueming Shen wrote: >>> Ivan, >>> >>> It might be worth trying String.index + StringBuilder, instead of >>> writing/handling everything yourself. >>> Yes, it inevitably adds an arraycopy at the end to convert the >>> StrinbBuilder to String, but it might have >>> better balance between performance and code complexity. The regex is >>> probably a little heavy for >>> literal string replacement, but StringBuilder should not be that bad >>> ... >>> >>> -Sherman >>> >>> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>>> I updated the webrev: >>>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>>> >>>> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE >>>> with Integer.MAX_VALUE, which seems to be more accurate here. >>>> >>>> And I want to add that this proposed implementation is not only >>>> faster, but also more memory efficient. >>>> The following simple stress-test shows that the proposed version is >>>> able to handle twice larger strings, comparing to the current >>>> implementation. >>>> >>>> ---------------------------------------- >>>> public class C { >>>> public static void main(String[] args) throws Throwable { >>>> String s = "string"; >>>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>>> try { >>>> s = s.replace("string", "stringstring"); >>>> } catch (OutOfMemoryError o) { >>>> System.out.println(i + ") " + s.length()); >>>> break; >>>> } >>>> } >>>> } >>>> } >>>> ---------------------------------------- >>>> >>>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>>> java version "1.9.0-ea" >>>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>>> >>>> 25) 100663296 >>>> >>>> real 0m4.525s >>>> user 0m4.402s >>>> sys 0m1.189s >>>> >>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>> java version "1.9.0-internal" >>>> Java(TM) SE Runtime Environment (build >>>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>>> Java HotSpot(TM) 64-Bit Server VM (build >>>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>>> >>>> 26) 201326592 >>>> >>>> real 0m2.139s >>>> user 0m1.960s >>>> sys 0m0.461s >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>>> Hello everybody! >>>>> >>>>> I know many people here like it when the performance is getting >>>>> better. >>>>> It was suggested to make the literal variant of String.replace() >>>>> faster. >>>>> Currently, this method is implemented as a few calls to regexp >>>>> API, so that the whole implementation takes only two lines of code. >>>>> >>>>> I've created two versions of the fix. >>>>> In the first one, we scan the string and store indices of the >>>>> found substrings in an array. >>>>> Then, we allocate the precisely sized char array and fill it it. >>>>> The case with the empty target has to be handled separately. >>>>> >>>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>>> >>>>> The second variant is much less verbose, however it's less >>>>> efficient too. >>>>> Here the StringJoiner is used as an intermediate storage. >>>>> >>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>>> >>>>> >>>>> Here are the micro-benchmark results (in a string of ~300 chars do >>>>> ~15 replacements). >>>>> 0) Baseline >>>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>>> >>>>> 1) Heavy-duty +308% >>>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>>> >>>>> 2) StringJoiner +190% >>>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>>> >>>>> >>>>> Personally, I like my first variant better, even though it adds >>>>> almost 300 lines of code. >>>>> But I'd like to hear what people think of it. >>>>> >>>>> Sincerely yours, >>>>> Ivan >>>>> >>>>> >>>> >>> >>> >>> >> > > > From martinrb at google.com Wed May 27 14:30:36 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 27 May 2015 07:30:36 -0700 Subject: RFR 8081027: Create a common test to check adequacy of initial size of static HashMap/ArrayList fields In-Reply-To: <5563AB19.4060507@oracle.com> References: <5563AB19.4060507@oracle.com> Message-ID: Thanks. Your methods like ofArrayList declare that they throw ReflectiveOperationException, but also have a try/catch to prevent that from ever happening. The assertions e.g. OptimalCapacity.ofArrayList(XClass.class, "theList", N) could look more like assertions, e.g. OptimalCapacity.assertOptimallySized(Class clazz, String fieldName, int initialCapacity) getStorage returns the actual internal array, but you only ever need the length. Maybe I would have a single method static int internalArraySize(Object x) { ... } "enteties" is misspelled. For ArrayLists, I would have been happy enough just testing that we have 100% utilization, i.e. size of array is the same as size of the List, without checking the initial capacity. On Mon, May 25, 2015 at 4:07 PM, Ivan Gerasimov wrote: > Hello! > > This is in some way continuation of JDK-8080535 (Expected size of > Character.UnicodeBlock.map is not optimal). > > A new utility class OptimalCapacity was added to jdk.testlibrary package. > The test NonOptimalMapSize.java that had been added with JDK-8080535, was > rewritten with use of this new class. > A couple more tests were added, which utilize methods of OptimalCapacity > for checking sizes of ArrayList and IdentityHashMap static variables. > > Optimization of initial sizes of two more variables saves us one > reallocation during java start-time and a few more bytes of memory. > > Would you please help review this fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8081027 > WEBREV: http://cr.openjdk.java.net/~igerasim/8081027/00/webrev/ > > Sincerely yours, > Ivan > From konstantin.shefov at oracle.com Wed May 27 14:50:35 2015 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Wed, 27 May 2015 17:50:35 +0300 Subject: [8u-dev] Review request : JDK-8062904: TEST_BUG: Tests java/lang/invoke/LFCaching fail when run with -Xcomp option Message-ID: <5565D9BB.60003@oracle.com> Hello, Please review the test bug fix https://bugs.openjdk.java.net/browse/JDK-8062904 Webrev is http://cr.openjdk.java.net/~kshefov/8062904/webrev.01/ Test fails only against JDK 8u and passes against JDK 9. Thanks -Konstantin From Alan.Bateman at oracle.com Wed May 27 15:27:08 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 27 May 2015 16:27:08 +0100 Subject: RFR JDK-8028480: (zipfs) NoSuchFileException on creating a file in ZipFileSystem with CREATE and WRITE In-Reply-To: <5564C81D.7050403@oracle.com> References: <5564C81D.7050403@oracle.com> Message-ID: <5565E24C.3060101@oracle.com> On 26/05/2015 20:23, Xueming Shen wrote: > Hi, > > Please help review the changes for JDK-8028480 and JDK-8034773 > > issues: > https://bugs.openjdk.java.net/browse/JDK-8028480 > https://bugs.openjdk.java.net/browse/JDK-8034773 > > webrev: > http://cr.openjdk.java.net/~sherman/8028480_8034773/ This looks okay but in several places it will require making a defensive copy of options before they are checked. -Alan. From forax at univ-mlv.fr Wed May 27 15:29:13 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 27 May 2015 17:29:13 +0200 Subject: Bad interaction between wildcard and functional interface conversion Message-ID: <5565E2C9.7050009@univ-mlv.fr> Hi all, The way the conversion between a lambda (or a method reference) and a functional interface is specified doesn't take wildcard (exactly ? super) into account making the concept of contravariance of functional interface less intuitive that it should be. The following code compiles: private static void create(Consumer> consumer) { consumer.accept(s -> System.out.println(s)); } This one doesn't compile because "? super Consumer" is not a functional interface: private static void create2(Consumer> consumer) { consumer.accept(s -> System.out.println(s)); } The workaround is to introduce a cast :( private static void create3(Consumer> consumer) { consumer.accept((Consumer)s -> System.out.println(s)); } which is stupid in this case because there is no ambiguity. This cast is just here because the JLS doesn't consider that ? super Consumer<...> is a valid target type IMO, this bug is very similar to JDK-6964923 and i think the spec should be changed to allow ? super Foo to be a valid target type for a lambda conversion (obviously if Foo is a functional interface). regards, R?mi From ivan.gerasimov at oracle.com Wed May 27 15:29:26 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 27 May 2015 18:29:26 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556503D8.6000303@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> Message-ID: <5565E2D6.2070806@oracle.com> For completeness, here's another webrev, which uses StringBuilder: http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ Its performance is somewhere in between the current implementation and the array-based implementation: MyBenchmark.test thrpt 40 796'059.192 ? 12455.970 ops/s Memory efficiency is less then the one of array-based implementation: $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C java version "1.9.0-internal" Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00) Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) 25) 100663296 real 0m2.585s user 0m1.875s sys 0m0.887s Sincerely yours, Ivan On 27.05.2015 2:38, Xueming Shen wrote: > Ivan, > > It might be worth trying String.index + StringBuilder, instead of > writing/handling everything yourself. > Yes, it inevitably adds an arraycopy at the end to convert the > StrinbBuilder to String, but it might have > better balance between performance and code complexity. The regex is > probably a little heavy for > literal string replacement, but StringBuilder should not be that bad ... > > -Sherman > > On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >> I updated the webrev: >> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >> >> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE >> with Integer.MAX_VALUE, which seems to be more accurate here. >> >> And I want to add that this proposed implementation is not only >> faster, but also more memory efficient. >> The following simple stress-test shows that the proposed version is >> able to handle twice larger strings, comparing to the current >> implementation. >> >> ---------------------------------------- >> public class C { >> public static void main(String[] args) throws Throwable { >> String s = "string"; >> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >> try { >> s = s.replace("string", "stringstring"); >> } catch (OutOfMemoryError o) { >> System.out.println(i + ") " + s.length()); >> break; >> } >> } >> } >> } >> ---------------------------------------- >> >> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >> java version "1.9.0-ea" >> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >> >> 25) 100663296 >> >> real 0m4.525s >> user 0m4.402s >> sys 0m1.189s >> >> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >> java version "1.9.0-internal" >> Java(TM) SE Runtime Environment (build >> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >> Java HotSpot(TM) 64-Bit Server VM (build >> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >> >> 26) 201326592 >> >> real 0m2.139s >> user 0m1.960s >> sys 0m0.461s >> >> Sincerely yours, >> Ivan >> >> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>> Hello everybody! >>> >>> I know many people here like it when the performance is getting better. >>> It was suggested to make the literal variant of String.replace() >>> faster. >>> Currently, this method is implemented as a few calls to regexp API, >>> so that the whole implementation takes only two lines of code. >>> >>> I've created two versions of the fix. >>> In the first one, we scan the string and store indices of the found >>> substrings in an array. >>> Then, we allocate the precisely sized char array and fill it it. >>> The case with the empty target has to be handled separately. >>> >>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>> >>> The second variant is much less verbose, however it's less efficient >>> too. >>> Here the StringJoiner is used as an intermediate storage. >>> >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>> >>> >>> Here are the micro-benchmark results (in a string of ~300 chars do >>> ~15 replacements). >>> 0) Baseline >>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>> >>> 1) Heavy-duty +308% >>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>> >>> 2) StringJoiner +190% >>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>> >>> >>> Personally, I like my first variant better, even though it adds >>> almost 300 lines of code. >>> But I'd like to hear what people think of it. >>> >>> Sincerely yours, >>> Ivan >>> >>> >> > > > From xueming.shen at oracle.com Wed May 27 15:44:39 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 27 May 2015 08:44:39 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5565E2D6.2070806@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> Message-ID: <5565E667.4050601@oracle.com> You might want to use directly sb.append.(char[], off, len), instead of append(str, off, len)/append(str). Btw, is the target.lenght==0 the popular use case/scenario? Just wonder why do we need a special case here for it. thanks, -Sherman On 5/27/15 8:29 AM, Ivan Gerasimov wrote: > For completeness, here's another webrev, which uses StringBuilder: > http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ > > Its performance is somewhere in between the current implementation and > the array-based implementation: > MyBenchmark.test thrpt 40 796'059.192 ? 12455.970 ops/s > > Memory efficiency is less then the one of array-based implementation: > $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C > java version "1.9.0-internal" > Java(TM) SE Runtime Environment (build > 1.9.0-internal-igerasim_2015_05_27_14_47-b00) > Java HotSpot(TM) 64-Bit Server VM (build > 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) > > 25) 100663296 > > real 0m2.585s > user 0m1.875s > sys 0m0.887s > > Sincerely yours, > Ivan > > On 27.05.2015 2:38, Xueming Shen wrote: >> Ivan, >> >> It might be worth trying String.index + StringBuilder, instead of >> writing/handling everything yourself. >> Yes, it inevitably adds an arraycopy at the end to convert the >> StrinbBuilder to String, but it might have >> better balance between performance and code complexity. The regex is >> probably a little heavy for >> literal string replacement, but StringBuilder should not be that bad ... >> >> -Sherman >> >> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>> I updated the webrev: >>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>> >>> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE >>> with Integer.MAX_VALUE, which seems to be more accurate here. >>> >>> And I want to add that this proposed implementation is not only >>> faster, but also more memory efficient. >>> The following simple stress-test shows that the proposed version is >>> able to handle twice larger strings, comparing to the current >>> implementation. >>> >>> ---------------------------------------- >>> public class C { >>> public static void main(String[] args) throws Throwable { >>> String s = "string"; >>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>> try { >>> s = s.replace("string", "stringstring"); >>> } catch (OutOfMemoryError o) { >>> System.out.println(i + ") " + s.length()); >>> break; >>> } >>> } >>> } >>> } >>> ---------------------------------------- >>> >>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>> java version "1.9.0-ea" >>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>> >>> 25) 100663296 >>> >>> real 0m4.525s >>> user 0m4.402s >>> sys 0m1.189s >>> >>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>> java version "1.9.0-internal" >>> Java(TM) SE Runtime Environment (build >>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>> Java HotSpot(TM) 64-Bit Server VM (build >>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>> >>> 26) 201326592 >>> >>> real 0m2.139s >>> user 0m1.960s >>> sys 0m0.461s >>> >>> Sincerely yours, >>> Ivan >>> >>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>> Hello everybody! >>>> >>>> I know many people here like it when the performance is getting >>>> better. >>>> It was suggested to make the literal variant of String.replace() >>>> faster. >>>> Currently, this method is implemented as a few calls to regexp API, >>>> so that the whole implementation takes only two lines of code. >>>> >>>> I've created two versions of the fix. >>>> In the first one, we scan the string and store indices of the found >>>> substrings in an array. >>>> Then, we allocate the precisely sized char array and fill it it. >>>> The case with the empty target has to be handled separately. >>>> >>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>> >>>> The second variant is much less verbose, however it's less >>>> efficient too. >>>> Here the StringJoiner is used as an intermediate storage. >>>> >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>> >>>> >>>> Here are the micro-benchmark results (in a string of ~300 chars do >>>> ~15 replacements). >>>> 0) Baseline >>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>> >>>> 1) Heavy-duty +308% >>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>> >>>> 2) StringJoiner +190% >>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>> >>>> >>>> Personally, I like my first variant better, even though it adds >>>> almost 300 lines of code. >>>> But I'd like to hear what people think of it. >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>> >>> >> >> >> > From xueming.shen at oracle.com Wed May 27 16:01:12 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 27 May 2015 09:01:12 -0700 Subject: RFR JDK-8028480: (zipfs) NoSuchFileException on creating a file in ZipFileSystem with CREATE and WRITE In-Reply-To: <5565E24C.3060101@oracle.com> References: <5564C81D.7050403@oracle.com> <5565E24C.3060101@oracle.com> Message-ID: <5565EA48.30901@oracle.com> On 5/27/15 8:27 AM, Alan Bateman wrote: > On 26/05/2015 20:23, Xueming Shen wrote: >> Hi, >> >> Please help review the changes for JDK-8028480 and JDK-8034773 >> >> issues: >> https://bugs.openjdk.java.net/browse/JDK-8028480 >> https://bugs.openjdk.java.net/browse/JDK-8034773 >> >> webrev: >> http://cr.openjdk.java.net/~sherman/8028480_8034773/ > This looks okay but in several places it will require making a > defensive copy of options before they are checked. > > -Alan. I'm aware of converting the options to internal flags in unix fs, but thought that is for the convenience... We are not saving the options for any future/internal use, simply checking its value on the spot. Just wonder really need to make the defensive copy here? The invoker changes the options during the invocation of this method? -Sherman From martinrb at google.com Wed May 27 16:54:30 2015 From: martinrb at google.com (Martin Buchholz) Date: Wed, 27 May 2015 09:54:30 -0700 Subject: RFR 9: 8074818: Resolve disabled warnings for libjava In-Reply-To: <5565D395.5000902@Oracle.com> References: <555E499C.6020300@Oracle.com> <55653157.1040202@Oracle.com> <5565D395.5000902@Oracle.com> Message-ID: Evil header file io_util.h effectively requires its callers to include fcntl.h first (on platforms where fcntl.h defines O_SYNC and D_SYNC) and that is a BIG NONO. I would try hard to fix io_util.h now (instead of adding workarounds to callers) and further, if any of its callers were including fcntl.h merely for io_util.h's benefit, remove those include statements. IWYU! Admittedly, google has far more IWYU religion than most. https://code.google.com/p/include-what-you-use/ On Wed, May 27, 2015 at 7:24 AM, Roger Riggs wrote: > Hi Martin, > > Untangling the past a bit. Perhaps this code could be cleaner but > priority-wise, > I've got some other things to do first. > > The Windows fcntl.h does not define O_SYNC/O_DSYNC so its relative include > order is not significant. > The explicit define of O_SYNC and O_DSYNC make the API to the Unix and > Windows > file support APIs consistent. > > On Windows file access is done using CreateFileW to get the native Windows > semantics. > The O_SYNC/DSYNC flags are mapped to the corresponding flags/attributes to > CreateFileW. > > Roger > > > > On 5/27/2015 2:59 AM, Martin Buchholz wrote: > > > > On Tue, May 26, 2015 at 7:52 PM, Roger Riggs > wrote: > >> Hi, >> >> Sadly, but not entirely unexpectedly there is an anomaly in the include >> files: >> It seems that Windows does not define O_SYNC and O_DSYNC. >> To make up for the absence >> jdk/src/java.base/share/native/libjava/io_util.h >> conditionally defines them. There is no problem if the system include >> files appear >> first, but in the other order, fcntl.h tries to re-define it. >> In the recommended order, there is no issue. >> > > We should work hard to remove order dependencies in include files. > > I see that io_util.h includes , but only on BSD. Why not > include it wherever it is available, (which may be all supported > platforms!) before trying to define O_SYNC and D_SYNC? > > > From vladimir.x.ivanov at oracle.com Wed May 27 16:54:45 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 27 May 2015 19:54:45 +0300 Subject: [8u-dev] Review request : JDK-8062904: TEST_BUG: Tests java/lang/invoke/LFCaching fail when run with -Xcomp option In-Reply-To: <5565D9BB.60003@oracle.com> References: <5565D9BB.60003@oracle.com> Message-ID: <5565F6D5.7030900@oracle.com> Have you tried to reduce iteration granularity? Probably, checking execution duration on every test case is more robust. Best regards, Vladimir Ivanov On 5/27/15 5:50 PM, Konstantin Shefov wrote: > Hello, > > Please review the test bug fix > https://bugs.openjdk.java.net/browse/JDK-8062904 > Webrev is http://cr.openjdk.java.net/~kshefov/8062904/webrev.01/ > Test fails only against JDK 8u and passes against JDK 9. > > Thanks > > -Konstantin From ivan.gerasimov at oracle.com Wed May 27 17:06:16 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 27 May 2015 20:06:16 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5565E667.4050601@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> Message-ID: <5565F988.7080209@oracle.com> On 27.05.2015 18:44, Xueming Shen wrote: > You might want to use directly sb.append.(char[], off, len), instead > of append(str, off, len)/append(str). Ah, yes sure! It would improve things. I updated the webrev in place: http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ However the general picture is almost the same: performance: Baseline: MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s StringBuilder: MyBenchmark.test thrpt 40 808'033.808 ? 22152.166 ops/s Arrays: MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s Memory efficiency is still less then for array-version: $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C java version "1.9.0-internal" Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00) Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) 25) 100663296 real 0m2.429s user 0m2.112s sys 0m0.792s Sincerely yours, Ivan > Btw, is the target.lenght==0 the popular use case/scenario? Just > wonder why do we need a special case > here for it. > > thanks, > -Sherman > > On 5/27/15 8:29 AM, Ivan Gerasimov wrote: >> For completeness, here's another webrev, which uses StringBuilder: >> http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ >> >> Its performance is somewhere in between the current implementation >> and the array-based implementation: >> MyBenchmark.test thrpt 40 796'059.192 ? 12455.970 ops/s >> >> Memory efficiency is less then the one of array-based implementation: >> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >> java version "1.9.0-internal" >> Java(TM) SE Runtime Environment (build >> 1.9.0-internal-igerasim_2015_05_27_14_47-b00) >> Java HotSpot(TM) 64-Bit Server VM (build >> 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) >> >> 25) 100663296 >> >> real 0m2.585s >> user 0m1.875s >> sys 0m0.887s >> >> Sincerely yours, >> Ivan >> >> On 27.05.2015 2:38, Xueming Shen wrote: >>> Ivan, >>> >>> It might be worth trying String.index + StringBuilder, instead of >>> writing/handling everything yourself. >>> Yes, it inevitably adds an arraycopy at the end to convert the >>> StrinbBuilder to String, but it might have >>> better balance between performance and code complexity. The regex is >>> probably a little heavy for >>> literal string replacement, but StringBuilder should not be that bad >>> ... >>> >>> -Sherman >>> >>> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>>> I updated the webrev: >>>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>>> >>>> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE >>>> with Integer.MAX_VALUE, which seems to be more accurate here. >>>> >>>> And I want to add that this proposed implementation is not only >>>> faster, but also more memory efficient. >>>> The following simple stress-test shows that the proposed version is >>>> able to handle twice larger strings, comparing to the current >>>> implementation. >>>> >>>> ---------------------------------------- >>>> public class C { >>>> public static void main(String[] args) throws Throwable { >>>> String s = "string"; >>>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>>> try { >>>> s = s.replace("string", "stringstring"); >>>> } catch (OutOfMemoryError o) { >>>> System.out.println(i + ") " + s.length()); >>>> break; >>>> } >>>> } >>>> } >>>> } >>>> ---------------------------------------- >>>> >>>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>>> java version "1.9.0-ea" >>>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>>> >>>> 25) 100663296 >>>> >>>> real 0m4.525s >>>> user 0m4.402s >>>> sys 0m1.189s >>>> >>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>> java version "1.9.0-internal" >>>> Java(TM) SE Runtime Environment (build >>>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>>> Java HotSpot(TM) 64-Bit Server VM (build >>>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>>> >>>> 26) 201326592 >>>> >>>> real 0m2.139s >>>> user 0m1.960s >>>> sys 0m0.461s >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>>> Hello everybody! >>>>> >>>>> I know many people here like it when the performance is getting >>>>> better. >>>>> It was suggested to make the literal variant of String.replace() >>>>> faster. >>>>> Currently, this method is implemented as a few calls to regexp >>>>> API, so that the whole implementation takes only two lines of code. >>>>> >>>>> I've created two versions of the fix. >>>>> In the first one, we scan the string and store indices of the >>>>> found substrings in an array. >>>>> Then, we allocate the precisely sized char array and fill it it. >>>>> The case with the empty target has to be handled separately. >>>>> >>>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>>> >>>>> The second variant is much less verbose, however it's less >>>>> efficient too. >>>>> Here the StringJoiner is used as an intermediate storage. >>>>> >>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>>> >>>>> >>>>> Here are the micro-benchmark results (in a string of ~300 chars do >>>>> ~15 replacements). >>>>> 0) Baseline >>>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>>> >>>>> 1) Heavy-duty +308% >>>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>>> >>>>> 2) StringJoiner +190% >>>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>>> >>>>> >>>>> Personally, I like my first variant better, even though it adds >>>>> almost 300 lines of code. >>>>> But I'd like to hear what people think of it. >>>>> >>>>> Sincerely yours, >>>>> Ivan >>>>> >>>>> >>>> >>> >>> >>> >> > > > From xueming.shen at oracle.com Wed May 27 17:40:16 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 27 May 2015 10:40:16 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <5565F988.7080209@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> Message-ID: <55660180.8030003@oracle.com> The .append(srepl) -> append(srep.value) And I would simply remove the "fastpath" for the target.length() = 0 special case ... And maybe pick an appropriate initial size (maybe this.length + 16 * diff) for the sb to further reduce its internal expanding ... Personally this code is straightforward and I would be happy with the 800+ vs 1000+ score diff. public String replace(CharSequence target, CharSequence replacement) { String starget = target.toString(); int targLen = starget.length(); String srepl = replacement.toString(); int j = indexOf(starget); // special case: nothing to replace if (j< 0) { return this; } final char[] value = this.value; StringBuilder sb = new StringBuilder(); int i = 0; do { sb.append(value, i, j - i) .append(srepl.value); i = j + targLen; } while ((j = indexOf(starget, i))> 0); return sb.append(this, i, length()).toString(); } -Sherman On 05/27/2015 10:06 AM, Ivan Gerasimov wrote: > > On 27.05.2015 18:44, Xueming Shen wrote: >> You might want to use directly sb.append.(char[], off, len), instead of append(str, off, len)/append(str). > > Ah, yes sure! It would improve things. > I updated the webrev in place: > http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ > > However the general picture is almost the same: > performance: > Baseline: MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s > StringBuilder: MyBenchmark.test thrpt 40 808'033.808 ? 22152.166 ops/s > Arrays: MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s > > Memory efficiency is still less then for array-version: > $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C > java version "1.9.0-internal" > Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00) > Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) > > 25) 100663296 > > real 0m2.429s > user 0m2.112s > sys 0m0.792s > > Sincerely yours, > Ivan > >> Btw, is the target.lenght==0 the popular use case/scenario? Just wonder why do we need a special case >> here for it. >> >> thanks, >> -Sherman >> >> On 5/27/15 8:29 AM, Ivan Gerasimov wrote: >>> For completeness, here's another webrev, which uses StringBuilder: >>> http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ >>> >>> Its performance is somewhere in between the current implementation and the array-based implementation: >>> MyBenchmark.test thrpt 40 796'059.192 ? 12455.970 ops/s >>> >>> Memory efficiency is less then the one of array-based implementation: >>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>> java version "1.9.0-internal" >>> Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00) >>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) >>> >>> 25) 100663296 >>> >>> real 0m2.585s >>> user 0m1.875s >>> sys 0m0.887s >>> >>> Sincerely yours, >>> Ivan >>> >>> On 27.05.2015 2:38, Xueming Shen wrote: >>>> Ivan, >>>> >>>> It might be worth trying String.index + StringBuilder, instead of writing/handling everything yourself. >>>> Yes, it inevitably adds an arraycopy at the end to convert the StrinbBuilder to String, but it might have >>>> better balance between performance and code complexity. The regex is probably a little heavy for >>>> literal string replacement, but StringBuilder should not be that bad ... >>>> >>>> -Sherman >>>> >>>> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>>>> I updated the webrev: >>>>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>>>> >>>>> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE with Integer.MAX_VALUE, which seems to be more accurate here. >>>>> >>>>> And I want to add that this proposed implementation is not only faster, but also more memory efficient. >>>>> The following simple stress-test shows that the proposed version is able to handle twice larger strings, comparing to the current implementation. >>>>> >>>>> ---------------------------------------- >>>>> public class C { >>>>> public static void main(String[] args) throws Throwable { >>>>> String s = "string"; >>>>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>>>> try { >>>>> s = s.replace("string", "stringstring"); >>>>> } catch (OutOfMemoryError o) { >>>>> System.out.println(i + ") " + s.length()); >>>>> break; >>>>> } >>>>> } >>>>> } >>>>> } >>>>> ---------------------------------------- >>>>> >>>>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>>>> java version "1.9.0-ea" >>>>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>>>> >>>>> 25) 100663296 >>>>> >>>>> real 0m4.525s >>>>> user 0m4.402s >>>>> sys 0m1.189s >>>>> >>>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>>> java version "1.9.0-internal" >>>>> Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>>>> >>>>> 26) 201326592 >>>>> >>>>> real 0m2.139s >>>>> user 0m1.960s >>>>> sys 0m0.461s >>>>> >>>>> Sincerely yours, >>>>> Ivan >>>>> >>>>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>>>> Hello everybody! >>>>>> >>>>>> I know many people here like it when the performance is getting better. >>>>>> It was suggested to make the literal variant of String.replace() faster. >>>>>> Currently, this method is implemented as a few calls to regexp API, so that the whole implementation takes only two lines of code. >>>>>> >>>>>> I've created two versions of the fix. >>>>>> In the first one, we scan the string and store indices of the found substrings in an array. >>>>>> Then, we allocate the precisely sized char array and fill it it. >>>>>> The case with the empty target has to be handled separately. >>>>>> >>>>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>>>> >>>>>> The second variant is much less verbose, however it's less efficient too. >>>>>> Here the StringJoiner is used as an intermediate storage. >>>>>> >>>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>>>> >>>>>> >>>>>> Here are the micro-benchmark results (in a string of ~300 chars do ~15 replacements). >>>>>> 0) Baseline >>>>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>>>> >>>>>> 1) Heavy-duty +308% >>>>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>>>> >>>>>> 2) StringJoiner +190% >>>>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>>>> >>>>>> >>>>>> Personally, I like my first variant better, even though it adds almost 300 lines of code. >>>>>> But I'd like to hear what people think of it. >>>>>> >>>>>> Sincerely yours, >>>>>> Ivan >>>>>> >>>>>> >>>>> >>>> >>>> >>>> >>> >> >> >> > From ivan.gerasimov at oracle.com Wed May 27 17:59:05 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 27 May 2015 20:59:05 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <55660180.8030003@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> Message-ID: <556605E9.3010302@oracle.com> On 27.05.2015 20:40, Xueming Shen wrote: > > The .append(srepl) -> append(srep.value) > > And I would simply remove the "fastpath" for the target.length() = 0 > special case ... > And maybe pick an appropriate initial size (maybe this.length + 16 * > diff) for the sb > to further reduce its internal expanding ... > Sorry, I forgot to comment this. This is not really a fastpath. This is a special case, which isn't handled by the general algorithm. We can modify the general algorithm, of course to handle empty target, but I thought it would be more clear to have a separate branch. I think your variant below would loop forever in the loop with an empty target: i = j + targLen; // targLen == 0 j = indexOf(starget, i) // j == i Sincerely yours, Ivan > Personally this code is straightforward and I would be happy with the > 800+ vs 1000+ > score diff. > > public String replace(CharSequence target, CharSequence > replacement) { > String starget = target.toString(); > int targLen = starget.length(); > String srepl = replacement.toString(); > > int j = indexOf(starget); > // special case: nothing to replace > if (j< 0) { > return this; > } > > final char[] value = this.value; > StringBuilder sb = new StringBuilder(); > int i = 0; > do { > sb.append(value, i, j - i) > .append(srepl.value); > i = j + targLen; > } while ((j = indexOf(starget, i))> 0); > > return sb.append(this, i, length()).toString(); > } > > -Sherman > > > On 05/27/2015 10:06 AM, Ivan Gerasimov wrote: >> >> On 27.05.2015 18:44, Xueming Shen wrote: >>> You might want to use directly sb.append.(char[], off, len), instead >>> of append(str, off, len)/append(str). >> >> Ah, yes sure! It would improve things. >> I updated the webrev in place: >> http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ >> >> However the general picture is almost the same: >> performance: >> Baseline: MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 >> ops/s >> StringBuilder: MyBenchmark.test thrpt 40 808'033.808 ? 22152.166 >> ops/s >> Arrays: MyBenchmark.test thrpt 40 1'049'235.602 ? >> 15501.803 ops/s >> >> Memory efficiency is still less then for array-version: >> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >> java version "1.9.0-internal" >> Java(TM) SE Runtime Environment (build >> 1.9.0-internal-igerasim_2015_05_27_14_47-b00) >> Java HotSpot(TM) 64-Bit Server VM (build >> 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) >> >> 25) 100663296 >> >> real 0m2.429s >> user 0m2.112s >> sys 0m0.792s >> >> Sincerely yours, >> Ivan >> >>> Btw, is the target.lenght==0 the popular use case/scenario? Just >>> wonder why do we need a special case >>> here for it. >>> >>> thanks, >>> -Sherman >>> >>> On 5/27/15 8:29 AM, Ivan Gerasimov wrote: >>>> For completeness, here's another webrev, which uses StringBuilder: >>>> http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ >>>> >>>> Its performance is somewhere in between the current implementation >>>> and the array-based implementation: >>>> MyBenchmark.test thrpt 40 796'059.192 ? 12455.970 ops/s >>>> >>>> Memory efficiency is less then the one of array-based implementation: >>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>> java version "1.9.0-internal" >>>> Java(TM) SE Runtime Environment (build >>>> 1.9.0-internal-igerasim_2015_05_27_14_47-b00) >>>> Java HotSpot(TM) 64-Bit Server VM (build >>>> 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) >>>> >>>> 25) 100663296 >>>> >>>> real 0m2.585s >>>> user 0m1.875s >>>> sys 0m0.887s >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>> On 27.05.2015 2:38, Xueming Shen wrote: >>>>> Ivan, >>>>> >>>>> It might be worth trying String.index + StringBuilder, instead of >>>>> writing/handling everything yourself. >>>>> Yes, it inevitably adds an arraycopy at the end to convert the >>>>> StrinbBuilder to String, but it might have >>>>> better balance between performance and code complexity. The regex >>>>> is probably a little heavy for >>>>> literal string replacement, but StringBuilder should not be that >>>>> bad ... >>>>> >>>>> -Sherman >>>>> >>>>> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>>>>> I updated the webrev: >>>>>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>>>>> >>>>>> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE >>>>>> with Integer.MAX_VALUE, which seems to be more accurate here. >>>>>> >>>>>> And I want to add that this proposed implementation is not only >>>>>> faster, but also more memory efficient. >>>>>> The following simple stress-test shows that the proposed version >>>>>> is able to handle twice larger strings, comparing to the current >>>>>> implementation. >>>>>> >>>>>> ---------------------------------------- >>>>>> public class C { >>>>>> public static void main(String[] args) throws Throwable { >>>>>> String s = "string"; >>>>>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>>>>> try { >>>>>> s = s.replace("string", "stringstring"); >>>>>> } catch (OutOfMemoryError o) { >>>>>> System.out.println(i + ") " + s.length()); >>>>>> break; >>>>>> } >>>>>> } >>>>>> } >>>>>> } >>>>>> ---------------------------------------- >>>>>> >>>>>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>>>>> java version "1.9.0-ea" >>>>>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>>>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>>>>> >>>>>> 25) 100663296 >>>>>> >>>>>> real 0m4.525s >>>>>> user 0m4.402s >>>>>> sys 0m1.189s >>>>>> >>>>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>>>> java version "1.9.0-internal" >>>>>> Java(TM) SE Runtime Environment (build >>>>>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>>>>> Java HotSpot(TM) 64-Bit Server VM (build >>>>>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>>>>> >>>>>> 26) 201326592 >>>>>> >>>>>> real 0m2.139s >>>>>> user 0m1.960s >>>>>> sys 0m0.461s >>>>>> >>>>>> Sincerely yours, >>>>>> Ivan >>>>>> >>>>>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>>>>> Hello everybody! >>>>>>> >>>>>>> I know many people here like it when the performance is getting >>>>>>> better. >>>>>>> It was suggested to make the literal variant of String.replace() >>>>>>> faster. >>>>>>> Currently, this method is implemented as a few calls to regexp >>>>>>> API, so that the whole implementation takes only two lines of code. >>>>>>> >>>>>>> I've created two versions of the fix. >>>>>>> In the first one, we scan the string and store indices of the >>>>>>> found substrings in an array. >>>>>>> Then, we allocate the precisely sized char array and fill it it. >>>>>>> The case with the empty target has to be handled separately. >>>>>>> >>>>>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>>>>> >>>>>>> The second variant is much less verbose, however it's less >>>>>>> efficient too. >>>>>>> Here the StringJoiner is used as an intermediate storage. >>>>>>> >>>>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>>>>> >>>>>>> >>>>>>> Here are the micro-benchmark results (in a string of ~300 chars >>>>>>> do ~15 replacements). >>>>>>> 0) Baseline >>>>>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>>>>> >>>>>>> 1) Heavy-duty +308% >>>>>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>>>>> >>>>>>> 2) StringJoiner +190% >>>>>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>>>>> >>>>>>> >>>>>>> Personally, I like my first variant better, even though it adds >>>>>>> almost 300 lines of code. >>>>>>> But I'd like to hear what people think of it. >>>>>>> >>>>>>> Sincerely yours, >>>>>>> Ivan >>>>>>> >>>>>>> >>>>>> >>>>> >>>>> >>>>> >>>> >>> >>> >>> >> > > > From xueming.shen at oracle.com Wed May 27 18:08:05 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 27 May 2015 11:08:05 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556605E9.3010302@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> Message-ID: <55660805.1030007@oracle.com> targLen = max(1, tagLen); ? On 05/27/2015 10:59 AM, Ivan Gerasimov wrote: > > > On 27.05.2015 20:40, Xueming Shen wrote: >> >> The .append(srepl) -> append(srep.value) >> >> And I would simply remove the "fastpath" for the target.length() = 0 special case ... >> And maybe pick an appropriate initial size (maybe this.length + 16 * diff) for the sb >> to further reduce its internal expanding ... >> > Sorry, I forgot to comment this. This is not really a fastpath. > This is a special case, which isn't handled by the general algorithm. > We can modify the general algorithm, of course to handle empty target, but I thought it would be more clear to have a separate branch. > > I think your variant below would loop forever in the loop with an empty target: > i = j + targLen; // targLen == 0 > j = indexOf(starget, i) // j == i > > Sincerely yours, > Ivan > >> Personally this code is straightforward and I would be happy with the 800+ vs 1000+ >> score diff. >> >> public String replace(CharSequence target, CharSequence replacement) { >> String starget = target.toString(); >> int targLen = starget.length(); >> String srepl = replacement.toString(); >> >> int j = indexOf(starget); >> // special case: nothing to replace >> if (j< 0) { >> return this; >> } >> >> final char[] value = this.value; >> StringBuilder sb = new StringBuilder(); >> int i = 0; >> do { >> sb.append(value, i, j - i) >> .append(srepl.value); >> i = j + targLen; >> } while ((j = indexOf(starget, i))> 0); >> >> return sb.append(this, i, length()).toString(); >> } >> >> -Sherman >> >> >> On 05/27/2015 10:06 AM, Ivan Gerasimov wrote: >>> >>> On 27.05.2015 18:44, Xueming Shen wrote: >>>> You might want to use directly sb.append.(char[], off, len), instead of append(str, off, len)/append(str). >>> >>> Ah, yes sure! It would improve things. >>> I updated the webrev in place: >>> http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ >>> >>> However the general picture is almost the same: >>> performance: >>> Baseline: MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>> StringBuilder: MyBenchmark.test thrpt 40 808'033.808 ? 22152.166 ops/s >>> Arrays: MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>> >>> Memory efficiency is still less then for array-version: >>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>> java version "1.9.0-internal" >>> Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00) >>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) >>> >>> 25) 100663296 >>> >>> real 0m2.429s >>> user 0m2.112s >>> sys 0m0.792s >>> >>> Sincerely yours, >>> Ivan >>> >>>> Btw, is the target.lenght==0 the popular use case/scenario? Just wonder why do we need a special case >>>> here for it. >>>> >>>> thanks, >>>> -Sherman >>>> >>>> On 5/27/15 8:29 AM, Ivan Gerasimov wrote: >>>>> For completeness, here's another webrev, which uses StringBuilder: >>>>> http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ >>>>> >>>>> Its performance is somewhere in between the current implementation and the array-based implementation: >>>>> MyBenchmark.test thrpt 40 796'059.192 ? 12455.970 ops/s >>>>> >>>>> Memory efficiency is less then the one of array-based implementation: >>>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>>> java version "1.9.0-internal" >>>>> Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00) >>>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) >>>>> >>>>> 25) 100663296 >>>>> >>>>> real 0m2.585s >>>>> user 0m1.875s >>>>> sys 0m0.887s >>>>> >>>>> Sincerely yours, >>>>> Ivan >>>>> >>>>> On 27.05.2015 2:38, Xueming Shen wrote: >>>>>> Ivan, >>>>>> >>>>>> It might be worth trying String.index + StringBuilder, instead of writing/handling everything yourself. >>>>>> Yes, it inevitably adds an arraycopy at the end to convert the StrinbBuilder to String, but it might have >>>>>> better balance between performance and code complexity. The regex is probably a little heavy for >>>>>> literal string replacement, but StringBuilder should not be that bad ... >>>>>> >>>>>> -Sherman >>>>>> >>>>>> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>>>>>> I updated the webrev: >>>>>>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>>>>>> >>>>>>> In the check at 2300-2301 and 2351-2352 I replaced MAX_ARRAY_SIZE with Integer.MAX_VALUE, which seems to be more accurate here. >>>>>>> >>>>>>> And I want to add that this proposed implementation is not only faster, but also more memory efficient. >>>>>>> The following simple stress-test shows that the proposed version is able to handle twice larger strings, comparing to the current implementation. >>>>>>> >>>>>>> ---------------------------------------- >>>>>>> public class C { >>>>>>> public static void main(String[] args) throws Throwable { >>>>>>> String s = "string"; >>>>>>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>>>>>> try { >>>>>>> s = s.replace("string", "stringstring"); >>>>>>> } catch (OutOfMemoryError o) { >>>>>>> System.out.println(i + ") " + s.length()); >>>>>>> break; >>>>>>> } >>>>>>> } >>>>>>> } >>>>>>> } >>>>>>> ---------------------------------------- >>>>>>> >>>>>>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>>>>>> java version "1.9.0-ea" >>>>>>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>>>>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>>>>>> >>>>>>> 25) 100663296 >>>>>>> >>>>>>> real 0m4.525s >>>>>>> user 0m4.402s >>>>>>> sys 0m1.189s >>>>>>> >>>>>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>>>>> java version "1.9.0-internal" >>>>>>> Java(TM) SE Runtime Environment (build 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>>>>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>>>>>> >>>>>>> 26) 201326592 >>>>>>> >>>>>>> real 0m2.139s >>>>>>> user 0m1.960s >>>>>>> sys 0m0.461s >>>>>>> >>>>>>> Sincerely yours, >>>>>>> Ivan >>>>>>> >>>>>>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>>>>>> Hello everybody! >>>>>>>> >>>>>>>> I know many people here like it when the performance is getting better. >>>>>>>> It was suggested to make the literal variant of String.replace() faster. >>>>>>>> Currently, this method is implemented as a few calls to regexp API, so that the whole implementation takes only two lines of code. >>>>>>>> >>>>>>>> I've created two versions of the fix. >>>>>>>> In the first one, we scan the string and store indices of the found substrings in an array. >>>>>>>> Then, we allocate the precisely sized char array and fill it it. >>>>>>>> The case with the empty target has to be handled separately. >>>>>>>> >>>>>>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>>>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>>>>>> >>>>>>>> The second variant is much less verbose, however it's less efficient too. >>>>>>>> Here the StringJoiner is used as an intermediate storage. >>>>>>>> >>>>>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>>>>>> >>>>>>>> >>>>>>>> Here are the micro-benchmark results (in a string of ~300 chars do ~15 replacements). >>>>>>>> 0) Baseline >>>>>>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>>>>>> >>>>>>>> 1) Heavy-duty +308% >>>>>>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>>>>>> >>>>>>>> 2) StringJoiner +190% >>>>>>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>>>>>> >>>>>>>> >>>>>>>> Personally, I like my first variant better, even though it adds almost 300 lines of code. >>>>>>>> But I'd like to hear what people think of it. >>>>>>>> >>>>>>>> Sincerely yours, >>>>>>>> Ivan >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>> >>>> >>>> >>> >> >> >> > From Roger.Riggs at Oracle.com Wed May 27 19:09:47 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 27 May 2015 15:09:47 -0400 Subject: RFR 9/8: JDK-8081022 : java/time/test/java/time/format/TestZoneTextPrinterParser.java fails by timeout on slow device Message-ID: <5566167B.9040705@Oracle.com> Please review this test modification to reduce the running time and to apply the recommended randomness pattern. webrev: http://cr.openjdk.java.net/~rriggs/webrev-random-8081022/ Issue: https://bugs.openjdk.java.net/browse/JDK-8081022 Thanks, Roger From xueming.shen at oracle.com Wed May 27 19:09:34 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 27 May 2015 12:09:34 -0700 Subject: RFR JDK-8038310: Re-examine integration of extended Charsets Message-ID: <5566166E.4040506@oracle.com> Hi, Please help review the change of changing the hard-wired extended charsets loading mechanism to ServiceLoader.loadInstalled(), for the module system. With the fix for JDK-8069588 in JDK 9 all charsets needed to startup in supported environments are in the base module. This change is to use ServiceLoader to load the extended charsets to remove the java.base dependency on jdk.charsets moduel. Issues: JDK-8038310: Re-examine integration of extended Charsets JDK-8069588: Need to avoid attempting to load extended charsets (from jdk.charsets module) before module system initialization runs webrev: http://cr.openjdk.java.net/~sherman/8069588_8038310/webrev Thanks -Sherman From naoto.sato at oracle.com Wed May 27 19:29:31 2015 From: naoto.sato at oracle.com (Naoto Sato) Date: Wed, 27 May 2015 12:29:31 -0700 Subject: RFR 9/8: JDK-8081022 : java/time/test/java/time/format/TestZoneTextPrinterParser.java fails by timeout on slow device In-Reply-To: <5566167B.9040705@Oracle.com> References: <5566167B.9040705@Oracle.com> Message-ID: <55661B1B.3060605@oracle.com> +1 Naoto On 5/27/15 12:09 PM, Roger Riggs wrote: > Please review this test modification to reduce the running time > and to apply the recommended randomness pattern. > > webrev: > http://cr.openjdk.java.net/~rriggs/webrev-random-8081022/ > > Issue: > https://bugs.openjdk.java.net/browse/JDK-8081022 > > Thanks, Roger > > From ivan.gerasimov at oracle.com Wed May 27 19:43:55 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 27 May 2015 22:43:55 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <55660805.1030007@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> Message-ID: <55661E7B.2010405@oracle.com> On 27.05.2015 21:08, Xueming Shen wrote: > targLen = max(1, tagLen); ? > Well, almost :) With such targLen, (i = j + targLen) would result in i == length() + 1, which will cause IOOBE in the following append(). I'm sure the algorithms can be adopted to run correctly with empty target, it just needs some accurate checking. But why can't we consider the first variant of replace()? http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ It's still faster and it can handle larger strings without OOME. I think this is important. I haven't heard any critics of it except for its relative complexity, comparing to the original code. And we have a backup variant with StringBuilder, if problems are found. Sincerely yours, Ivan > On 05/27/2015 10:59 AM, Ivan Gerasimov wrote: >> >> >> On 27.05.2015 20:40, Xueming Shen wrote: >>> >>> The .append(srepl) -> append(srep.value) >>> >>> And I would simply remove the "fastpath" for the target.length() = 0 >>> special case ... >>> And maybe pick an appropriate initial size (maybe this.length + 16 * >>> diff) for the sb >>> to further reduce its internal expanding ... >>> >> Sorry, I forgot to comment this. This is not really a fastpath. >> This is a special case, which isn't handled by the general algorithm. >> We can modify the general algorithm, of course to handle empty >> target, but I thought it would be more clear to have a separate branch. >> >> I think your variant below would loop forever in the loop with an >> empty target: >> i = j + targLen; // targLen == 0 >> j = indexOf(starget, i) // j == i >> >> Sincerely yours, >> Ivan >> >>> Personally this code is straightforward and I would be happy with >>> the 800+ vs 1000+ >>> score diff. >>> >>> public String replace(CharSequence target, CharSequence >>> replacement) { >>> String starget = target.toString(); >>> int targLen = starget.length(); >>> String srepl = replacement.toString(); >>> >>> int j = indexOf(starget); >>> // special case: nothing to replace >>> if (j< 0) { >>> return this; >>> } >>> >>> final char[] value = this.value; >>> StringBuilder sb = new StringBuilder(); >>> int i = 0; >>> do { >>> sb.append(value, i, j - i) >>> .append(srepl.value); >>> i = j + targLen; >>> } while ((j = indexOf(starget, i))> 0); >>> >>> return sb.append(this, i, length()).toString(); >>> } >>> >>> -Sherman >>> >>> >>> On 05/27/2015 10:06 AM, Ivan Gerasimov wrote: >>>> >>>> On 27.05.2015 18:44, Xueming Shen wrote: >>>>> You might want to use directly sb.append.(char[], off, len), >>>>> instead of append(str, off, len)/append(str). >>>> >>>> Ah, yes sure! It would improve things. >>>> I updated the webrev in place: >>>> http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ >>>> >>>> However the general picture is almost the same: >>>> performance: >>>> Baseline: MyBenchmark.test thrpt 40 257'051.948 ? >>>> 4537.484 ops/s >>>> StringBuilder: MyBenchmark.test thrpt 40 808'033.808 ? >>>> 22152.166 ops/s >>>> Arrays: MyBenchmark.test thrpt 40 1'049'235.602 ? >>>> 15501.803 ops/s >>>> >>>> Memory efficiency is still less then for array-version: >>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>> java version "1.9.0-internal" >>>> Java(TM) SE Runtime Environment (build >>>> 1.9.0-internal-igerasim_2015_05_27_14_47-b00) >>>> Java HotSpot(TM) 64-Bit Server VM (build >>>> 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) >>>> >>>> 25) 100663296 >>>> >>>> real 0m2.429s >>>> user 0m2.112s >>>> sys 0m0.792s >>>> >>>> Sincerely yours, >>>> Ivan >>>> >>>>> Btw, is the target.lenght==0 the popular use case/scenario? Just >>>>> wonder why do we need a special case >>>>> here for it. >>>>> >>>>> thanks, >>>>> -Sherman >>>>> >>>>> On 5/27/15 8:29 AM, Ivan Gerasimov wrote: >>>>>> For completeness, here's another webrev, which uses StringBuilder: >>>>>> http://cr.openjdk.java.net/~igerasim/8058779/03/webrev/ >>>>>> >>>>>> Its performance is somewhere in between the current >>>>>> implementation and the array-based implementation: >>>>>> MyBenchmark.test thrpt 40 796'059.192 ? 12455.970 ops/s >>>>>> >>>>>> Memory efficiency is less then the one of array-based >>>>>> implementation: >>>>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>>>> java version "1.9.0-internal" >>>>>> Java(TM) SE Runtime Environment (build >>>>>> 1.9.0-internal-igerasim_2015_05_27_14_47-b00) >>>>>> Java HotSpot(TM) 64-Bit Server VM (build >>>>>> 1.9.0-internal-igerasim_2015_05_27_14_47-b00, mixed mode) >>>>>> >>>>>> 25) 100663296 >>>>>> >>>>>> real 0m2.585s >>>>>> user 0m1.875s >>>>>> sys 0m0.887s >>>>>> >>>>>> Sincerely yours, >>>>>> Ivan >>>>>> >>>>>> On 27.05.2015 2:38, Xueming Shen wrote: >>>>>>> Ivan, >>>>>>> >>>>>>> It might be worth trying String.index + StringBuilder, instead >>>>>>> of writing/handling everything yourself. >>>>>>> Yes, it inevitably adds an arraycopy at the end to convert the >>>>>>> StrinbBuilder to String, but it might have >>>>>>> better balance between performance and code complexity. The >>>>>>> regex is probably a little heavy for >>>>>>> literal string replacement, but StringBuilder should not be that >>>>>>> bad ... >>>>>>> >>>>>>> -Sherman >>>>>>> >>>>>>> On 5/26/15 4:11 PM, Ivan Gerasimov wrote: >>>>>>>> I updated the webrev: >>>>>>>> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >>>>>>>> >>>>>>>> In the check at 2300-2301 and 2351-2352 I replaced >>>>>>>> MAX_ARRAY_SIZE with Integer.MAX_VALUE, which seems to be more >>>>>>>> accurate here. >>>>>>>> >>>>>>>> And I want to add that this proposed implementation is not >>>>>>>> only faster, but also more memory efficient. >>>>>>>> The following simple stress-test shows that the proposed >>>>>>>> version is able to handle twice larger strings, comparing to >>>>>>>> the current implementation. >>>>>>>> >>>>>>>> ---------------------------------------- >>>>>>>> public class C { >>>>>>>> public static void main(String[] args) throws Throwable { >>>>>>>> String s = "string"; >>>>>>>> for (int i = 1; i < Integer.MAX_VALUE; ++i) { >>>>>>>> try { >>>>>>>> s = s.replace("string", "stringstring"); >>>>>>>> } catch (OutOfMemoryError o) { >>>>>>>> System.out.println(i + ") " + s.length()); >>>>>>>> break; >>>>>>>> } >>>>>>>> } >>>>>>>> } >>>>>>>> } >>>>>>>> ---------------------------------------- >>>>>>>> >>>>>>>> $ time ~/java9/jdk/bin/java -showversion -Xmx1g C >>>>>>>> java version "1.9.0-ea" >>>>>>>> Java(TM) SE Runtime Environment (build 1.9.0-ea-b63) >>>>>>>> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b63, mixed mode) >>>>>>>> >>>>>>>> 25) 100663296 >>>>>>>> >>>>>>>> real 0m4.525s >>>>>>>> user 0m4.402s >>>>>>>> sys 0m1.189s >>>>>>>> >>>>>>>> $ time ~/java9/jdk-build/bin/java -showversion -Xmx1g C >>>>>>>> java version "1.9.0-internal" >>>>>>>> Java(TM) SE Runtime Environment (build >>>>>>>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00) >>>>>>>> Java HotSpot(TM) 64-Bit Server VM (build >>>>>>>> 1.9.0-internal-igerasim_2015_05_23_19_25-b00, mixed mode) >>>>>>>> >>>>>>>> 26) 201326592 >>>>>>>> >>>>>>>> real 0m2.139s >>>>>>>> user 0m1.960s >>>>>>>> sys 0m0.461s >>>>>>>> >>>>>>>> Sincerely yours, >>>>>>>> Ivan >>>>>>>> >>>>>>>> On 24.05.2015 23:17, Ivan Gerasimov wrote: >>>>>>>>> Hello everybody! >>>>>>>>> >>>>>>>>> I know many people here like it when the performance is >>>>>>>>> getting better. >>>>>>>>> It was suggested to make the literal variant of >>>>>>>>> String.replace() faster. >>>>>>>>> Currently, this method is implemented as a few calls to regexp >>>>>>>>> API, so that the whole implementation takes only two lines of >>>>>>>>> code. >>>>>>>>> >>>>>>>>> I've created two versions of the fix. >>>>>>>>> In the first one, we scan the string and store indices of the >>>>>>>>> found substrings in an array. >>>>>>>>> Then, we allocate the precisely sized char array and fill it it. >>>>>>>>> The case with the empty target has to be handled separately. >>>>>>>>> >>>>>>>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>>>>>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/00/webrev/ >>>>>>>>> >>>>>>>>> The second variant is much less verbose, however it's less >>>>>>>>> efficient too. >>>>>>>>> Here the StringJoiner is used as an intermediate storage. >>>>>>>>> >>>>>>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/01/webrev/ >>>>>>>>> >>>>>>>>> >>>>>>>>> Here are the micro-benchmark results (in a string of ~300 >>>>>>>>> chars do ~15 replacements). >>>>>>>>> 0) Baseline >>>>>>>>> MyBenchmark.test thrpt 40 257'051.948 ? 4537.484 ops/s >>>>>>>>> >>>>>>>>> 1) Heavy-duty +308% >>>>>>>>> MyBenchmark.test thrpt 40 1'049'235.602 ? 15501.803 ops/s >>>>>>>>> >>>>>>>>> 2) StringJoiner +190% >>>>>>>>> MyBenchmark.test thrpt 40 746'000.629 ? 15387.036 ops/s >>>>>>>>> >>>>>>>>> >>>>>>>>> Personally, I like my first variant better, even though it >>>>>>>>> adds almost 300 lines of code. >>>>>>>>> But I'd like to hear what people think of it. >>>>>>>>> >>>>>>>>> Sincerely yours, >>>>>>>>> Ivan >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>>> >>>>> >>>> >>> >>> >>> >> > > > From xueming.shen at oracle.com Wed May 27 20:10:34 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 27 May 2015 13:10:34 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <55661E7B.2010405@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> Message-ID: <556624BA.1030703@oracle.com> On 05/27/2015 12:43 PM, Ivan Gerasimov wrote: > > > On 27.05.2015 21:08, Xueming Shen wrote: >> targLen = max(1, tagLen); ? >> > Well, almost :) > With such targLen, (i = j + targLen) would result in i == length() + 1, which will cause IOOBE in the following append(). > > I'm sure the algorithms can be adopted to run correctly with empty target, it just needs some accurate checking. > > But why can't we consider the first variant of replace()? > http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ > > It's still faster and it can handle larger strings without OOME. I think this is important. > > I haven't heard any critics of it except for its relative complexity, comparing to the original code. > And we have a backup variant with StringBuilder, if problems are found. > From xueming.shen at oracle.com Wed May 27 20:15:33 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 27 May 2015 13:15:33 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556624BA.1030703@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> Message-ID: <556625E5.5040806@oracle.com> On 05/27/2015 01:10 PM, Xueming Shen wrote: > On 05/27/2015 12:43 PM, Ivan Gerasimov wrote: >> >> >> On 27.05.2015 21:08, Xueming Shen wrote: >>> targLen = max(1, tagLen); ? >>> >> Well, almost :) >> With such targLen, (i = j + targLen) would result in i == length() + 1, which will cause IOOBE in the following append(). >> >> I'm sure the algorithms can be adopted to run correctly with empty target, it just needs some accurate checking. >> >> But why can't we consider the first variant of replace()? >> http://cr.openjdk.java.net/~igerasim/8058779/02/webrev/ >> >> It's still faster and it can handle larger strings without OOME. I think this is important. >> >> I haven't heard any critics of it except for its relative complexity, comparing to the original code. >> And we have a backup variant with StringBuilder, if problems are found. >> > > Personally I prefer not do "buffer management" issue in replace(), StringBuilder is just doing the job fine. If possible I would avoid to have a special method() to just work a corner case. "is relative complexity" is a critics. We are trying to see if we can achieve most of the gain without such complexity. -Sherman From mandy.chung at oracle.com Wed May 27 23:57:07 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 27 May 2015 16:57:07 -0700 Subject: Review Request for 8081347: Add @modules to jdk_core tests Message-ID: jtreg supports a new @modules to specify the module and the internal API that a test depends on. This is to prepare when the module boundaries are enforced at runtime. This initial patch is contributed by several of us including Alexander Kulyakhtin and Alan. Webrev at: http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8081347/webrev.00/ Thanks Mandy From mandy.chung at oracle.com Thu May 28 05:07:10 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 27 May 2015 22:07:10 -0700 Subject: Review Request for 8081347: Add @modules to jdk_core tests In-Reply-To: References: Message-ID: An update to this patch: Joe pointed out that javax/sql/testng has a TEST.properties file. I now move the @modules from test/javax/sql/testng individual tests to the modules key in TEST.properties. $ hg diff test/javax/sql/testng diff --git a/test/javax/sql/testng/TEST.properties b/test/javax/sql/testng/TEST.properties --- a/test/javax/sql/testng/TEST.properties +++ b/test/javax/sql/testng/TEST.properties @@ -2,3 +2,6 @@ TestNG.dirs= . othervm.dirs= . lib.dirs = /java/sql/testng +modules = java.sql.rowset/com.sun.rowset \ + java.sql.rowset/com.sun.rowset.internal \ + java.sql.rowset/com.sun.rowset.providers Mandy > On May 27, 2015, at 4:57 PM, Mandy Chung wrote: > > jtreg supports a new @modules to specify the module and the internal API that a test depends on. This is to prepare when the module boundaries are enforced at runtime. This initial patch is contributed by several of us including Alexander Kulyakhtin and Alan. > > Webrev at: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8081347/webrev.00/ > > Thanks > Mandy From huizhe.wang at oracle.com Thu May 28 05:26:16 2015 From: huizhe.wang at oracle.com (huizhe wang) Date: Wed, 27 May 2015 22:26:16 -0700 Subject: Review Request for 8081347: Add @modules to jdk_core tests In-Reply-To: References: Message-ID: <5566A6F8.6050904@oracle.com> Looks good to me, Mandy. -Joe On 5/27/2015 10:07 PM, Mandy Chung wrote: > An update to this patch: > > Joe pointed out that javax/sql/testng has a TEST.properties file. I now move the @modules from test/javax/sql/testng individual tests to the modules key in TEST.properties. > > $ hg diff test/javax/sql/testng > diff --git a/test/javax/sql/testng/TEST.properties b/test/javax/sql/testng/TEST.properties > --- a/test/javax/sql/testng/TEST.properties > +++ b/test/javax/sql/testng/TEST.properties > @@ -2,3 +2,6 @@ > TestNG.dirs= . > othervm.dirs= . > lib.dirs = /java/sql/testng > +modules = java.sql.rowset/com.sun.rowset \ > + java.sql.rowset/com.sun.rowset.internal \ > + java.sql.rowset/com.sun.rowset.providers > > Mandy > >> On May 27, 2015, at 4:57 PM, Mandy Chung wrote: >> >> jtreg supports a new @modules to specify the module and the internal API that a test depends on. This is to prepare when the module boundaries are enforced at runtime. This initial patch is contributed by several of us including Alexander Kulyakhtin and Alan. >> >> Webrev at: >> http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8081347/webrev.00/ >> >> Thanks >> Mandy From joe.darcy at oracle.com Thu May 28 05:38:01 2015 From: joe.darcy at oracle.com (joe darcy) Date: Wed, 27 May 2015 22:38:01 -0700 Subject: JDK 9 RFR of JDK-8081359: Update bug reporting URL Message-ID: <5566A9B9.8020802@oracle.com> Hello, As the venerable URL http://bugreport.sun.com/bugreport/ has been retired and replaced with http://bugreport.java.com/bugreport/ Occurrences of the old URL in the source base should be updated. Please review the patch below which does this: --- a/src/java.base/share/native/libjava/System.c Thu May 28 09:11:14 2015 +0800 +++ b/src/java.base/share/native/libjava/System.c Wed May 27 22:36:07 2015 -0700 @@ -111,7 +111,7 @@ #ifndef VENDOR /* Third party may overwrite this. */ #define VENDOR "Oracle Corporation" #define VENDOR_URL "http://java.oracle.com/" -#define VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/" +#define VENDOR_URL_BUG "http://bugreport.java.com/bugreport/" #endif #define JAVA_MAX_SUPPORTED_VERSION 52 diff -r de8fc052f1b6 src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties --- a/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties Thu May 28 09:11:14 2015 +0800 +++ b/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties Wed May 27 22:36:07 2015 -0700 @@ -498,9 +498,9 @@ javac.err.cant.write=\ Can''t write: {0} javac.err.fatal.error=\ - An error has occurred in the compiler; please file a bug report (http://bugreport.sun.com/bugreport/). + An error has occurred in the compiler; please file a bug report (http://bugreport.java.com/bugreport/). javac.err.fatal.exception=\ - An exception has occurred in the compiler; please file a bug report (http://bugreport.sun.com/bugreport/). + An exception has occurred in the compiler; please file a bug report (http://bugreport.java.com/bugreport/). javac.err.no.inner.classes=\ Support for inner classes has been disabled. javac.err.uncaught.exception=\ These were the only remaining occurrences of the old URL in the OpenJDK code base. The occurrence in langtools was previously updated (JDK-8078560). Thanks, -Joe From joe.darcy at oracle.com Thu May 28 05:47:09 2015 From: joe.darcy at oracle.com (joe darcy) Date: Wed, 27 May 2015 22:47:09 -0700 Subject: JDK 9 RFR of JDK-8081245: MHIllegalAccess.java failing across platforms Message-ID: <5566ABDD.5030502@oracle.com> Hello, The latest HotSpot integration into JDK 9 dev introduced a test failure in java/lang/invoke/8022701/MHIllegalAccess.java.MHIllegalAccess.java Please review the change below to problem list the test until such time as the fix for the test (JDK-8080428) propagates to dev: --- a/test/ProblemList.txt Thu May 28 09:11:14 2015 +0800 +++ b/test/ProblemList.txt Wed May 27 22:43:49 2015 -0700 @@ -123,6 +123,9 @@ # 8029891 java/lang/ClassLoader/deadlock/GetResource.java generic-all +# 8080428 +java/lang/invoke/8022701/MHIllegalAccess.java.MHIllegalAccess.java generic-all + ############################################################################ # jdk_instrument Thanks, -Joe From Alan.Bateman at oracle.com Thu May 28 06:47:28 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 28 May 2015 07:47:28 +0100 Subject: JDK 9 RFR of JDK-8081245: MHIllegalAccess.java failing across platforms In-Reply-To: <5566ABDD.5030502@oracle.com> References: <5566ABDD.5030502@oracle.com> Message-ID: <5566BA00.6070704@oracle.com> On 28/05/2015 06:47, joe darcy wrote: > Hello, > > The latest HotSpot integration into JDK 9 dev introduced a test > failure in > > java/lang/invoke/8022701/MHIllegalAccess.java.MHIllegalAccess.java > > Please review the change below to problem list the test until such > time as the fix for the test (JDK-8080428) propagates to dev: > > --- a/test/ProblemList.txt Thu May 28 09:11:14 2015 +0800 > +++ b/test/ProblemList.txt Wed May 27 22:43:49 2015 -0700 > @@ -123,6 +123,9 @@ > # 8029891 > java/lang/ClassLoader/deadlock/GetResource.java generic-all > > +# 8080428 > +java/lang/invoke/8022701/MHIllegalAccess.java.MHIllegalAccess.java > generic-all > + > ############################################################################ > Looks okay to me although might be better if Vladimir just pushes the fix for JDK-8080428 to jdk9/dev/jdk. -Alan. From Alan.Bateman at oracle.com Thu May 28 06:52:02 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 28 May 2015 07:52:02 +0100 Subject: Review Request for 8081347: Add @modules to jdk_core tests In-Reply-To: References: Message-ID: <5566BB12.7010709@oracle.com> On 28/05/2015 06:07, Mandy Chung wrote: > An update to this patch: > > Updated patch looks good to me. I assume that Alexander Kulyakhtin and others will follow up at some point to also add @modules to aid test selection. -Alan From Alan.Bateman at oracle.com Thu May 28 07:03:50 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 28 May 2015 08:03:50 +0100 Subject: RFR JDK-8028480: (zipfs) NoSuchFileException on creating a file in ZipFileSystem with CREATE and WRITE In-Reply-To: <5565EA48.30901@oracle.com> References: <5564C81D.7050403@oracle.com> <5565E24C.3060101@oracle.com> <5565EA48.30901@oracle.com> Message-ID: <5566BDD6.4070005@oracle.com> On 27/05/2015 17:01, Xueming Shen wrote: > > I'm aware of converting the options to internal flags in unix fs, but > thought that is for the convenience... > We are not saving the options for any future/internal use, simply > checking its value on the spot. Just wonder > really need to make the defensive copy here? The invoker changes the > options during the invocation of this > method? Yes because otherwise the validation can be bypassed. ZipFileSystem.newFileChannel is a good example where it is copying the options (to add CREATE_NEW) after it validates when it should make the copy first to avoid the options changing under its feet. There may be a few places in the ZIP provider where this should be done. -Alan. From Alan.Bateman at oracle.com Thu May 28 07:46:35 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 28 May 2015 08:46:35 +0100 Subject: RFR JDK-8038310: Re-examine integration of extended Charsets In-Reply-To: <5566166E.4040506@oracle.com> References: <5566166E.4040506@oracle.com> Message-ID: <5566C7DB.9040204@oracle.com> On 27/05/2015 20:09, Xueming Shen wrote: > Hi, > > Please help review the change of changing the hard-wired extended > charsets loading mechanism > to ServiceLoader.loadInstalled(), for the module system. With the fix > for JDK-8069588 in JDK 9 all > charsets needed to startup in supported environments are in the base > module. This change is to > use ServiceLoader to load the extended charsets to remove the > java.base dependency on jdk.charsets > moduel. > > Issues: > JDK-8038310: Re-examine integration of extended Charsets > JDK-8069588: Need to avoid attempting to load extended charsets (from > jdk.charsets module) before module system initialization runs > > webrev: > http://cr.openjdk.java.net/~sherman/8069588_8038310/webrev It's good to get this moved to ServiceLoader as that will make it easy for jdk.charsets to be a service provider module. ExtendedProviderHolder.extendedProviders() returning an array is a surprise but okay given that there will mostly be just the one provider. Builds for small devices might have zero and would be a bit cleaner to return an empty array rather than null. Also a bit cleaner to just use the for-each construct, I don't see any reason to use hasNext/next here. The VM.isBooted check looks right as we should never get here during startup if running on a supported configuration. -Alan From konstantin.shefov at oracle.com Thu May 28 09:03:20 2015 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Thu, 28 May 2015 12:03:20 +0300 Subject: [8u-dev] Review request : JDK-8062904: TEST_BUG: Tests java/lang/invoke/LFCaching fail when run with -Xcomp option In-Reply-To: <5565F6D5.7030900@oracle.com> References: <5565D9BB.60003@oracle.com> <5565F6D5.7030900@oracle.com> Message-ID: <5566D9D8.4090401@oracle.com> Vladimir, This fix is not for timeout issue, this fix is for "java.lang.VirtualMachineError: out of space in CodeCache for adapters". Timeout issue is other bug and should be filed separately. I do not know why SQE added RULES with timeout to this bug. By the way, if -Xcomp is set on JDK 8u, test works if not more than one iteration is allowed. The same thing was for JDK 9 until JDK-8046809 had been fixed. -Konstantin On 27.05.2015 19:54, Vladimir Ivanov wrote: > Have you tried to reduce iteration granularity? > > Probably, checking execution duration on every test case is more robust. > > Best regards, > Vladimir Ivanov > > On 5/27/15 5:50 PM, Konstantin Shefov wrote: >> Hello, >> >> Please review the test bug fix >> https://bugs.openjdk.java.net/browse/JDK-8062904 >> Webrev is http://cr.openjdk.java.net/~kshefov/8062904/webrev.01/ >> Test fails only against JDK 8u and passes against JDK 9. >> >> Thanks >> >> -Konstantin From tomasz.kowalczewski at gmail.com Thu May 28 10:06:56 2015 From: tomasz.kowalczewski at gmail.com (Tomasz Kowalczewski) Date: Thu, 28 May 2015 12:06:56 +0200 Subject: String.contains(CharSequence) calls toString on argument In-Reply-To: References: <550C3F7A.1020404@oracle.com> <550C42F0.6010506@oracle.com> Message-ID: Hello all, encouraged by your responses I did a simple implementation and performed some JMH experiments. Details below. Webrev [1] contains my changes. I deliberately wanted to do minimal code changes. The gist of it is implementing indexOf that works on CharSequence instead of String's internal char array. Both versions are almost identical (I did not change existing implementation in place to not impact all other String-only paths that use it). In my first attempt I just inlined (and simplified) indexOf implementation into String::contains, but in the end decided to create general purpose (package private) version. This might prove useful for others[2] JMH test project is here [3]. All benchmarks were run using "java -jar benchmarks.jar -wi 10 -i 10 -f -prof gc" on Amazon EC2 instance (c4.xlarge, 4 virtual cores). I have run it against three java builds: a. stock java 8u40 b. my own build from clean jdk9 sources c. my own build from modified jdk9 sources Results with gc profiler enabled are included in benchmark repo. This gist contains summary results [4]. I know that this test covers only very narrow space of possible performance regressions (ideas form more comprehensive tests are welcome). The results show that String only path is not impacted by my changes. When using actual CharSequence (StringBuilder in this case) we are mostly winning, exception is case when CharSequence is of medium size and has many partial matches in searched string. I hope this exercise will be useful to someone and that this change might be considered for inclusion in OpenJDK. If not then maybe at least tests for String::indexOf? [1] http://openjdk.s3-website-us-east-1.amazonaws.com/ [2] Changeset from http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-May/033678.html uses indexOf that could accept CharSequence instead of String. [3] https://github.com/tkowalcz/openjdk-jmh [4] https://gist.github.com/tkowalcz/d8f5b9435e184f65fd2a Regards, Tomasz Kowalczewski On Sat, Mar 21, 2015 at 9:21 AM, Tomasz Kowalczewski < tomasz.kowalczewski at gmail.com> wrote: > There are other places which accept CharSequence and iterate over it > not caring about possible concurrent modification (the only sane way > IMHO). Examples are String.contentEquals and String.join that uses > StringJoiner which iterates its argument char by char. > > It looks like contains is the exception in this regard. > > On 20 mar 2015, at 17:05, Vitaly Davidovich wrote: > > >> > >> If CharSequence is mutable and thread-safe, I would expect toString() > >> implementation to provide the atomic snapshot (e.g. do the > >> synchronization). Therefore, I find Sherman's argument interesting. > > > > > > That's my point about "it ought to be up to the caller" -- they're in a > > position to make this call, but String.contains() is playing defensive > > because it has no clue of the context. > > > > On Fri, Mar 20, 2015 at 11:55 AM, Aleksey Shipilev < > > aleksey.shipilev at oracle.com> wrote: > > > >> If CharSequence is mutable and thread-safe, I would expect toString() > >> implementation to provide the atomic snapshot (e.g. do the > >> synchronization). Therefore, I find Sherman's argument interesting. > >> > >> On the other hand, we don't seem to be having any details/requirements > >> for contains(CharSequence) w.r.t. it's own argument. What if > >> String.contains pulls the values one charAt at a time? The concurrency > >> requirements are not enforceable in CharSequence alone then, unless you > >> call the supposed-to-be-atomic toString() first. > >> > >> -Aleksey. > >> > >>> On 03/20/2015 06:48 PM, Vitaly Davidovich wrote: > >>> Yes, but that ought to be for the caller to decide. Also, although the > >>> resulting String is immutable, toString() itself may observe mutation. > >>> > >>> On Fri, Mar 20, 2015 at 11:40 AM, Xueming Shen < > xueming.shen at oracle.com> > >>> wrote: > >>> > >>>>> On 03/20/2015 02:34 AM, Tomasz Kowalczewski wrote: > >>>>> > >>>>> Hello! > >>>>> > >>>>> Current implementation of String.contains that accepts CharSequence > >> calls > >>>>> toString on it and passes resulting string to indexOf(String). This > IMO > >>>>> defeats the purpose of using CharSequences (that is to have a mutable > >>>>> character buffer and not allocate unnecessary objects). > >>>> It is arguable that cs.toString() may serve the purpose of taking a > >>>> snapshot of an otherwise > >>>> "mutable" character buffer? > >>>> > >>>> -Sherman > >>>> > >>>> > >>>> Is changing this a desirable development? It seems pretty > >> straightforward > >>>>> to port indexOf(String) to use CharSequence. > >>>>> > >>>>> If all you need is patch then I can work on it (I have signed OCA) > just > >>>>> wanted to make sure it is not a futile work. > >> > >> > >> > -- Tomasz Kowalczewski From Ulf.Zibis at CoSoCo.de Thu May 28 10:35:41 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Thu, 28 May 2015 12:35:41 +0200 Subject: String.contains(CharSequence) calls toString on argument In-Reply-To: References: <550C3F7A.1020404@oracle.com> <550C42F0.6010506@oracle.com> Message-ID: <5566EF7D.9020104@CoSoCo.de> Hi, I more would like: 2199 return (s instanceof String) 2200 ? indexOf((String) s) >= 0; 2201 : indexOf(value, 0, value.length, s, 0, s.length(), 0) >= 0; or: 2199 return (s instanceof String 2200 ? indexOf((String) s) 2201 : indexOf(value, 0, value.length, s, 0, s.length(), 0)) 2202 >= 0; or: 2199 int index = (s instanceof String) 2200 ? indexOf((String) s) 2201 : indexOf(value, 0, value.length, s, 0, s.length(), 0); 2202return index >= 0; -Ulf Am 28.05.2015 um 12:06 schrieb Tomasz Kowalczewski: > Hello all, > > encouraged by your responses I did a simple implementation and performed > some JMH experiments. Details below. > > Webrev [1] contains my changes. I deliberately wanted to do minimal code > changes. The gist of it is implementing indexOf that works on CharSequence > instead of String's internal char array. Both versions are almost identical > (I did not change existing implementation in place to not impact all other > String-only paths that use it). > > In my first attempt I just inlined (and simplified) indexOf implementation > into String::contains, but in the end decided to create general purpose > (package private) version. This might prove useful for others[2] > > JMH test project is here [3]. All benchmarks were run using "java -jar > benchmarks.jar -wi 10 -i 10 -f -prof gc" on Amazon EC2 instance (c4.xlarge, > 4 virtual cores). I have run it against three java builds: > > a. stock java 8u40 > b. my own build from clean jdk9 sources > c. my own build from modified jdk9 sources > > Results with gc profiler enabled are included in benchmark repo. This gist > contains summary results [4]. > > I know that this test covers only very narrow space of possible performance > regressions (ideas form more comprehensive tests are welcome). The results > show that String only path is not impacted by my changes. When using actual > CharSequence (StringBuilder in this case) we are mostly winning, exception > is case when CharSequence is of medium size and has many partial matches in > searched string. > > I hope this exercise will be useful to someone and that this change might > be considered for inclusion in OpenJDK. If not then maybe at least tests > for String::indexOf? > > [1] http://openjdk.s3-website-us-east-1.amazonaws.com/ > [2] Changeset from > http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-May/033678.html uses > indexOf that could accept CharSequence instead of String. > [3] https://github.com/tkowalcz/openjdk-jmh > [4] https://gist.github.com/tkowalcz/d8f5b9435e184f65fd2a > > Regards, > Tomasz Kowalczewski > > On Sat, Mar 21, 2015 at 9:21 AM, Tomasz Kowalczewski < > tomasz.kowalczewski at gmail.com> wrote: > >> There are other places which accept CharSequence and iterate over it >> not caring about possible concurrent modification (the only sane way >> IMHO). Examples are String.contentEquals and String.join that uses >> StringJoiner which iterates its argument char by char. >> >> It looks like contains is the exception in this regard. >> >> On 20 mar 2015, at 17:05, Vitaly Davidovich wrote: >> >>>> If CharSequence is mutable and thread-safe, I would expect toString() >>>> implementation to provide the atomic snapshot (e.g. do the >>>> synchronization). Therefore, I find Sherman's argument interesting. >>> >>> That's my point about "it ought to be up to the caller" -- they're in a >>> position to make this call, but String.contains() is playing defensive >>> because it has no clue of the context. >>> >>> On Fri, Mar 20, 2015 at 11:55 AM, Aleksey Shipilev < >>> aleksey.shipilev at oracle.com> wrote: >>> >>>> If CharSequence is mutable and thread-safe, I would expect toString() >>>> implementation to provide the atomic snapshot (e.g. do the >>>> synchronization). Therefore, I find Sherman's argument interesting. >>>> >>>> On the other hand, we don't seem to be having any details/requirements >>>> for contains(CharSequence) w.r.t. it's own argument. What if >>>> String.contains pulls the values one charAt at a time? The concurrency >>>> requirements are not enforceable in CharSequence alone then, unless you >>>> call the supposed-to-be-atomic toString() first. >>>> >>>> -Aleksey. >>>> >>>>> On 03/20/2015 06:48 PM, Vitaly Davidovich wrote: >>>>> Yes, but that ought to be for the caller to decide. Also, although the >>>>> resulting String is immutable, toString() itself may observe mutation. >>>>> >>>>> On Fri, Mar 20, 2015 at 11:40 AM, Xueming Shen < >> xueming.shen at oracle.com> >>>>> wrote: >>>>> >>>>>>> On 03/20/2015 02:34 AM, Tomasz Kowalczewski wrote: >>>>>>> >>>>>>> Hello! >>>>>>> >>>>>>> Current implementation of String.contains that accepts CharSequence >>>> calls >>>>>>> toString on it and passes resulting string to indexOf(String). This >> IMO >>>>>>> defeats the purpose of using CharSequences (that is to have a mutable >>>>>>> character buffer and not allocate unnecessary objects). >>>>>> It is arguable that cs.toString() may serve the purpose of taking a >>>>>> snapshot of an otherwise >>>>>> "mutable" character buffer? >>>>>> >>>>>> -Sherman >>>>>> >>>>>> >>>>>> Is changing this a desirable development? It seems pretty >>>> straightforward >>>>>>> to port indexOf(String) to use CharSequence. >>>>>>> >>>>>>> If all you need is patch then I can work on it (I have signed OCA) >> just >>>>>>> wanted to make sure it is not a futile work. >>>> >>>> > > From weijun.wang at oracle.com Thu May 28 10:43:20 2015 From: weijun.wang at oracle.com (Weijun Wang) Date: Thu, 28 May 2015 18:43:20 +0800 Subject: setOut() and redirectOutput() together Message-ID: <5566F148.6060305@oracle.com> I am writing something like this ByteArrayOutputStream bout = new ByteArrayOutputStream(); System.setOut(out); System.out.println("Hello"); ProcessBuilder pb1 = new ProcessBuilder("./native-app"); pb1.redirectOutput(ProcessBuilder.Redirect.INHERIT); pb1.start(); Now "Hello" no longer shows on screen, but the output of "native-app" still shows up there. What else shall I do? This is Ubuntu 14.04.2. Thanks Max From dawid.weiss at gmail.com Thu May 28 10:48:35 2015 From: dawid.weiss at gmail.com (Dawid Weiss) Date: Thu, 28 May 2015 12:48:35 +0200 Subject: setOut() and redirectOutput() together In-Reply-To: <5566F148.6060305@oracle.com> References: <5566F148.6060305@oracle.com> Message-ID: Your code makes the native app inherit native stdout/err process descriptors, you need to pipe the output from your native app to Java and then redirect the output to wherever you wish (byte array for example). In other words, Redirect.PIPE + pipe code. Dawid On Thu, May 28, 2015 at 12:43 PM, Weijun Wang wrote: > I am writing something like this > > ByteArrayOutputStream bout = new ByteArrayOutputStream(); > System.setOut(out); > > System.out.println("Hello"); > > ProcessBuilder pb1 = new ProcessBuilder("./native-app"); > pb1.redirectOutput(ProcessBuilder.Redirect.INHERIT); > > pb1.start(); > > Now "Hello" no longer shows on screen, but the output of "native-app" still > shows up there. What else shall I do? > > This is Ubuntu 14.04.2. > > Thanks > Max From tomasz.kowalczewski at gmail.com Thu May 28 10:57:26 2015 From: tomasz.kowalczewski at gmail.com (Tomasz Kowalczewski) Date: Thu, 28 May 2015 12:57:26 +0200 Subject: String.contains(CharSequence) calls toString on argument In-Reply-To: <5566EF7D.9020104@CoSoCo.de> References: <550C3F7A.1020404@oracle.com> <550C42F0.6010506@oracle.com> <5566EF7D.9020104@CoSoCo.de> Message-ID: Hi, thank you for taking time to read my proposal. Is this a matter of some OpenJDK coding conventions? I myself never use ternary operator and always use if with braces. My experience is that it improves code readability. If I have to apply one of proposed changes I would choose first or third. Regards, Tomasz On Thu, May 28, 2015 at 12:35 PM, Ulf Zibis wrote: > Hi, > > I more would like: > > 2199 return (s instanceof String) > 2200 ? indexOf((String) s) >= 0; > 2201 : indexOf(value, 0, value.length, s, 0, s.length(), > 0) >= 0; > > or: > > 2199 return (s instanceof String > 2200 ? indexOf((String) s) > 2201 : indexOf(value, 0, value.length, s, 0, s.length(), > 0)) > 2202 >= 0; > > or: > > 2199 int index = (s instanceof String) > 2200 ? indexOf((String) s) > 2201 : indexOf(value, 0, value.length, s, 0, s.length(), > 0); > 2202return index >= 0; > > -Ulf > > > > Am 28.05.2015 um 12:06 schrieb Tomasz Kowalczewski: > >> Hello all, >> >> encouraged by your responses I did a simple implementation and performed >> some JMH experiments. Details below. >> >> Webrev [1] contains my changes. I deliberately wanted to do minimal code >> changes. The gist of it is implementing indexOf that works on CharSequence >> instead of String's internal char array. Both versions are almost >> identical >> (I did not change existing implementation in place to not impact all other >> String-only paths that use it). >> >> In my first attempt I just inlined (and simplified) indexOf implementation >> into String::contains, but in the end decided to create general purpose >> (package private) version. This might prove useful for others[2] >> >> JMH test project is here [3]. All benchmarks were run using "java -jar >> benchmarks.jar -wi 10 -i 10 -f -prof gc" on Amazon EC2 instance >> (c4.xlarge, >> 4 virtual cores). I have run it against three java builds: >> >> a. stock java 8u40 >> b. my own build from clean jdk9 sources >> c. my own build from modified jdk9 sources >> >> Results with gc profiler enabled are included in benchmark repo. This gist >> contains summary results [4]. >> >> I know that this test covers only very narrow space of possible >> performance >> regressions (ideas form more comprehensive tests are welcome). The results >> show that String only path is not impacted by my changes. When using >> actual >> CharSequence (StringBuilder in this case) we are mostly winning, exception >> is case when CharSequence is of medium size and has many partial matches >> in >> searched string. >> >> I hope this exercise will be useful to someone and that this change might >> be considered for inclusion in OpenJDK. If not then maybe at least tests >> for String::indexOf? >> >> [1] http://openjdk.s3-website-us-east-1.amazonaws.com/ >> [2] Changeset from >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-May/033678.html >> uses >> indexOf that could accept CharSequence instead of String. >> [3] https://github.com/tkowalcz/openjdk-jmh >> [4] https://gist.github.com/tkowalcz/d8f5b9435e184f65fd2a >> >> Regards, >> Tomasz Kowalczewski >> >> On Sat, Mar 21, 2015 at 9:21 AM, Tomasz Kowalczewski < >> tomasz.kowalczewski at gmail.com> wrote: >> >> There are other places which accept CharSequence and iterate over it >>> not caring about possible concurrent modification (the only sane way >>> IMHO). Examples are String.contentEquals and String.join that uses >>> StringJoiner which iterates its argument char by char. >>> >>> It looks like contains is the exception in this regard. >>> >>> On 20 mar 2015, at 17:05, Vitaly Davidovich wrote: >>> >>> If CharSequence is mutable and thread-safe, I would expect toString() >>>>> implementation to provide the atomic snapshot (e.g. do the >>>>> synchronization). Therefore, I find Sherman's argument interesting. >>>>> >>>> >>>> That's my point about "it ought to be up to the caller" -- they're in a >>>> position to make this call, but String.contains() is playing defensive >>>> because it has no clue of the context. >>>> >>>> On Fri, Mar 20, 2015 at 11:55 AM, Aleksey Shipilev < >>>> aleksey.shipilev at oracle.com> wrote: >>>> >>>> If CharSequence is mutable and thread-safe, I would expect toString() >>>>> implementation to provide the atomic snapshot (e.g. do the >>>>> synchronization). Therefore, I find Sherman's argument interesting. >>>>> >>>>> On the other hand, we don't seem to be having any details/requirements >>>>> for contains(CharSequence) w.r.t. it's own argument. What if >>>>> String.contains pulls the values one charAt at a time? The concurrency >>>>> requirements are not enforceable in CharSequence alone then, unless you >>>>> call the supposed-to-be-atomic toString() first. >>>>> >>>>> -Aleksey. >>>>> >>>>> On 03/20/2015 06:48 PM, Vitaly Davidovich wrote: >>>>>> Yes, but that ought to be for the caller to decide. Also, although >>>>>> the >>>>>> resulting String is immutable, toString() itself may observe mutation. >>>>>> >>>>>> On Fri, Mar 20, 2015 at 11:40 AM, Xueming Shen < >>>>>> >>>>> xueming.shen at oracle.com> >>> >>>> wrote: >>>>>> >>>>>> On 03/20/2015 02:34 AM, Tomasz Kowalczewski wrote: >>>>>>>> >>>>>>>> Hello! >>>>>>>> >>>>>>>> Current implementation of String.contains that accepts CharSequence >>>>>>>> >>>>>>> calls >>>>> >>>>>> toString on it and passes resulting string to indexOf(String). This >>>>>>>> >>>>>>> IMO >>> >>>> defeats the purpose of using CharSequences (that is to have a mutable >>>>>>>> character buffer and not allocate unnecessary objects). >>>>>>>> >>>>>>> It is arguable that cs.toString() may serve the purpose of taking a >>>>>>> snapshot of an otherwise >>>>>>> "mutable" character buffer? >>>>>>> >>>>>>> -Sherman >>>>>>> >>>>>>> >>>>>>> Is changing this a desirable development? It seems pretty >>>>>>> >>>>>> straightforward >>>>> >>>>>> to port indexOf(String) to use CharSequence. >>>>>>>> >>>>>>>> If all you need is patch then I can work on it (I have signed OCA) >>>>>>>> >>>>>>> just >>> >>>> wanted to make sure it is not a futile work. >>>>>>>> >>>>>>> >>>>> >>>>> >> >> > -- Tomasz Kowalczewski From peter.levart at gmail.com Thu May 28 11:37:45 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 28 May 2015 13:37:45 +0200 Subject: RFR: 8077242: Add default method CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) In-Reply-To: <554E9B01.3000504@oracle.com> References: <554E2FDF.40603@oracle.com> <554E324E.3090205@oracle.com> <554E3EE0.5020400@oracle.com> <554E9B01.3000504@oracle.com> Message-ID: <5566FE09.60208@gmail.com> On 05/10/2015 01:40 AM, Ivan Gerasimov wrote: > Thanks Martin for quick reply! > > On 10.05.2015 1:17, Martin Buchholz wrote: >> >> Martin can you recollect if there were any concerns? >> >> >> It's absolutely true that I dropped the ball on this in jdk8, >> discouraged by David's message here: >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-May/017174.html >> > > Ah, yes. I see the problem. > I'm not going to suggest a general solution, but would it make sense > to at least create an overloaded method > AbstractStringBuilder.append(String str, int start, int end)? > > Here's a draft webrev for this proposal: > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8077242 > WEBREV: http://cr.openjdk.java.net/~igerasim/8077242/01/webrev/ > > Sincerely yours, > Ivan > Hi Ivan and others, I think it would be nice to give users back an official way to handle sub-strings as views without copying the characters. After offset & length were dropped from String, String.substring and String.subSequence started copying characters. That's ok for small sub-sequences, but unacceptable for large. If there was an explicit API that allowed old behaviour it could be used in scenarios where this has performance advantage. Here's what I'm thinking about: http://cr.openjdk.java.net/~plevart/jdk9-dev/ArrayCharSequence/webrev.01/ I know that this somehow conflicts with the efforts of JEP 254: Compact Strings - as it assumes that internal String.value character array can be shared between a String and an ArrayCharSequence, but above proposal could be tweaked to accommodate that too: instead of ArrayCharSequence(String, ...) constructors, there could be an internal or public implementation of a special ConstantLengthCharSequence that was used for the purpose of String sub-sequence views only. In that case the ArrayCharSequence as a public class could be dropped all together and new public String method(s) introduced: public CharSequence toCharSequenceView(); // and/or public CharSequence subSequenceView(int start, int end); ...that returned private implementation of a ConstantLengthCharSequence. I wonder how the above proposal when combined with StringJoiner based solution of optimizing String.replace compares with your index-array based specialized solution. Regards, Peter From peter.levart at gmail.com Thu May 28 13:43:30 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 28 May 2015 15:43:30 +0200 Subject: setOut() and redirectOutput() together In-Reply-To: References: <5566F148.6060305@oracle.com> Message-ID: <55671B82.5020006@gmail.com> That's right. System.setOut(OutputStream) only assigns some OutputStream object to the System.out field, so any Java code using System.out to retrieve the OutputStream will use the newly set OuputStream. ProcessBuilder.Redirect.INHERIT on the other hand, tells ProcessBuilder where to redirect the standard output of the subprocess when it is started. This has nothing to do with System.out field except that by default the field holds an OutputStream object that outputs to the standard output of the java process and that is also where ProcessBuilder.Redirect.INHERIT instructs ProcessBuilder to redirect the output of the started subprocess (inherits the output of the java process). In other words: the "target" of the default System.out and subprocess redirected output when using ProcessBuilder.Redirect.INHERIT is the same. When you change System.out, you change it's target, but that doesn't change where ProcessBuilder.Redirect.INHERIT redirects to. Regards, Peter On 05/28/2015 12:48 PM, Dawid Weiss wrote: > Your code makes the native app inherit native stdout/err process > descriptors, you need to pipe the output from your native app to Java > and then redirect the output to wherever you wish (byte array for > example). > > In other words, Redirect.PIPE + pipe code. > > Dawid > > On Thu, May 28, 2015 at 12:43 PM, Weijun Wang wrote: >> I am writing something like this >> >> ByteArrayOutputStream bout = new ByteArrayOutputStream(); >> System.setOut(out); >> >> System.out.println("Hello"); >> >> ProcessBuilder pb1 = new ProcessBuilder("./native-app"); >> pb1.redirectOutput(ProcessBuilder.Redirect.INHERIT); >> >> pb1.start(); >> >> Now "Hello" no longer shows on screen, but the output of "native-app" still >> shows up there. What else shall I do? >> >> This is Ubuntu 14.04.2. >> >> Thanks >> Max From Roger.Riggs at Oracle.com Thu May 28 13:49:22 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 28 May 2015 09:49:22 -0400 Subject: JDK 9 RFR of JDK-8081245: MHIllegalAccess.java failing across platforms In-Reply-To: <5566ABDD.5030502@oracle.com> References: <5566ABDD.5030502@oracle.com> Message-ID: <55671CE2.6050408@Oracle.com> Hi Joe, +1 to add to the problem list. Looks fine. Roger On 5/28/2015 1:47 AM, joe darcy wrote: > Hello, > > The latest HotSpot integration into JDK 9 dev introduced a test > failure in > > java/lang/invoke/8022701/MHIllegalAccess.java.MHIllegalAccess.java > > Please review the change below to problem list the test until such > time as the fix for the test (JDK-8080428) propagates to dev: > > --- a/test/ProblemList.txt Thu May 28 09:11:14 2015 +0800 > +++ b/test/ProblemList.txt Wed May 27 22:43:49 2015 -0700 > @@ -123,6 +123,9 @@ > # 8029891 > java/lang/ClassLoader/deadlock/GetResource.java generic-all > > +# 8080428 > +java/lang/invoke/8022701/MHIllegalAccess.java.MHIllegalAccess.java > generic-all > + > ############################################################################ > > > # jdk_instrument > > Thanks, > > -Joe From Roger.Riggs at Oracle.com Thu May 28 14:12:36 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 28 May 2015 10:12:36 -0400 Subject: RFR 9: 8077350 : JEP 102 Process API Updates Implementation Message-ID: <55672254.7060902@Oracle.com> Thanks to everyone who has reviewed the Process API updates and contributed comments and improvements. Unless there are any showstoppers, I'd like to commit the work completed so far and treat any issues that come up as incremental changes. Please comment on these changes or if I missed giving credit to any reviewers. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-process-8077350/ javadoc: http://cr.openjdk.java.net/~rriggs/ph-apidraft/ Thanks, Roger From peter.levart at gmail.com Thu May 28 14:35:14 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 28 May 2015 16:35:14 +0200 Subject: RFR(M,v9): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <7EB0BE71-1608-4047-B71D-1A9EAA9083BB@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> <5564802A.2010403@oracle.com> <5565738A.4040109@gmail.com> <7EB0BE71-1608-4047-B71D-1A9EAA9083BB@oracle.com> Message-ID: <556727A2.9060209@gmail.com> Hi Mandy, On 05/27/2015 03:32 PM, Mandy Chung wrote: >> On May 27, 2015, at 12:34 AM, Peter Levart wrote: >> >> Hi Dmitry, >> >> The jdk part looks OK (no great changes on this side from last webrev). Is there a particular reason why the return type of printFinalizayionQueue() method is Object[] and not Map.Entry[] ? >> > Taking it further - is it simpler to return String[] of all classnames including the duplicated ones and have the VM do the count? Are you concerned with the size of the String[]? Yes, the histogram is much smaller than the list of all instances. There can be millions of instances waiting in finalizer queue, but only a few distinct classes. What could be done in Java to simplify things in native code but still not format the output is to convert the array of Map.Entry(s) into an Object[] array of alternating {String, int[], String, int[], .... } Would this simplify native code for the price of a little extra work in Java? The sizes of old and new arrays are not big (# of distinct classes of finalizable objects in the queue). > >> For the hotspot part, I have a few reservations. You expect that the type of array elements will be HashMap.Node and that the key/value fields will be at fixed offsets. Is this even true for all architectures (32bit, 64bit +-UseCompressedOops)? >> >> The type of HashMap entry is controlled by code in HashMap which has a long history of changes. Next time the implementation of HashMap changes, your code could break. Would it be possible to only use public API? To invoke methods on Map.Entry interface to obtain the key and value? >> > Indeed, depending on the HashMap internal implementation is a bad idea. > > Mandy Regards, Peter > >> Regards, Peter >> >> On 05/26/2015 04:16 PM, Dmitry Samersoff wrote: >>> Hi Everybody, >>> >>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.09/ >>> >>> Please review updated webrev - >>> >>> printFinalizationQueue now returns and array of Map.Entry>> and all formatting is done on VM side. >>> >>> -Dmitry >>> >>> On 2015-05-21 02:07, Mandy Chung wrote: >>>>> On May 19, 2015, at 11:51 PM, Dmitry Samersoff >>>>> > wrote: >>>>> >>>>> Other alternatives could be to do all hashing/sorting/printing on native >>>>> layer i.e. implement printFinalizationQueue inside VM. >>>>> >>>>> Both options has pros and cons - Java based solution requires less JNI >>>>> calls and better readable but takes more memory. >>>>> >>>>> It might be better to return an array of Map.Entry >>>>> objects to VM rather than one huge string. >>>> The output and formatting should be done by jcmd. What you really need >>>> to get a peek on the finalizer queue and print the histogram. The VM >>>> has the heap histogram implementation. Have you considered leveraging >>>> that? >>>> >>>> 5: 1012 40480 java.lang.ref.Finalizer >>>> >>>> You can find the registered Finalizer instances. The downside is that >>>> icmd -finalizerinfo stops the world. I think it?s not unreasonable for >>>> this diagnostic command to be expensive like -heap command. >>>> >>>> Mandy From lance.andersen at oracle.com Thu May 28 14:41:35 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 28 May 2015 10:41:35 -0400 Subject: Review Request for 8081347: Add @modules to jdk_core tests In-Reply-To: References: Message-ID: <413328B6-B0F8-4C39-AB07-90091FC3672A@oracle.com> Hi Mandy, The webrev and the diff below seem fine. Best Lance On May 28, 2015, at 1:07 AM, Mandy Chung wrote: > An update to this patch: > > Joe pointed out that javax/sql/testng has a TEST.properties file. I now move the @modules from test/javax/sql/testng individual tests to the modules key in TEST.properties. > > $ hg diff test/javax/sql/testng > diff --git a/test/javax/sql/testng/TEST.properties b/test/javax/sql/testng/TEST.properties > --- a/test/javax/sql/testng/TEST.properties > +++ b/test/javax/sql/testng/TEST.properties > @@ -2,3 +2,6 @@ > TestNG.dirs= . > othervm.dirs= . > lib.dirs = /java/sql/testng > +modules = java.sql.rowset/com.sun.rowset \ > + java.sql.rowset/com.sun.rowset.internal \ > + java.sql.rowset/com.sun.rowset.providers > > Mandy > >> On May 27, 2015, at 4:57 PM, Mandy Chung wrote: >> >> jtreg supports a new @modules to specify the module and the internal API that a test depends on. This is to prepare when the module boundaries are enforced at runtime. This initial patch is contributed by several of us including Alexander Kulyakhtin and Alan. >> >> Webrev at: >> http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8081347/webrev.00/ >> >> Thanks >> Mandy > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From jason_mehrens at hotmail.com Thu May 28 14:44:20 2015 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Thu, 28 May 2015 09:44:20 -0500 Subject: RFR: 8077242: Add default method CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) In-Reply-To: <5566FE09.60208@gmail.com> References: <554E2FDF.40603@oracle.com>, <554E324E.3090205@oracle.com>, <554E3EE0.5020400@oracle.com>, , <554E9B01.3000504@oracle.com>, <5566FE09.60208@gmail.com> Message-ID: Peter, Have we considered just embracing CharBuffer.wrap(CharSequence, int, int) work as way to support the old substring behavior? If you dig through the code, that creates a java.nio.StringCharBuffer which is a view of the wrapped string. We could then optimize all of the friend classes to special case CharBuffer and use the bulk get methods. The nice thing is that there should be no way to create a malicious CharBuffer which should fix the concern mentioned here: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-May/017174.html. Regards, Jason > Hi Ivan and others, > > I think it would be nice to give users back an official way to handle > sub-strings as views without copying the characters. After offset & > length were dropped from String, String.substring and String.subSequence > started copying characters. That's ok for small sub-sequences, but > unacceptable for large. If there was an explicit API that allowed old > behaviour it could be used in scenarios where this has performance > advantage. Here's what I'm thinking about: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ArrayCharSequence/webrev.01/ > > I know that this somehow conflicts with the efforts of JEP 254: Compact > Strings - as it assumes that internal String.value character array can > be shared between a String and an ArrayCharSequence, but above proposal > could be tweaked to accommodate that too: instead of > ArrayCharSequence(String, ...) constructors, there could be an internal > or public implementation of a special ConstantLengthCharSequence that > was used for the purpose of String sub-sequence views only. In that case > the ArrayCharSequence as a public class could be dropped all together > and new public String method(s) introduced: > > public CharSequence toCharSequenceView(); // and/or > public CharSequence subSequenceView(int start, int end); > > ...that returned private implementation of a ConstantLengthCharSequence. > > I wonder how the above proposal when combined with StringJoiner based > solution of optimizing String.replace compares with your index-array > based specialized solution. > > Regards, Peter > From peter.levart at gmail.com Thu May 28 15:19:45 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 28 May 2015 17:19:45 +0200 Subject: RFR: 8077242: Add default method CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) In-Reply-To: References: <554E2FDF.40603@oracle.com>, <554E324E.3090205@oracle.com>, <554E3EE0.5020400@oracle.com>, , <554E9B01.3000504@oracle.com>, <5566FE09.60208@gmail.com> Message-ID: <55673211.90406@gmail.com> On 05/28/2015 04:44 PM, Jason Mehrens wrote: > Peter, > > > Have we considered just embracing CharBuffer.wrap(CharSequence, int, int) work as way to support the old substring behavior? If you dig through the code, that creates a java.nio.StringCharBuffer which is a view of the wrapped string. We could then optimize all of the friend classes to special case CharBuffer and use the bulk get methods. The nice thing is that there should be no way to create a malicious CharBuffer which should fix the concern mentioned here: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-May/017174.html. > > > Regards, > > > Jason Thanks Jason for pointing me to this. So all we need is specialization in StringBuilder and perhaps StringJoiner (to not make the String from CharSequence immediately if it is a StringCharBuffer). I'll try to prepare that specialization patch to see what it takes... Regards, Peter > > >> Hi Ivan and others, >> >> I think it would be nice to give users back an official way to handle >> sub-strings as views without copying the characters. After offset & >> length were dropped from String, String.substring and String.subSequence >> started copying characters. That's ok for small sub-sequences, but >> unacceptable for large. If there was an explicit API that allowed old >> behaviour it could be used in scenarios where this has performance >> advantage. Here's what I'm thinking about: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ArrayCharSequence/webrev.01/ >> >> I know that this somehow conflicts with the efforts of JEP 254: Compact >> Strings - as it assumes that internal String.value character array can >> be shared between a String and an ArrayCharSequence, but above proposal >> could be tweaked to accommodate that too: instead of >> ArrayCharSequence(String, ...) constructors, there could be an internal >> or public implementation of a special ConstantLengthCharSequence that >> was used for the purpose of String sub-sequence views only. In that case >> the ArrayCharSequence as a public class could be dropped all together >> and new public String method(s) introduced: >> >> public CharSequence toCharSequenceView(); // and/or >> public CharSequence subSequenceView(int start, int end); >> >> ...that returned private implementation of a ConstantLengthCharSequence. >> >> I wonder how the above proposal when combined with StringJoiner based >> solution of optimizing String.replace compares with your index-array >> based specialized solution. >> >> Regards, Peter >> From aleksej.efimov at oracle.com Thu May 28 15:33:59 2015 From: aleksej.efimov at oracle.com (Aleksej Efimov) Date: Thu, 28 May 2015 18:33:59 +0300 Subject: RFR: 8081392: getNodeValue should return NULL value for Element nodes Message-ID: <55673567.4020900@oracle.com> Hi, Please, review JDK9 fix [1] for a bug [2] in 'getNodeValue' JAXP function: According to w3c [3] getNodeValue should return 'null' value for Element nodes. This behavior was changed by JDK-8032908 [4] fix - in current implementation the node content is returned. To address this issue the JDK-8032908 fix was reverted and 'getTextContent' function was modified properly to address issue reported by JDK-8032908. JDK-8032908 test was modified to test that 'getNodeValue' returns 'null' for Element nodes. DocumentExtFunc test was modified to use 'getTextContent' instead of 'getNodeValue' for node content retrival. No related test failures on local and JPRT builds were observed. With Best Regards, Aleksej [1] http://cr.openjdk.java.net/~aefimov/8081392/9/00 [2] https://bugs.openjdk.java.net/browse/JDK-8081392 [3] http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 [4] https://bugs.openjdk.java.net/browse/JDK-8032908 From xueming.shen at oracle.com Thu May 28 15:53:29 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 28 May 2015 08:53:29 -0700 Subject: RFR JDK-8038310: Re-examine integration of extended Charsets In-Reply-To: <5566C7DB.9040204@oracle.com> References: <5566166E.4040506@oracle.com> <5566C7DB.9040204@oracle.com> Message-ID: <556739F9.2090803@oracle.com> On 5/28/15 12:46 AM, Alan Bateman wrote: > > On 27/05/2015 20:09, Xueming Shen wrote: >> Hi, >> >> Please help review the change of changing the hard-wired extended >> charsets loading mechanism >> to ServiceLoader.loadInstalled(), for the module system. With the fix >> for JDK-8069588 in JDK 9 all >> charsets needed to startup in supported environments are in the base >> module. This change is to >> use ServiceLoader to load the extended charsets to remove the >> java.base dependency on jdk.charsets >> moduel. >> >> Issues: >> JDK-8038310: Re-examine integration of extended Charsets >> JDK-8069588: Need to avoid attempting to load extended charsets (from >> jdk.charsets module) before module system initialization runs >> >> webrev: >> http://cr.openjdk.java.net/~sherman/8069588_8038310/webrev > It's good to get this moved to ServiceLoader as that will make it easy > for jdk.charsets to be a service provider module. > > ExtendedProviderHolder.extendedProviders() returning an array is a > surprise but okay given that there will mostly be just the one > provider. Builds for small devices might have zero and would be a bit > cleaner to return an empty array rather than null. Also a bit cleaner > to just use the for-each construct, I don't see any reason to use > hasNext/next here. > > The VM.isBooted check looks right as we should never get here during > startup if running on a supported configuration. > Alan, Thanks for the comments. Webrev has been updated accordingly. http://cr.openjdk.java.net/~sherman/8069588_8038310/webrev -Sherman From mandy.chung at oracle.com Thu May 28 16:05:12 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Thu, 28 May 2015 09:05:12 -0700 Subject: RFR JDK-8038310: Re-examine integration of extended Charsets In-Reply-To: <556739F9.2090803@oracle.com> References: <5566166E.4040506@oracle.com> <5566C7DB.9040204@oracle.com> <556739F9.2090803@oracle.com> Message-ID: <55673CB8.1090805@oracle.com> On 05/28/2015 08:53 AM, Xueming Shen wrote: > http://cr.openjdk.java.net/~sherman/8069588_8038310/webrev This change looks okay. This code optimizes for space and assumes one single installed provider which I am not sure if it buys us much - List.toArray might be another alternative rather than expanding/shrinking the array. But just minor point. Mandy From Ulf.Zibis at CoSoCo.de Thu May 28 16:08:55 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Thu, 28 May 2015 18:08:55 +0200 Subject: Why isn't Object.notify() a synchronized method? Message-ID: <55673D97.4010505@CoSoCo.de> Hi all, in the Javadoc of notify(), notifyAll() and wait(...) I read, that this methods should only be used with synchronisation on it's instance. So I'm wondering, why they don't have the synchronized modifier out of the box in Object class. Also I think, the following note should be moved from wait(long,int) to wait(long): /The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until either of the following two conditions has occurred:// / * /Another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method./ * /The timeout period, specified by timeout milliseconds plus nanos nanoseconds arguments, has elapsed. / Cheers, Ulf From Alan.Bateman at oracle.com Thu May 28 16:15:21 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 28 May 2015 17:15:21 +0100 Subject: RFR JDK-8038310: Re-examine integration of extended Charsets In-Reply-To: <556739F9.2090803@oracle.com> References: <5566166E.4040506@oracle.com> <5566C7DB.9040204@oracle.com> <556739F9.2090803@oracle.com> Message-ID: <55673F19.9070404@oracle.com> On 28/05/2015 16:53, Xueming Shen wrote: > > Alan, > > Thanks for the comments. Webrev has been updated accordingly. > > http://cr.openjdk.java.net/~sherman/8069588_8038310/webrev Looks good. -Alan. From vitalyd at gmail.com Thu May 28 16:13:51 2015 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 28 May 2015 12:13:51 -0400 Subject: Why isn't Object.notify() a synchronized method? In-Reply-To: <55673D97.4010505@CoSoCo.de> References: <55673D97.4010505@CoSoCo.de> Message-ID: What would synchronized on that method help with? Typically you do something while holding the lock and then notify while still holding the lock. sent from my phone On May 28, 2015 12:09 PM, "Ulf Zibis" wrote: > Hi all, > > in the Javadoc of notify(), notifyAll() and wait(...) I read, that this > methods should only be used with synchronisation on it's instance. > So I'm wondering, why they don't have the synchronized modifier out of the > box in Object class. > > Also I think, the following note should be moved from wait(long,int) to > wait(long): > /The current thread must own this object's monitor. The thread releases > ownership of this monitor and waits until either of the following two > conditions has occurred:// > / > > * /Another thread notifies threads waiting on this object's monitor to > wake up either through a > call to the notify method or the notifyAll method./ > * /The timeout period, specified by timeout milliseconds plus nanos > nanoseconds arguments, has > elapsed. / > > > > Cheers, > > Ulf > > From david.lloyd at redhat.com Thu May 28 16:27:54 2015 From: david.lloyd at redhat.com (David M. Lloyd) Date: Thu, 28 May 2015 11:27:54 -0500 Subject: Why isn't Object.notify() a synchronized method? In-Reply-To: <55673D97.4010505@CoSoCo.de> References: <55673D97.4010505@CoSoCo.de> Message-ID: <5567420A.9020406@redhat.com> Since most of the time you have to hold the lock anyway for other reasons, I think this would generally be an unwelcome change since I expect the cost of recursive lock acquisition is nonzero. On 05/28/2015 11:08 AM, Ulf Zibis wrote: > Hi all, > > in the Javadoc of notify(), notifyAll() and wait(...) I read, that this > methods should only be used with synchronisation on it's instance. > So I'm wondering, why they don't have the synchronized modifier out of > the box in Object class. > > Also I think, the following note should be moved from wait(long,int) to > wait(long): > /The current thread must own this object's monitor. The thread releases > ownership of this monitor and waits until either of the following two > conditions has occurred:// > / > > * /Another thread notifies threads waiting on this object's monitor to > wake up either through a > call to the notify method or the notifyAll method./ > * /The timeout period, specified by timeout milliseconds plus nanos > nanoseconds arguments, has > elapsed. / > > > > Cheers, > > Ulf > -- - DML From aleksey.shipilev at oracle.com Thu May 28 16:28:17 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 28 May 2015 19:28:17 +0300 Subject: Why isn't Object.notify() a synchronized method? In-Reply-To: <55673D97.4010505@CoSoCo.de> References: <55673D97.4010505@CoSoCo.de> Message-ID: <55674221.8090402@oracle.com> On 05/28/2015 07:08 PM, Ulf Zibis wrote: > Hi all, > > in the Javadoc of notify(), notifyAll() and wait(...) I read, that this > methods should only be used with synchronisation on it's instance. > So I'm wondering, why they don't have the synchronized modifier out of > the box in Object class. Well, at least "synchronized" wait() would be very odd, since it actually relinquishes the monitor. This will pose an interesting paradox: if wait() is claimed to be synchronized, but notify() requires acquiring the same monitor, how would any object be notified, ever? But really, I'd think this serves the purpose of "waking up" with all the appropriate locking state preserved. E.g. making sure only one thread owns the object monitor, and it "reenters" back right where it had left at wait() in the synchronized section. Thanks, -Aleksey From xueming.shen at oracle.com Thu May 28 16:41:58 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 28 May 2015 09:41:58 -0700 Subject: RFR JDK-8038310: Re-examine integration of extended Charsets In-Reply-To: <55673CB8.1090805@oracle.com> References: <5566166E.4040506@oracle.com> <5566C7DB.9040204@oracle.com> <556739F9.2090803@oracle.com> <55673CB8.1090805@oracle.com> Message-ID: <55674556.7070606@oracle.com> On 05/28/2015 09:05 AM, Mandy Chung wrote: > On 05/28/2015 08:53 AM, Xueming Shen wrote: >> http://cr.openjdk.java.net/~sherman/8069588_8038310/webrev > > This change looks okay. This code optimizes for space and assumes one single installed provider which I am not sure if it buys us much - List.toArray might be another alternative rather than expanding/shrinking the array. But just minor point. Thanks Mandy! Given we probably are not going to have "lots" of providers installed, probably two as the max in the foreseeable future , a List is little heavy for me:-) Let's keep this "simple code" asis for now. -Sherman From huizhe.wang at oracle.com Thu May 28 16:50:40 2015 From: huizhe.wang at oracle.com (huizhe wang) Date: Thu, 28 May 2015 09:50:40 -0700 Subject: RFR: 8081392: getNodeValue should return NULL value for Element nodes In-Reply-To: <55673567.4020900@oracle.com> References: <55673567.4020900@oracle.com> Message-ID: <55674760.6020404@oracle.com> Hi Aleksej, Thanks for the quick action! The changes are good to me. Best, Joe On 5/28/2015 8:33 AM, Aleksej Efimov wrote: > Hi, > > Please, review JDK9 fix [1] for a bug [2] in 'getNodeValue' JAXP > function: > According to w3c [3] getNodeValue should return 'null' value for > Element nodes. This behavior was changed by JDK-8032908 [4] fix - in > current implementation the node content is returned. > To address this issue the JDK-8032908 fix was reverted and > 'getTextContent' function was modified properly to address issue > reported by JDK-8032908. > JDK-8032908 test was modified to test that 'getNodeValue' returns > 'null' for Element nodes. > DocumentExtFunc test was modified to use 'getTextContent' instead of > 'getNodeValue' for node content retrival. No related test failures on > local and JPRT builds were observed. > > With Best Regards, > Aleksej > > [1] http://cr.openjdk.java.net/~aefimov/8081392/9/00 > [2] https://bugs.openjdk.java.net/browse/JDK-8081392 > [3] > http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 > [4] https://bugs.openjdk.java.net/browse/JDK-8032908 > From kumar.x.srinivasan at oracle.com Thu May 28 17:03:26 2015 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Thu, 28 May 2015 10:03:26 -0700 Subject: RFR (XS: JDK-8080991 Compilation error with recent clang .... Message-ID: <55674A5E.1090803@oracle.com> Hi, I have already reviewed it, contributed by Staffan Larsen. This is an fyi, I will push this changeset if no one has any objections. https://bugs.openjdk.java.net/browse/JDK-8080991 http://cr.openjdk.java.net/~ksrini/8080991/webrev/ Thanks Kumar From peter.levart at gmail.com Thu May 28 17:12:14 2015 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 28 May 2015 19:12:14 +0200 Subject: JEP 132: More-prompt finalization Message-ID: <55674C6E.8050509@gmail.com> Hi, Did you know that the following simple loop: public class FinalizableBottleneck { static boolean no; @Override protected void finalize() throws Throwable { // empty finalize() method does not make the object finalizable // (it is not even registered on the finalizer's list) if (no) { throw new AssertionError(); } } public static void main(String[] args) { while (true) { new FinalizableBottleneck(); } } } ...quickly fills the entire heap with FinalizableBottleneck and internal Finalizer objects and brings the JVM to a halt? After a few seconds of running the above program, jmap -histo:live reports: num #instances #bytes class name ---------------------------------------------- 1: 50048325 2001933000 java.lang.ref.Finalizer 2: 50048278 800772448 FinalizableBottleneck There are a couple of bottlenecks that make this happen: - ReferenceHandler thread synchronizes with VM to unhook Reference(s) from the pending chain one be one and dispatches them to their respected ReferenceQueue(s) which also use synchronization for equeueing each Reference. - Enqueueing synchronizes with the finalization thread which removes the Finalizer(s) (FinalReferences) from the finalization queue and executes them. - Executing the Finalizer(s) removes them from the doubly-linked list of all Finalizer(s) which is used to retain them until they are needed and this synchronizes with the threads that link new Finalizer(s) into the doubly-linked list as new finalizable objects get registered. We see that the creation of a finalizable object only takes one synchronization (registering into the doubly-linked list) and is performed synchronously, while finalization takes 4 synchronizations among 4 different threads (in pairs) and happens when the Finalizer instance "travels" over from VM thread to ReferenceHandler thread and then to finalization thread. No wonder that finalization can not keep up with allocation in a single thread. The situation is even worse when finalize() methods do some actual work. I have experimented with various approaches to widen these bottlenecks and found out that I can not beat the ForkJoinPool when combined with some improvements to internal data structures used in reference processing. Here's a prototype I came up with: http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/webrev.01/ And this is the benchmark I use for measuring the throughput: http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/FinalizerThroughput.java The benchmark shows (results inline in source) that using unpatched JDK, on my PC (i7-2700K, Linux, JDK8) I can not construct more than 1500 finalizable objects per ms in a single thread and that while doing so, finalization only manages to process approx. 100 - 120 objects at the same time. Objects "in-flight" quickly accumulate and bring the VM to a halt, where it is not doing anything but full GC cycles. When constructing in 4 threads, there's not much difference. Construction of finalizable objects simply doesn't scale. Patched JDK shows something completely different. Single thread construction achieves a rate of 3600 objects / ms. Number of "in-flight" objects is kept constant at about 5-6M instances which amounts to approx 1.5 s of allocation. I think this is about the rate of GC cycles during which VM also processes the references. The benchmark also shows the ForkJoinPool statistics which shows that the number of queued tasks is also kept low. Increasing the allocation threads to 4 increases allocation rate to about 4300 objects / ms and finalization keeps up. Increasing allocation threads to 8, further increases allocation rate to about 4600 objects / ms and finalization still keeps up. The increase in rate is not linear, but keep in mind that i7 is a 4-core CPU. About the implementation... 1st improvement I did was for the doubly-linked list of Finalizer instances that is used to keep them alive until they are needed. I ripped-off the wonderful ConcurrentLinkedDeque by Doug Lea and Martin Buchholz and just kept the internal link/unlink methods while specializing them to Finalizer entries (very straight-forward). I experimented with throughput and got some improvement, but throughput has increased much more when I used several instances of independent lists and distributed registrations among them randomly (unlinking consequently is also distributed randomly). I found out that no matter how hard I try to optimize ReferenceQueue while keeping the API unchanged, I can only do so much and that was not enough. I have been surprised by how well ForkJoinPool distributes tasks among threads, so I concluded that leveraging it is the best choice. I re-designed the pending-list unhooking loop to unhook pending references in chunks which greatly improves the throughput. Since unhooking can be performed by a single thread while holding a lock which is mandated by interface between VM and Java, I didn't employ multiple threads, but a single eternal ForkJoinTask that unhooks in chunks and forks-off other processing tasks that process chunks. When there are just a couple of References pending at one time and a not-full chunk is unhooked, then the processing is performed by the same thread that unhooked the refrences, but when there are more, worker tasks are forked off and the unhooking thread continues with full peace. This processing includes execution of Cleaners, forking the finalizer tasks and enqueue-ing other references. Finalizer(s) are always executed as separate ForkJoinTask(s). It's interesting how Runtime.runFinalizers() is implemented in this patch - it basically amounts to ForkJoinPool.awaitQuiescence() ... I also tweaked the ReferenceQueue implementation a bit (it is still used for other kinds of references) so that it avoids synchronization with a monitor lock when there are no blocking waiters and uses CAS to enqueue/dequeue. This improves throughput when the queue is not empty. Since in the prototype multiple threads can enqueue into the same queue, I thought this would improve throughput in such situations. Comments, suggestions, criticism are welcome. Regards, Peter From lance.andersen at oracle.com Thu May 28 17:31:40 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 28 May 2015 13:31:40 -0400 Subject: JDK 9 RFR of JDK-8081359: Update bug reporting URL In-Reply-To: <5566A9B9.8020802@oracle.com> References: <5566A9B9.8020802@oracle.com> Message-ID: looks OK Joe On May 28, 2015, at 1:38 AM, joe darcy wrote: > Hello, > > As the venerable URL > > http://bugreport.sun.com/bugreport/ > > has been retired and replaced with > > http://bugreport.java.com/bugreport/ > > Occurrences of the old URL in the source base should be updated. Please review the patch below which does this: > > --- a/src/java.base/share/native/libjava/System.c Thu May 28 09:11:14 2015 +0800 > +++ b/src/java.base/share/native/libjava/System.c Wed May 27 22:36:07 2015 -0700 > @@ -111,7 +111,7 @@ > #ifndef VENDOR /* Third party may overwrite this. */ > #define VENDOR "Oracle Corporation" > #define VENDOR_URL "http://java.oracle.com/" > -#define VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/" > +#define VENDOR_URL_BUG "http://bugreport.java.com/bugreport/" > #endif > > #define JAVA_MAX_SUPPORTED_VERSION 52 > diff -r de8fc052f1b6 src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties > --- a/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties Thu May 28 09:11:14 2015 +0800 > +++ b/src/jdk.rmic/share/classes/sun/tools/javac/resources/javac.properties Wed May 27 22:36:07 2015 -0700 > @@ -498,9 +498,9 @@ > javac.err.cant.write=\ > Can''t write: {0} > javac.err.fatal.error=\ > - An error has occurred in the compiler; please file a bug report (http://bugreport.sun.com/bugreport/). > + An error has occurred in the compiler; please file a bug report (http://bugreport.java.com/bugreport/). > javac.err.fatal.exception=\ > - An exception has occurred in the compiler; please file a bug report (http://bugreport.sun.com/bugreport/). > + An exception has occurred in the compiler; please file a bug report (http://bugreport.java.com/bugreport/). > javac.err.no.inner.classes=\ > Support for inner classes has been disabled. > javac.err.uncaught.exception=\ > > These were the only remaining occurrences of the old URL in the OpenJDK code base. The occurrence in langtools was previously updated (JDK-8078560). > > 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 mandy.chung at oracle.com Thu May 28 18:06:00 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Thu, 28 May 2015 11:06:00 -0700 Subject: RFR(M,v9): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <556727A2.9060209@gmail.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> <5564802A.2010403@oracle.com> <5565738A.4040109@gmail.com> <7EB0BE71-1608-4047-B71D-1A9EAA9083BB@oracle.com> <556727A2.9060209@gmail.com> Message-ID: <55675908.6030406@oracle.com> On 05/28/2015 07:35 AM, Peter Levart wrote: > Hi Mandy, > > On 05/27/2015 03:32 PM, Mandy Chung wrote: >> Taking it further - is it simpler to return String[] of all >> classnames including the duplicated ones and have the VM do the >> count? Are you concerned with the size of the String[]? > > Yes, the histogram is much smaller than the list of all instances. > There can be millions of instances waiting in finalizer queue, but > only a few distinct classes. Do you happen to know what libraries are the major contributors to these millions of finalizers? It has been strongly recommended to avoid finalizers (see Effective Java Item 7). I'm not surprised that existing code is still using finalizers while we should really encourage them to migrate away from it. > What could be done in Java to simplify things in native code but still > not format the output is to convert the array of Map.Entry(s) into an > Object[] array of alternating {String, int[], String, int[], .... } > > Would this simplify native code for the price of a little extra work > in Java? The sizes of old and new arrays are not big (# of distinct > classes of finalizable objects in the queue). I also prefer writing in Java and writing less native code (much simplified). It's an interface that we have to agree upon and keep it simple. Having the returned Object[] as alternate String and int[] is a reasonable compromise. ReferenceQueue.java - you can move @SuppressWarning from the method to just the field variable "rn" @SuppressWarnings("unchecked") Reference rn = r.next; Finalizer.java It's better to rename printFinalizationQueue as it inspects the finalizer reference queue (maybe getFinalizerHistogram?). Can you move this method to the end of this class and add the comment saying that this is invoked by VM for jcmd -finalizerinfo support and @return to describe the returned content. I also think you can remove @SuppressWarnings for this method. Mandy From vladimir.x.ivanov at oracle.com Thu May 28 18:22:03 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Thu, 28 May 2015 21:22:03 +0300 Subject: [8u-dev] Review request : JDK-8062904: TEST_BUG: Tests java/lang/invoke/LFCaching fail when run with -Xcomp option In-Reply-To: <5566D9D8.4090401@oracle.com> References: <5565D9BB.60003@oracle.com> <5565F6D5.7030900@oracle.com> <5566D9D8.4090401@oracle.com> Message-ID: <55675CCB.8010506@oracle.com> Got it, thanks. Can we ignore errors caused by code cache overflow for now? Best regards, Vladimir Ivanov On 5/28/15 12:03 PM, Konstantin Shefov wrote: > Vladimir, > > This fix is not for timeout issue, this fix is for > "java.lang.VirtualMachineError: out of space in CodeCache for adapters". > > Timeout issue is other bug and should be filed separately. > I do not know why SQE added RULES with timeout to this bug. > > By the way, if -Xcomp is set on JDK 8u, test works if not more than one > iteration is allowed. The same thing was for JDK 9 until JDK-8046809 had > been fixed. > > -Konstantin > > On 27.05.2015 19:54, Vladimir Ivanov wrote: >> Have you tried to reduce iteration granularity? >> >> Probably, checking execution duration on every test case is more robust. >> >> Best regards, >> Vladimir Ivanov >> >> On 5/27/15 5:50 PM, Konstantin Shefov wrote: >>> Hello, >>> >>> Please review the test bug fix >>> https://bugs.openjdk.java.net/browse/JDK-8062904 >>> Webrev is http://cr.openjdk.java.net/~kshefov/8062904/webrev.01/ >>> Test fails only against JDK 8u and passes against JDK 9. >>> >>> Thanks >>> >>> -Konstantin > From staffan.larsen at oracle.com Thu May 28 18:35:13 2015 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Thu, 28 May 2015 20:35:13 +0200 Subject: RFR(M, v9): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55675908.6030406@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> <5564802A.2010403@oracle.com> <5565738A.4040109@gmail.com> <7EB0BE71-1608-4047-B71D-1A9EAA9083BB@oracle.com> <556727A2.9060209@gmail.com> <55675908.6030406@oracle.com> Message-ID: <2FB398BE-12CE-49AC-91F6-BC1C5B2F7F7A@oracle.com> > On 28 maj 2015, at 20:06, Mandy Chung wrote: > > > On 05/28/2015 07:35 AM, Peter Levart wrote: >> Hi Mandy, >> >> On 05/27/2015 03:32 PM, Mandy Chung wrote: >>> Taking it further - is it simpler to return String[] of all classnames including the duplicated ones and have the VM do the count? Are you concerned with the size of the String[]? >> >> Yes, the histogram is much smaller than the list of all instances. There can be millions of instances waiting in finalizer queue, but only a few distinct classes. > > Do you happen to know what libraries are the major contributors to these millions of finalizers? > > It has been strongly recommended to avoid finalizers (see Effective Java Item 7). I'm not surprised that existing code is still using finalizers while we should really encourage them to migrate away from it. Having ways to introspect the finalizer queue is one way to make people aware that they have a problem :-) > >> What could be done in Java to simplify things in native code but still not format the output is to convert the array of Map.Entry(s) into an Object[] array of alternating {String, int[], String, int[], .... } >> >> Would this simplify native code for the price of a little extra work in Java? The sizes of old and new arrays are not big (# of distinct classes of finalizable objects in the queue). > > I also prefer writing in Java and writing less native code (much simplified). It's an interface that we have to agree upon and keep it simple. Having the returned Object[] as alternate String and int[] is a reasonable compromise. > > ReferenceQueue.java - you can move @SuppressWarning from the method to just the field variable "rn" > @SuppressWarnings("unchecked") > Reference rn = r.next; > > Finalizer.java > It's better to rename printFinalizationQueue as it inspects the finalizer reference queue (maybe getFinalizerHistogram?). Can you move this method to the end of this class and add the comment saying that this is invoked by VM for jcmd -finalizerinfo support and @return to describe the returned content. I also think you can remove @SuppressWarnings for this method. > > Mandy From Roger.Riggs at Oracle.com Thu May 28 20:14:12 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 28 May 2015 16:14:12 -0400 Subject: RFR 9: JDK-8075678 : java.time javadoc error in DateTimeFormatter::parsedLeapSecond Message-ID: <55677714.8090001@Oracle.com> Please review 3 editorial issues in the java.time package: Issues: 8075678 : java.time javadoc error in DateTimeFormatter::parsedLeapSecond 8075676 : java.time package javadoc typos 8068276 : java.time.chrono.HijrahChronology.eraOf() assertions may lead to misunderstanding Webrev: http://cr.openjdk.java.net/~rriggs/webrev-typo-8075678/ Thanks, Roger From lance.andersen at oracle.com Thu May 28 20:22:36 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 28 May 2015 16:22:36 -0400 Subject: RFR 9: JDK-8075678 : java.time javadoc error in DateTimeFormatter::parsedLeapSecond In-Reply-To: <55677714.8090001@Oracle.com> References: <55677714.8090001@Oracle.com> Message-ID: <0794CB22-BF1A-45C9-9345-6389BA3F6A70@oracle.com> Changes seem reasonable Roger Best Lance On May 28, 2015, at 4:14 PM, Roger Riggs wrote: > Please review 3 editorial issues in the java.time package: > > Issues: > 8075678 : java.time javadoc error in DateTimeFormatter::parsedLeapSecond > 8075676 : java.time package javadoc typos > 8068276 : java.time.chrono.HijrahChronology.eraOf() assertions may lead to misunderstanding > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-typo-8075678/ > > 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 scolebourne at joda.org Thu May 28 20:25:12 2015 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 28 May 2015 21:25:12 +0100 Subject: RFR 9: JDK-8075678 : java.time javadoc error in DateTimeFormatter::parsedLeapSecond In-Reply-To: <55677714.8090001@Oracle.com> References: <55677714.8090001@Oracle.com> Message-ID: Fine by me Stephen On 28 May 2015 at 21:14, Roger Riggs wrote: > Please review 3 editorial issues in the java.time package: > > Issues: > 8075678 : java.time > javadoc error in DateTimeFormatter::parsedLeapSecond > 8075676 : java.time > package javadoc typos > 8068276 : > java.time.chrono.HijrahChronology.eraOf() assertions may lead to > misunderstanding > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-typo-8075678/ > > Thanks, Roger > From ivan.gerasimov at oracle.com Thu May 28 22:43:07 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 29 May 2015 01:43:07 +0300 Subject: RFR 8081027: Create a common test to check adequacy of initial size of static HashMap/ArrayList fields In-Reply-To: References: <5563AB19.4060507@oracle.com> Message-ID: <556799FB.6000503@oracle.com> Thank you Martin for looking at this! On 27.05.2015 17:30, Martin Buchholz wrote: > Thanks. > > Your methods like ofArrayList declare that they > throw ReflectiveOperationException, but also have a try/catch to > prevent that from ever happening. > Fixed! > The assertions e.g. > OptimalCapacity.ofArrayList(XClass.class, "theList", N) > could look more like assertions, e.g. > OptimalCapacity.assertOptimallySized(Class clazz, String fieldName, > int initialCapacity) > Good naming is one of the most difficult part of coding IMO. The chosen names were meant to be read literally: "optimal capacity of ArrayList", etc. I agree, 'assert' would tell more about these methods' intention, but I'm not sure how to include it in the names. Maybe rename the class to AssertOptimalCapacity? > getStorage returns the actual internal array, but you only ever need > the length. Maybe I would have a single method > > static int internalArraySize(Object x) { ... } > Yes. I was going to compare the references, but finished comparing only sizes. Changed the method to internalArraySize(), as you suggested. > "enteties" is misspelled. > Fixed. > For ArrayLists, I would have been happy enough just testing that we > have 100% utilization, i.e. size of array is the same as size of the > List, without checking the initial capacity. > But then the test wouldn't have caught the "bug" in src/java.base/share/classes/sun/security/ssl/ExtensionType.java The ArrayList was pre-sized to 9, and after reallocation the capacity happened to become (9 + 9/2) = 13, which by coincidence is the final size of the List. Please have a look at the updated webrev: http://cr.openjdk.java.net/~igerasim/8081027/01/webrev/ Sincerely yours, Ivan > On Mon, May 25, 2015 at 4:07 PM, Ivan Gerasimov > > wrote: > > Hello! > > This is in some way continuation of JDK-8080535 (Expected size of > Character.UnicodeBlock.map is not optimal). > > A new utility class OptimalCapacity was added to jdk.testlibrary > package. > The test NonOptimalMapSize.java that had been added with > JDK-8080535, was rewritten with use of this new class. > A couple more tests were added, which utilize methods of > OptimalCapacity for checking sizes of ArrayList and > IdentityHashMap static variables. > > Optimization of initial sizes of two more variables saves us one > reallocation during java start-time and a few more bytes of memory. > > Would you please help review this fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8081027 > WEBREV: http://cr.openjdk.java.net/~igerasim/8081027/00/webrev/ > > > Sincerely yours, > Ivan > > From martinrb at google.com Fri May 29 00:03:49 2015 From: martinrb at google.com (Martin Buchholz) Date: Thu, 28 May 2015 17:03:49 -0700 Subject: RFR 8081027: Create a common test to check adequacy of initial size of static HashMap/ArrayList fields In-Reply-To: <556799FB.6000503@oracle.com> References: <5563AB19.4060507@oracle.com> <556799FB.6000503@oracle.com> Message-ID: Approved. On Thu, May 28, 2015 at 3:43 PM, Ivan Gerasimov wrote: Good naming is one of the most difficult part of coding IMO. > The chosen names were meant to be read literally: "optimal capacity of > ArrayList", etc. > I agree, 'assert' would tell more about these methods' intention, but I'm > not sure how to include it in the names. > Maybe rename the class to AssertOptimalCapacity? > > Assertions are a class of names we are used to importing statically. Junit and Testng both have collections of static methods named assertXXX. > For ArrayLists, I would have been happy enough just testing that we have > 100% utilization, i.e. size of array is the same as size of the List, > without checking the initial capacity. > > But then the test wouldn't have caught the "bug" in > src/java.base/share/classes/sun/security/ssl/ExtensionType.java > The ArrayList was pre-sized to 9, and after reallocation the capacity > happened to become (9 + 9/2) = 13, which by coincidence is the final size > of the List. > It's a tradeoff of maintenance burden vs performance. Note also that oversize is a much bigger performance bug than undersize because you pay for it for the entire process, not just startup. From david.holmes at oracle.com Fri May 29 02:10:38 2015 From: david.holmes at oracle.com (David Holmes) Date: Fri, 29 May 2015 12:10:38 +1000 Subject: Why isn't Object.notify() a synchronized method? In-Reply-To: <55673D97.4010505@CoSoCo.de> References: <55673D97.4010505@CoSoCo.de> Message-ID: <5567CA9E.9090103@oracle.com> On 29/05/2015 2:08 AM, Ulf Zibis wrote: > Hi all, > > in the Javadoc of notify(), notifyAll() and wait(...) I read, that this > methods should only be used with synchronisation on it's instance. > So I'm wondering, why they don't have the synchronized modifier out of > the box in Object class. Because, as others have said, the way you use a monitor is to acquire the monitor lock, then inspect/modify mutable object state, then do a wait/notify/notifyAll as appropriate, and finally release the monitor. Making the methods themselves synchronized would be useless from a synchronization correctness perspective and would prevent coding errors from resulting in IllegalMonitorStateException. > Also I think, the following note should be moved from wait(long,int) to > wait(long): > /The current thread must own this object's monitor. The thread releases > ownership of this monitor and waits until either of the following two > conditions has occurred:// > / > > * /Another thread notifies threads waiting on this object's monitor to > wake up either through a > call to the notify method or the notifyAll method./ > * /The timeout period, specified by timeout milliseconds plus nanos > nanoseconds arguments, has > elapsed. / Why would you move it when wait(long) already has the more detailed: *

    * The current thread must own this object's monitor. *

    * This method causes the current thread (call it T) to * place itself in the wait set for this object and then to relinquish * any and all synchronization claims on this object. Thread T * becomes disabled for thread scheduling purposes and lies dormant * until one of four things happens: ... David ----- > > > Cheers, > > Ulf > From david.holmes at oracle.com Fri May 29 02:18:06 2015 From: david.holmes at oracle.com (David Holmes) Date: Fri, 29 May 2015 12:18:06 +1000 Subject: JEP 132: More-prompt finalization In-Reply-To: <55674C6E.8050509@gmail.com> References: <55674C6E.8050509@gmail.com> Message-ID: <5567CC5E.7000102@oracle.com> Hi Peter, I guess I'm very concerned about the premise that finalization should scale to millions of objects and be performed highly concurrently. To me that's sending the wrong message about finalization. It also isn't the most effective use of cpu resources - most people would want to do useful work on most cpu's most of the time. Cheers, David On 29/05/2015 3:12 AM, Peter Levart wrote: > Hi, > > Did you know that the following simple loop: > > public class FinalizableBottleneck { > static boolean no; > > @Override > protected void finalize() throws Throwable { > // empty finalize() method does not make the object finalizable > // (it is not even registered on the finalizer's list) > if (no) { > throw new AssertionError(); > } > } > > public static void main(String[] args) { > while (true) { > new FinalizableBottleneck(); > } > } > } > > > ...quickly fills the entire heap with FinalizableBottleneck and internal > Finalizer objects and brings the JVM to a halt? After a few seconds of > running the above program, jmap -histo:live reports: > > num #instances #bytes class name > ---------------------------------------------- > 1: 50048325 2001933000 java.lang.ref.Finalizer > 2: 50048278 800772448 FinalizableBottleneck > > > There are a couple of bottlenecks that make this happen: > > - ReferenceHandler thread synchronizes with VM to unhook Reference(s) > from the pending chain one be one and dispatches them to their respected > ReferenceQueue(s) which also use synchronization for equeueing each > Reference. > - Enqueueing synchronizes with the finalization thread which removes the > Finalizer(s) (FinalReferences) from the finalization queue and executes > them. > - Executing the Finalizer(s) removes them from the doubly-linked list of > all Finalizer(s) which is used to retain them until they are needed and > this synchronizes with the threads that link new Finalizer(s) into the > doubly-linked list as new finalizable objects get registered. > > We see that the creation of a finalizable object only takes one > synchronization (registering into the doubly-linked list) and is > performed synchronously, while finalization takes 4 synchronizations > among 4 different threads (in pairs) and happens when the Finalizer > instance "travels" over from VM thread to ReferenceHandler thread and > then to finalization thread. No wonder that finalization can not keep up > with allocation in a single thread. The situation is even worse when > finalize() methods do some actual work. > > I have experimented with various approaches to widen these bottlenecks > and found out that I can not beat the ForkJoinPool when combined with > some improvements to internal data structures used in reference > processing. Here's a prototype I came up with: > > http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/webrev.01/ > > > And this is the benchmark I use for measuring the throughput: > > http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/FinalizerThroughput.java > > > The benchmark shows (results inline in source) that using unpatched JDK, > on my PC (i7-2700K, Linux, JDK8) I can not construct more than 1500 > finalizable objects per ms in a single thread and that while doing so, > finalization only manages to process approx. 100 - 120 objects at the > same time. Objects "in-flight" quickly accumulate and bring the VM to a > halt, where it is not doing anything but full GC cycles. > > When constructing in 4 threads, there's not much difference. > Construction of finalizable objects simply doesn't scale. > > Patched JDK shows something completely different. Single thread > construction achieves a rate of 3600 objects / ms. Number of "in-flight" > objects is kept constant at about 5-6M instances which amounts to approx > 1.5 s of allocation. I think this is about the rate of GC cycles during > which VM also processes the references. The benchmark also shows the > ForkJoinPool statistics which shows that the number of queued tasks is > also kept low. > > Increasing the allocation threads to 4 increases allocation rate to > about 4300 objects / ms and finalization keeps up. Increasing allocation > threads to 8, further increases allocation rate to about 4600 objects / > ms and finalization still keeps up. The increase in rate is not linear, > but keep in mind that i7 is a 4-core CPU. > > About the implementation... > > 1st improvement I did was for the doubly-linked list of Finalizer > instances that is used to keep them alive until they are needed. I > ripped-off the wonderful ConcurrentLinkedDeque by Doug Lea and Martin > Buchholz and just kept the internal link/unlink methods while > specializing them to Finalizer entries (very straight-forward). I > experimented with throughput and got some improvement, but throughput > has increased much more when I used several instances of independent > lists and distributed registrations among them randomly (unlinking > consequently is also distributed randomly). > > I found out that no matter how hard I try to optimize ReferenceQueue > while keeping the API unchanged, I can only do so much and that was not > enough. I have been surprised by how well ForkJoinPool distributes tasks > among threads, so I concluded that leveraging it is the best choice. I > re-designed the pending-list unhooking loop to unhook pending references > in chunks which greatly improves the throughput. Since unhooking can be > performed by a single thread while holding a lock which is mandated by > interface between VM and Java, I didn't employ multiple threads, but a > single eternal ForkJoinTask that unhooks in chunks and forks-off other > processing tasks that process chunks. When there are just a couple of > References pending at one time and a not-full chunk is unhooked, then > the processing is performed by the same thread that unhooked the > refrences, but when there are more, worker tasks are forked off and the > unhooking thread continues with full peace. This processing includes > execution of Cleaners, forking the finalizer tasks and enqueue-ing other > references. Finalizer(s) are always executed as separate ForkJoinTask(s). > > It's interesting how Runtime.runFinalizers() is implemented in this > patch - it basically amounts to ForkJoinPool.awaitQuiescence() ... > > I also tweaked the ReferenceQueue implementation a bit (it is still used > for other kinds of references) so that it avoids synchronization with a > monitor lock when there are no blocking waiters and uses CAS to > enqueue/dequeue. This improves throughput when the queue is not empty. > Since in the prototype multiple threads can enqueue into the same queue, > I thought this would improve throughput in such situations. > > Comments, suggestions, criticism are welcome. > > Regards, Peter > From xueming.shen at oracle.com Fri May 29 06:58:20 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 28 May 2015 23:58:20 -0700 Subject: RFR JDK-8081452: Move sun.nio.cs.AbstractCharsetProvider into jdk.charset/sun.nio.cs.ext Message-ID: <55680E0C.1000105@oracle.com> Please help review change to move the AbstractCharsetProvider from java.base/sun.nio.cs to jdk.charsets/sun.nio.cs.ext. This is needed for the modules. issue: https://bugs.openjdk.java.net/browse/JDK-8081452 webrev: http://cr.openjdk.java.net/~sherman/8081452 Thanks, -Sherman From Alan.Bateman at oracle.com Fri May 29 07:04:48 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 29 May 2015 08:04:48 +0100 Subject: RFR JDK-8081452: Move sun.nio.cs.AbstractCharsetProvider into jdk.charset/sun.nio.cs.ext In-Reply-To: <55680E0C.1000105@oracle.com> References: <55680E0C.1000105@oracle.com> Message-ID: <55680F90.6070205@oracle.com> On 29/05/2015 07:58, Xueming Shen wrote: > Please help review change to move the AbstractCharsetProvider from > java.base/sun.nio.cs to > jdk.charsets/sun.nio.cs.ext. This is needed for the modules. > > issue: https://bugs.openjdk.java.net/browse/JDK-8081452 > webrev: http://cr.openjdk.java.net/~sherman/8081452 This looks okay to me. I just wonder if it should we renamed too as it isn't abstract. -Alan From xueming.shen at oracle.com Fri May 29 07:20:52 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 29 May 2015 00:20:52 -0700 Subject: RFR JDK-8081452: Move sun.nio.cs.AbstractCharsetProvider into jdk.charset/sun.nio.cs.ext In-Reply-To: <55680F90.6070205@oracle.com> References: <55680E0C.1000105@oracle.com> <55680F90.6070205@oracle.com> Message-ID: <55681354.305@oracle.com> It was originally written to be the base class for both std and ext charsets providers... maybe it should just be merged into the ExtendedCharsets class later separately. -sherman On 5/29/2015 12:04 AM, Alan Bateman wrote: > > > On 29/05/2015 07:58, Xueming Shen wrote: >> Please help review change to move the AbstractCharsetProvider from >> java.base/sun.nio.cs to >> jdk.charsets/sun.nio.cs.ext. This is needed for the modules. >> >> issue: https://bugs.openjdk.java.net/browse/JDK-8081452 >> webrev: http://cr.openjdk.java.net/~sherman/8081452 > This looks okay to me. I just wonder if it should we renamed too as it > isn't abstract. > > -Alan From konstantin.shefov at oracle.com Fri May 29 08:49:31 2015 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Fri, 29 May 2015 11:49:31 +0300 Subject: [8u-dev] Review request : JDK-8062904: TEST_BUG: Tests java/lang/invoke/LFCaching fail when run with -Xcomp option In-Reply-To: <55675CCB.8010506@oracle.com> References: <5565D9BB.60003@oracle.com> <5565F6D5.7030900@oracle.com> <5566D9D8.4090401@oracle.com> <55675CCB.8010506@oracle.com> Message-ID: <5568281B.7040108@oracle.com> Vladimir, What do you mean by ignore code cache overflow? Do you mean I should fix the test to ignore these errors or should I leave this test unfixed because it is a product related issue? -Konstantin On 28.05.2015 21:22, Vladimir Ivanov wrote: > Got it, thanks. > > Can we ignore errors caused by code cache overflow for now? > > Best regards, > Vladimir Ivanov > > On 5/28/15 12:03 PM, Konstantin Shefov wrote: >> Vladimir, >> >> This fix is not for timeout issue, this fix is for >> "java.lang.VirtualMachineError: out of space in CodeCache for adapters". >> >> Timeout issue is other bug and should be filed separately. >> I do not know why SQE added RULES with timeout to this bug. >> >> By the way, if -Xcomp is set on JDK 8u, test works if not more than one >> iteration is allowed. The same thing was for JDK 9 until JDK-8046809 had >> been fixed. >> >> -Konstantin >> >> On 27.05.2015 19:54, Vladimir Ivanov wrote: >>> Have you tried to reduce iteration granularity? >>> >>> Probably, checking execution duration on every test case is more >>> robust. >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> On 5/27/15 5:50 PM, Konstantin Shefov wrote: >>>> Hello, >>>> >>>> Please review the test bug fix >>>> https://bugs.openjdk.java.net/browse/JDK-8062904 >>>> Webrev is http://cr.openjdk.java.net/~kshefov/8062904/webrev.01/ >>>> Test fails only against JDK 8u and passes against JDK 9. >>>> >>>> Thanks >>>> >>>> -Konstantin >> From maxim.soloviev at oracle.com Fri May 29 11:34:59 2015 From: maxim.soloviev at oracle.com (Maxim Soloviev) Date: Fri, 29 May 2015 14:34:59 +0300 Subject: [8u-dev] Review request : JDK-8081479: Backport JDBC tests from JDK 9 from test/java/sql and test/javax/sql to JDK 8u. Message-ID: <55684EE3.3040304@oracle.com> Hello, Please review the test bug fix https://bugs.openjdk.java.net/browse/JDK-8081479 Webrev is http://cr.openjdk.java.net/~kshefov/8081479/webrev.00/ It's a backport of JDK9 JDBC tests to JDK8u. Thanks Maxim From vladimir.x.ivanov at oracle.com Fri May 29 11:49:56 2015 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 29 May 2015 14:49:56 +0300 Subject: [8u-dev] Review request : JDK-8062904: TEST_BUG: Tests java/lang/invoke/LFCaching fail when run with -Xcomp option In-Reply-To: <5568281B.7040108@oracle.com> References: <5565D9BB.60003@oracle.com> <5565F6D5.7030900@oracle.com> <5566D9D8.4090401@oracle.com> <55675CCB.8010506@oracle.com> <5568281B.7040108@oracle.com> Message-ID: <55685264.20001@oracle.com> > What do you mean by ignore code cache overflow? Do you mean I should fix > the test to ignore these errors or should I leave this test unfixed > because it is a product related issue? The former. How reliable the test is if it ignores NoSuchMethodException & VirtualMachineError? Are there other manifestations of the problem? Best regards, Vladimir Ivanov > On 28.05.2015 21:22, Vladimir Ivanov wrote: >> Got it, thanks. >> >> Can we ignore errors caused by code cache overflow for now? >> >> Best regards, >> Vladimir Ivanov >> >> On 5/28/15 12:03 PM, Konstantin Shefov wrote: >>> Vladimir, >>> >>> This fix is not for timeout issue, this fix is for >>> "java.lang.VirtualMachineError: out of space in CodeCache for adapters". >>> >>> Timeout issue is other bug and should be filed separately. >>> I do not know why SQE added RULES with timeout to this bug. >>> >>> By the way, if -Xcomp is set on JDK 8u, test works if not more than one >>> iteration is allowed. The same thing was for JDK 9 until JDK-8046809 had >>> been fixed. >>> >>> -Konstantin >>> >>> On 27.05.2015 19:54, Vladimir Ivanov wrote: >>>> Have you tried to reduce iteration granularity? >>>> >>>> Probably, checking execution duration on every test case is more >>>> robust. >>>> >>>> Best regards, >>>> Vladimir Ivanov >>>> >>>> On 5/27/15 5:50 PM, Konstantin Shefov wrote: >>>>> Hello, >>>>> >>>>> Please review the test bug fix >>>>> https://bugs.openjdk.java.net/browse/JDK-8062904 >>>>> Webrev is http://cr.openjdk.java.net/~kshefov/8062904/webrev.01/ >>>>> Test fails only against JDK 8u and passes against JDK 9. >>>>> >>>>> Thanks >>>>> >>>>> -Konstantin >>> > From Alan.Bateman at oracle.com Fri May 29 13:02:15 2015 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 29 May 2015 14:02:15 +0100 Subject: RFR [9] 8080502: Changing accessing module resources In-Reply-To: <5564660D.3030703@oracle.com> References: <555B04AE.8040009@oracle.com> <555DD0CF.8060407@oracle.com> <5564660D.3030703@oracle.com> Message-ID: <55686357.1010300@oracle.com> On 26/05/2015 13:24, Miroslav Kos wrote: > Thanks, you are correct. Changed to try-catch with resources, the some > code moved to SchemaCache. Refernced resources found by > com.sun.tools.internal.xjc.SchemaCache.ResourceResolver added to > collection and closed after parsing. > > updated webrev: http://cr.openjdk.java.net/~mkos/8080502/jaxws.02/ > tests: rerun standalone tests for bot standalone build and for JDK. This looks much better, it seems to close all the streams now. There's a TODO-Miran left in MetroConfigLoader that I assume should be looked at before you push. In ParserContext then you could throw InternalError(e) rather than e.getMessage(), assuming of course this doesn't need to compile on JDK 7 or older. -Alan From lance.andersen at oracle.com Fri May 29 13:54:27 2015 From: lance.andersen at oracle.com (Lance Andersen) Date: Fri, 29 May 2015 09:54:27 -0400 Subject: [8u-dev] Review request : JDK-8081479: Backport JDBC tests from JDK 9 from test/java/sql and test/javax/sql to JDK 8u. In-Reply-To: <55684EE3.3040304@oracle.com> References: <55684EE3.3040304@oracle.com> Message-ID: Hi Maxim, this looks fine Best Lance On May 29, 2015, at 7:34 AM, Maxim Soloviev wrote: > Hello, > > Please review the test bug fix > https://bugs.openjdk.java.net/browse/JDK-8081479 > Webrev is http://cr.openjdk.java.net/~kshefov/8081479/webrev.00/ > It's a backport of JDK9 JDBC tests to JDK8u. > > Thanks > Maxim 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 kirk.pepperdine at gmail.com Fri May 29 03:57:34 2015 From: kirk.pepperdine at gmail.com (Kirk Pepperdine) Date: Fri, 29 May 2015 06:57:34 +0300 Subject: JEP 132: More-prompt finalization In-Reply-To: <5567CC5E.7000102@oracle.com> References: <55674C6E.8050509@gmail.com> <5567CC5E.7000102@oracle.com> Message-ID: <8DBC7345-09D8-458F-9017-298D1E620F86@gmail.com> Hi Peter, It is a very interesting proposal but to further David?s comments, the life-cycle costs of reference objects is horrendous of which the actual process of finalizing an object is only a fraction of that total cost. Unfortunately your micro-benchmark only focuses on one aspect of that cost. In other words, it isn?t very representative of a real concern. In the real world the finalizer *must compete with mutator threads and since F-J is an ?all threads on deck? implementation, it doesn?t play well with others. It creates a ?tragedy of the commons?. That is situations where everyone behaves rationally with a common resource but to the detriment of the whole group?. In short, parallelizing (F-Jing) *everything* in an application is simply not a good idea. We do not live in an infinite compute environment which means to have to consider the impact of our actions to the entire group. This was one of the points of my recent article in Java Magazine which I wrote to try to counter some of the rhetoric I was hearing in conference about the universal benefits of being able easily parallelize streams in Java 8. Yes, I agree it?s a great feature but it must be used with discretion. Case in point. After I finished writing the article, I started running into a couple of early adopters that had swallowed the parallel message whole indiscriminately parallelizing all of their streams. As you can imagine, they were quite surprised by the results and quickly worked to de-parallelize *all* of the streams in the application. To add some ability to parallelize the handling of reference objects seems like a good idea if you are collecting large numbers of reference objects (>10,000 per GC cycle). However if you are collecting large numbers of reference objects you?re most likely doing something else wrong. IME, finalization is extremely useful but really only for a limited number of use cases and none of them (to date) have resulted in the app burning through 1000s of final objects / sec. It would be interesting to know why why you picked on this particular issue. Kind regards, Kirk On May 29, 2015, at 5:18 AM, David Holmes wrote: > Hi Peter, > > I guess I'm very concerned about the premise that finalization should scale to millions of objects and be performed highly concurrently. To me that's sending the wrong message about finalization. It also isn't the most effective use of cpu resources - most people would want to do useful work on most cpu's most of the time. > > Cheers, > David > > On 29/05/2015 3:12 AM, Peter Levart wrote: >> Hi, >> >> Did you know that the following simple loop: >> >> public class FinalizableBottleneck { >> static boolean no; >> >> @Override >> protected void finalize() throws Throwable { >> // empty finalize() method does not make the object finalizable >> // (it is not even registered on the finalizer's list) >> if (no) { >> throw new AssertionError(); >> } >> } >> >> public static void main(String[] args) { >> while (true) { >> new FinalizableBottleneck(); >> } >> } >> } >> >> >> ...quickly fills the entire heap with FinalizableBottleneck and internal >> Finalizer objects and brings the JVM to a halt? After a few seconds of >> running the above program, jmap -histo:live reports: >> >> num #instances #bytes class name >> ---------------------------------------------- >> 1: 50048325 2001933000 java.lang.ref.Finalizer >> 2: 50048278 800772448 FinalizableBottleneck >> >> >> There are a couple of bottlenecks that make this happen: >> >> - ReferenceHandler thread synchronizes with VM to unhook Reference(s) >> from the pending chain one be one and dispatches them to their respected >> ReferenceQueue(s) which also use synchronization for equeueing each >> Reference. >> - Enqueueing synchronizes with the finalization thread which removes the >> Finalizer(s) (FinalReferences) from the finalization queue and executes >> them. >> - Executing the Finalizer(s) removes them from the doubly-linked list of >> all Finalizer(s) which is used to retain them until they are needed and >> this synchronizes with the threads that link new Finalizer(s) into the >> doubly-linked list as new finalizable objects get registered. >> >> We see that the creation of a finalizable object only takes one >> synchronization (registering into the doubly-linked list) and is >> performed synchronously, while finalization takes 4 synchronizations >> among 4 different threads (in pairs) and happens when the Finalizer >> instance "travels" over from VM thread to ReferenceHandler thread and >> then to finalization thread. No wonder that finalization can not keep up >> with allocation in a single thread. The situation is even worse when >> finalize() methods do some actual work. >> >> I have experimented with various approaches to widen these bottlenecks >> and found out that I can not beat the ForkJoinPool when combined with >> some improvements to internal data structures used in reference >> processing. Here's a prototype I came up with: >> >> http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/webrev.01/ >> >> >> And this is the benchmark I use for measuring the throughput: >> >> http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/FinalizerThroughput.java >> >> >> The benchmark shows (results inline in source) that using unpatched JDK, >> on my PC (i7-2700K, Linux, JDK8) I can not construct more than 1500 >> finalizable objects per ms in a single thread and that while doing so, >> finalization only manages to process approx. 100 - 120 objects at the >> same time. Objects "in-flight" quickly accumulate and bring the VM to a >> halt, where it is not doing anything but full GC cycles. >> >> When constructing in 4 threads, there's not much difference. >> Construction of finalizable objects simply doesn't scale. >> >> Patched JDK shows something completely different. Single thread >> construction achieves a rate of 3600 objects / ms. Number of "in-flight" >> objects is kept constant at about 5-6M instances which amounts to approx >> 1.5 s of allocation. I think this is about the rate of GC cycles during >> which VM also processes the references. The benchmark also shows the >> ForkJoinPool statistics which shows that the number of queued tasks is >> also kept low. >> >> Increasing the allocation threads to 4 increases allocation rate to >> about 4300 objects / ms and finalization keeps up. Increasing allocation >> threads to 8, further increases allocation rate to about 4600 objects / >> ms and finalization still keeps up. The increase in rate is not linear, >> but keep in mind that i7 is a 4-core CPU. >> >> About the implementation... >> >> 1st improvement I did was for the doubly-linked list of Finalizer >> instances that is used to keep them alive until they are needed. I >> ripped-off the wonderful ConcurrentLinkedDeque by Doug Lea and Martin >> Buchholz and just kept the internal link/unlink methods while >> specializing them to Finalizer entries (very straight-forward). I >> experimented with throughput and got some improvement, but throughput >> has increased much more when I used several instances of independent >> lists and distributed registrations among them randomly (unlinking >> consequently is also distributed randomly). >> >> I found out that no matter how hard I try to optimize ReferenceQueue >> while keeping the API unchanged, I can only do so much and that was not >> enough. I have been surprised by how well ForkJoinPool distributes tasks >> among threads, so I concluded that leveraging it is the best choice. I >> re-designed the pending-list unhooking loop to unhook pending references >> in chunks which greatly improves the throughput. Since unhooking can be >> performed by a single thread while holding a lock which is mandated by >> interface between VM and Java, I didn't employ multiple threads, but a >> single eternal ForkJoinTask that unhooks in chunks and forks-off other >> processing tasks that process chunks. When there are just a couple of >> References pending at one time and a not-full chunk is unhooked, then >> the processing is performed by the same thread that unhooked the >> refrences, but when there are more, worker tasks are forked off and the >> unhooking thread continues with full peace. This processing includes >> execution of Cleaners, forking the finalizer tasks and enqueue-ing other >> references. Finalizer(s) are always executed as separate ForkJoinTask(s). >> >> It's interesting how Runtime.runFinalizers() is implemented in this >> patch - it basically amounts to ForkJoinPool.awaitQuiescence() ... >> >> I also tweaked the ReferenceQueue implementation a bit (it is still used >> for other kinds of references) so that it avoids synchronization with a >> monitor lock when there are no blocking waiters and uses CAS to >> enqueue/dequeue. This improves throughput when the queue is not empty. >> Since in the prototype multiple threads can enqueue into the same queue, >> I thought this would improve throughput in such situations. >> >> Comments, suggestions, criticism are welcome. >> >> Regards, Peter >> From mandy.chung at oracle.com Fri May 29 16:28:26 2015 From: mandy.chung at oracle.com (Mandy Chung) Date: Fri, 29 May 2015 09:28:26 -0700 Subject: RFR JDK-8081452: Move sun.nio.cs.AbstractCharsetProvider into jdk.charset/sun.nio.cs.ext In-Reply-To: <55681354.305@oracle.com> References: <55680E0C.1000105@oracle.com> <55680F90.6070205@oracle.com> <55681354.305@oracle.com> Message-ID: <556893AA.80600@oracle.com> On 05/29/2015 12:20 AM, Xueming Shen wrote: > It was originally written to be the base class for both std and ext > charsets providers... maybe it should > just be merged into the ExtendedCharsets class later separately. > Perhaps better to merge it now rather than separately? Mandy > -sherman > > On 5/29/2015 12:04 AM, Alan Bateman wrote: >> >> >> On 29/05/2015 07:58, Xueming Shen wrote: >>> Please help review change to move the AbstractCharsetProvider from >>> java.base/sun.nio.cs to >>> jdk.charsets/sun.nio.cs.ext. This is needed for the modules. >>> >>> issue: https://bugs.openjdk.java.net/browse/JDK-8081452 >>> webrev: http://cr.openjdk.java.net/~sherman/8081452 >> This looks okay to me. I just wonder if it should we renamed too as >> it isn't abstract. >> >> -Alan > From ivan.gerasimov at oracle.com Fri May 29 16:42:48 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 29 May 2015 19:42:48 +0300 Subject: RFR 8081027: Create a common test to check adequacy of initial size of static HashMap/ArrayList fields In-Reply-To: References: <5563AB19.4060507@oracle.com> <556799FB.6000503@oracle.com> Message-ID: <55689708.2000807@oracle.com> Thank you Martin for review! On 29.05.2015 3:03, Martin Buchholz wrote: > Approved. > > On Thu, May 28, 2015 at 3:43 PM, Ivan Gerasimov > > wrote: > > Good naming is one of the most difficult part of coding IMO. > The chosen names were meant to be read literally: "optimal > capacity of ArrayList", etc. > I agree, 'assert' would tell more about these methods' intention, > but I'm not sure how to include it in the names. > Maybe rename the class to AssertOptimalCapacity? > > > Assertions are a class of names we are used to importing statically. > Junit and Testng both have collections of static methods named assertXXX. > >> For ArrayLists, I would have been happy enough just testing that >> we have 100% utilization, i.e. size of array is the same as size >> of the List, without checking the initial capacity. >> > But then the test wouldn't have caught the "bug" in > src/java.base/share/classes/sun/security/ssl/ExtensionType.java > The ArrayList was pre-sized to 9, and after reallocation the > capacity happened to become (9 + 9/2) = 13, which by coincidence > is the final size of the List. > > > It's a tradeoff of maintenance burden vs performance. Note also that > oversize is a much bigger performance bug than undersize because you > pay for it for the entire process, not just startup. From Ulf.Zibis at CoSoCo.de Fri May 29 16:48:28 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Fri, 29 May 2015 18:48:28 +0200 Subject: Why isn't Object.notify() a synchronized method? In-Reply-To: <5567420A.9020406@redhat.com> References: <55673D97.4010505@CoSoCo.de> <5567420A.9020406@redhat.com> Message-ID: <5568985C.6050507@CoSoCo.de> Thanks for your hint David. That's the only reason I could imagine too. Can somebody tell something about the cost for recursive lock acquisition in comparison to the whole call, couldn't it be eliminated by Hotspot? As I recently fell into the trap of forgetting the synchronized block around a single notifyAll(), I believe, the current situation is just errorprone. Any comments about the Javadoc issue? -Ulf Am 28.05.2015 um 18:27 schrieb David M. Lloyd: > Since most of the time you have to hold the lock anyway for other reasons, I think this would > generally be an unwelcome change since I expect the cost of recursive lock acquisition is nonzero. > > On 05/28/2015 11:08 AM, Ulf Zibis wrote: >> Hi all, >> >> in the Javadoc of notify(), notifyAll() and wait(...) I read, that this >> methods should only be used with synchronisation on it's instance. >> So I'm wondering, why they don't have the synchronized modifier out of >> the box in Object class. >> >> Also I think, the following note should be moved from wait(long,int) to >> wait(long): >> /The current thread must own this object's monitor. The thread releases >> ownership of this monitor and waits until either of the following two >> conditions has occurred:// >> / >> >> * /Another thread notifies threads waiting on this object's monitor to >> wake up either through a >> call to the notify method or the notifyAll method./ >> * /The timeout period, specified by timeout milliseconds plus nanos >> nanoseconds arguments, has >> elapsed. / >> >> >> >> Cheers, >> >> Ulf >> > From Mohammad.Rezaei at gs.com Fri May 29 17:20:49 2015 From: Mohammad.Rezaei at gs.com (Rezaei, Mohammad A.) Date: Fri, 29 May 2015 13:20:49 -0400 Subject: JEP 132: More-prompt finalization In-Reply-To: <8DBC7345-09D8-458F-9017-298D1E620F86@gmail.com> References: <55674C6E.8050509@gmail.com> <5567CC5E.7000102@oracle.com> <8DBC7345-09D8-458F-9017-298D1E620F86@gmail.com> Message-ID: <6882C9A35DFB9B4FA2779F7BF5B9757D20761169A2@GSCMAMP06EX.firmwide.corp.gs.com> For what it's worth, I fully agree with David and Kirk around finalization not necessarily needing this treatment. However, I was hoping this would have the effect of improving (non-finalizable) reference handling. We've seen serious issues in WeakReference handling and have had to write some twisted code to deal with this. So I guess the question I have to Kirk and David is: do you feel a GC load of 10K WeakReferences per cycle is also "doing something else wrong"? Sorry if this is going off-topic. Thanks Moh >-----Original Message----- >From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] On Behalf >Of Kirk Pepperdine >Sent: Thursday, May 28, 2015 11:58 PM >To: david.holmes at oracle.com Holmes >Cc: hotspot-gc-dev at openjdk.java.net openjdk.java.net; core-libs- >dev at openjdk.java.net >Subject: Re: JEP 132: More-prompt finalization > >Hi Peter, > >It is a very interesting proposal but to further David's comments, the life- >cycle costs of reference objects is horrendous of which the actual process of >finalizing an object is only a fraction of that total cost. Unfortunately your >micro-benchmark only focuses on one aspect of that cost. In other words, it >isn't very representative of a real concern. In the real world the finalizer >*must compete with mutator threads and since F-J is an "all threads on deck" >implementation, it doesn't play well with others. It creates a "tragedy of the >commons". That is situations where everyone behaves rationally with a common >resource but to the detriment of the whole group". In short, parallelizing (F- >Jing) *everything* in an application is simply not a good idea. We do not live >in an infinite compute environment which means to have to consider the impact >of our actions to the entire group. > >This was one of the points of my recent article in Java Magazine which I wrote >to try to counter some of the rhetoric I was hearing in conference about the >universal benefits of being able easily parallelize streams in Java 8. Yes, I >agree it's a great feature but it must be used with discretion. Case in point. >After I finished writing the article, I started running into a couple of early >adopters that had swallowed the parallel message whole indiscriminately >parallelizing all of their streams. As you can imagine, they were quite >surprised by the results and quickly worked to de-parallelize *all* of the >streams in the application. > >To add some ability to parallelize the handling of reference objects seems >like a good idea if you are collecting large numbers of reference objects >(>10,000 per GC cycle). However if you are collecting large numbers of >reference objects you're most likely doing something else wrong. IME, >finalization is extremely useful but really only for a limited number of use >cases and none of them (to date) have resulted in the app burning through >1000s of final objects / sec. > >It would be interesting to know why why you picked on this particular issue. > >Kind regards, >Kirk > > > >On May 29, 2015, at 5:18 AM, David Holmes wrote: > >> Hi Peter, >> >> I guess I'm very concerned about the premise that finalization should scale >to millions of objects and be performed highly concurrently. To me that's >sending the wrong message about finalization. It also isn't the most effective >use of cpu resources - most people would want to do useful work on most cpu's >most of the time. >> >> Cheers, >> David >> >> On 29/05/2015 3:12 AM, Peter Levart wrote: >>> Hi, >>> >>> Did you know that the following simple loop: >>> >>> public class FinalizableBottleneck { >>> static boolean no; >>> >>> @Override >>> protected void finalize() throws Throwable { >>> // empty finalize() method does not make the object finalizable >>> // (it is not even registered on the finalizer's list) >>> if (no) { >>> throw new AssertionError(); >>> } >>> } >>> >>> public static void main(String[] args) { >>> while (true) { >>> new FinalizableBottleneck(); >>> } >>> } >>> } >>> >>> >>> ...quickly fills the entire heap with FinalizableBottleneck and internal >>> Finalizer objects and brings the JVM to a halt? After a few seconds of >>> running the above program, jmap -histo:live reports: >>> >>> num #instances #bytes class name >>> ---------------------------------------------- >>> 1: 50048325 2001933000 java.lang.ref.Finalizer >>> 2: 50048278 800772448 FinalizableBottleneck >>> >>> >>> There are a couple of bottlenecks that make this happen: >>> >>> - ReferenceHandler thread synchronizes with VM to unhook Reference(s) >>> from the pending chain one be one and dispatches them to their respected >>> ReferenceQueue(s) which also use synchronization for equeueing each >>> Reference. >>> - Enqueueing synchronizes with the finalization thread which removes the >>> Finalizer(s) (FinalReferences) from the finalization queue and executes >>> them. >>> - Executing the Finalizer(s) removes them from the doubly-linked list of >>> all Finalizer(s) which is used to retain them until they are needed and >>> this synchronizes with the threads that link new Finalizer(s) into the >>> doubly-linked list as new finalizable objects get registered. >>> >>> We see that the creation of a finalizable object only takes one >>> synchronization (registering into the doubly-linked list) and is >>> performed synchronously, while finalization takes 4 synchronizations >>> among 4 different threads (in pairs) and happens when the Finalizer >>> instance "travels" over from VM thread to ReferenceHandler thread and >>> then to finalization thread. No wonder that finalization can not keep up >>> with allocation in a single thread. The situation is even worse when >>> finalize() methods do some actual work. >>> >>> I have experimented with various approaches to widen these bottlenecks >>> and found out that I can not beat the ForkJoinPool when combined with >>> some improvements to internal data structures used in reference >>> processing. Here's a prototype I came up with: >>> >>> >http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/webrev.01/ >>> >>> >>> And this is the benchmark I use for measuring the throughput: >>> >>> >http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/FinalizerThr >oughput.java >>> >>> >>> The benchmark shows (results inline in source) that using unpatched JDK, >>> on my PC (i7-2700K, Linux, JDK8) I can not construct more than 1500 >>> finalizable objects per ms in a single thread and that while doing so, >>> finalization only manages to process approx. 100 - 120 objects at the >>> same time. Objects "in-flight" quickly accumulate and bring the VM to a >>> halt, where it is not doing anything but full GC cycles. >>> >>> When constructing in 4 threads, there's not much difference. >>> Construction of finalizable objects simply doesn't scale. >>> >>> Patched JDK shows something completely different. Single thread >>> construction achieves a rate of 3600 objects / ms. Number of "in-flight" >>> objects is kept constant at about 5-6M instances which amounts to approx >>> 1.5 s of allocation. I think this is about the rate of GC cycles during >>> which VM also processes the references. The benchmark also shows the >>> ForkJoinPool statistics which shows that the number of queued tasks is >>> also kept low. >>> >>> Increasing the allocation threads to 4 increases allocation rate to >>> about 4300 objects / ms and finalization keeps up. Increasing allocation >>> threads to 8, further increases allocation rate to about 4600 objects / >>> ms and finalization still keeps up. The increase in rate is not linear, >>> but keep in mind that i7 is a 4-core CPU. >>> >>> About the implementation... >>> >>> 1st improvement I did was for the doubly-linked list of Finalizer >>> instances that is used to keep them alive until they are needed. I >>> ripped-off the wonderful ConcurrentLinkedDeque by Doug Lea and Martin >>> Buchholz and just kept the internal link/unlink methods while >>> specializing them to Finalizer entries (very straight-forward). I >>> experimented with throughput and got some improvement, but throughput >>> has increased much more when I used several instances of independent >>> lists and distributed registrations among them randomly (unlinking >>> consequently is also distributed randomly). >>> >>> I found out that no matter how hard I try to optimize ReferenceQueue >>> while keeping the API unchanged, I can only do so much and that was not >>> enough. I have been surprised by how well ForkJoinPool distributes tasks >>> among threads, so I concluded that leveraging it is the best choice. I >>> re-designed the pending-list unhooking loop to unhook pending references >>> in chunks which greatly improves the throughput. Since unhooking can be >>> performed by a single thread while holding a lock which is mandated by >>> interface between VM and Java, I didn't employ multiple threads, but a >>> single eternal ForkJoinTask that unhooks in chunks and forks-off other >>> processing tasks that process chunks. When there are just a couple of >>> References pending at one time and a not-full chunk is unhooked, then >>> the processing is performed by the same thread that unhooked the >>> refrences, but when there are more, worker tasks are forked off and the >>> unhooking thread continues with full peace. This processing includes >>> execution of Cleaners, forking the finalizer tasks and enqueue-ing other >>> references. Finalizer(s) are always executed as separate ForkJoinTask(s). >>> >>> It's interesting how Runtime.runFinalizers() is implemented in this >>> patch - it basically amounts to ForkJoinPool.awaitQuiescence() ... >>> >>> I also tweaked the ReferenceQueue implementation a bit (it is still used >>> for other kinds of references) so that it avoids synchronization with a >>> monitor lock when there are no blocking waiters and uses CAS to >>> enqueue/dequeue. This improves throughput when the queue is not empty. >>> Since in the prototype multiple threads can enqueue into the same queue, >>> I thought this would improve throughput in such situations. >>> >>> Comments, suggestions, criticism are welcome. >>> >>> Regards, Peter >>> From xueming.shen at oracle.com Fri May 29 17:42:52 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 29 May 2015 10:42:52 -0700 Subject: RFR JDK-8081452: Move sun.nio.cs.AbstractCharsetProvider into jdk.charset/sun.nio.cs.ext In-Reply-To: <556893AA.80600@oracle.com> References: <55680E0C.1000105@oracle.com> <55680F90.6070205@oracle.com> <55681354.305@oracle.com> <556893AA.80600@oracle.com> Message-ID: <5568A51C.4090905@oracle.com> On 05/29/2015 09:28 AM, Mandy Chung wrote: > On 05/29/2015 12:20 AM, Xueming Shen wrote: >> It was originally written to be the base class for both std and ext charsets providers... maybe it should >> just be merged into the ExtendedCharsets class later separately. >> > > Perhaps better to merge it now rather than separately? > But if it is decided later that we may want to have a separate ext charsets provider2, for example to split most of the ibm charsets to a separate provider, it might be desired to keep it as a base class ... From Roger.Riggs at Oracle.com Fri May 29 19:13:31 2015 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 29 May 2015 15:13:31 -0400 Subject: RFR: 8081536 : (process) remove unreliable ScaleTest from process tests Message-ID: <5568BA5B.70103@Oracle.com> Please review the removal of the java/lang/ProcessHandle/ScaleTest for ProcessHandles. It is not appropriate for regression testing and does not run reliably. It was inadvertently included in the commit. Webrev: http://bussund0416.us.oracle.com/~rriggs/webrev/webrev-scaletest-remove-8081536/ Issue: 8081536 : (process) remove unreliable ScaleTest from process tests Thanks, Roger From joe.darcy at oracle.com Fri May 29 19:15:25 2015 From: joe.darcy at oracle.com (joe darcy) Date: Fri, 29 May 2015 12:15:25 -0700 Subject: RFR: 8081536 : (process) remove unreliable ScaleTest from process tests In-Reply-To: <5568BA5B.70103@Oracle.com> References: <5568BA5B.70103@Oracle.com> Message-ID: <5568BACD.6000006@oracle.com> Approved; cheers, -Joe On 5/29/2015 12:13 PM, Roger Riggs wrote: > Please review the removal of the java/lang/ProcessHandle/ScaleTest for > ProcessHandles. > It is not appropriate for regression testing and does not run reliably. > It was inadvertently included in the commit. > > Webrev: > http://bussund0416.us.oracle.com/~rriggs/webrev/webrev-scaletest-remove-8081536/ > > Issue: > 8081536 : (process) > remove unreliable ScaleTest from process tests > > Thanks, Roger > From Ulf.Zibis at CoSoCo.de Fri May 29 23:02:04 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Sat, 30 May 2015 01:02:04 +0200 Subject: RFR JDK-8081452: Move sun.nio.cs.AbstractCharsetProvider into jdk.charset/sun.nio.cs.ext In-Reply-To: <5568A51C.4090905@oracle.com> References: <55680E0C.1000105@oracle.com> <55680F90.6070205@oracle.com> <55681354.305@oracle.com> <556893AA.80600@oracle.com> <5568A51C.4090905@oracle.com> Message-ID: <5568EFEC.6050106@CoSoCo.de> Am 29.05.2015 um 19:42 schrieb Xueming Shen: > But if it is decided later that we may want to have a separate ext charsets provider2, for example > to split most of the ibm charsets to a separate provider, it might be desired to keep it as a base > class ... Hm, is it mandatory, that each charset provider must have it's own class? I also think, that we do not need a separate class for each charset. -Ulf From xueming.shen at oracle.com Sat May 30 01:26:39 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 29 May 2015 18:26:39 -0700 Subject: RFR JDK-8081452: Move sun.nio.cs.AbstractCharsetProvider into jdk.charset/sun.nio.cs.ext In-Reply-To: <5568EFEC.6050106@CoSoCo.de> References: <55680E0C.1000105@oracle.com> <55680F90.6070205@oracle.com> <55681354.305@oracle.com> <556893AA.80600@oracle.com> <5568A51C.4090905@oracle.com> <5568EFEC.6050106@CoSoCo.de> Message-ID: <556911CF.7080407@oracle.com> On 5/29/15 4:02 PM, Ulf Zibis wrote: > > Am 29.05.2015 um 19:42 schrieb Xueming Shen: >> But if it is decided later that we may want to have a separate ext >> charsets provider2, for example to split most of the ibm charsets to >> a separate provider, it might be desired to keep it as a base class ... > Hm, is it mandatory, that each charset provider must have it's own class? > I also think, that we do not need a separate class for each charset. No, it's not a "must" to have a separate class for each charset, but it's a logical way to organize those charset with their data. Given how most of these charsets are src-generated in current jdk, it's fair easy to actually generate a "charset" object from a base classes (SingleByte, or DoubleByte) + a set of "data" ( such as the name, aliases table, mapping data, etc) during runtime, without having a real concrete charset class. But then you need to figure out a better way to organize, store and read/initialize those "data" in a optimized way to initialize each charset on the fly, which we are now utilizing the jvm's class initialization mechanism to achieve this. Any benefit/advantage of doing this? We might throw in some resource someday to gather some data ... -Sherman From Ulf.Zibis at CoSoCo.de Sat May 30 17:37:57 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Sat, 30 May 2015 19:37:57 +0200 Subject: RFR JDK-8081452: Move sun.nio.cs.AbstractCharsetProvider into jdk.charset/sun.nio.cs.ext In-Reply-To: <556911CF.7080407@oracle.com> References: <55680E0C.1000105@oracle.com> <55680F90.6070205@oracle.com> <55681354.305@oracle.com> <556893AA.80600@oracle.com> <5568A51C.4090905@oracle.com> <5568EFEC.6050106@CoSoCo.de> <556911CF.7080407@oracle.com> Message-ID: <5569F575.1090009@CoSoCo.de> Am 30.05.2015 um 03:26 schrieb Xueming Shen: > On 5/29/15 4:02 PM, Ulf Zibis wrote: >> >> Am 29.05.2015 um 19:42 schrieb Xueming Shen: >>> But if it is decided later that we may want to have a separate ext charsets provider2, for >>> example to split most of the ibm charsets to a separate provider, it might be desired to keep it >>> as a base class ... >> Hm, is it mandatory, that each charset provider must have it's own class? >> I also think, that we do not need a separate class for each charset. > No, it's not a "must" to have a separate class for each charset, but it's a logical way to > organize those > charset with their data. Given how most of these charsets are src-generated in current jdk, it's > fair easy > to actually generate a "charset" object from a base classes (SingleByte, or DoubleByte) + a set of > "data" > ( such as the name, aliases table, mapping data, etc) during runtime, without having a real concrete > charset class. But then you need to figure out a better way to organize, store and > read/initialize those > "data" in a optimized way to initialize each charset on the fly, which we are now utilizing the jvm's > class initialization mechanism to achieve this. Any benefit/advantage of doing this? We might throw > in some resource someday to gather some data ... Hi sherman, I did some work here: https://bugs.openjdk.java.net/show_bug.cgi?id=100090 https://bugs.openjdk.java.net/show_bug.cgi?id=100091 https://bugs.openjdk.java.net/show_bug.cgi?id=100092 https://bugs.openjdk.java.net/show_bug.cgi?id=100095 https://bugs.openjdk.java.net/show_bug.cgi?id=100098 https://bugs.openjdk.java.net/show_bug.cgi?id=1000104 https://bugs.openjdk.java.net/show_bug.cgi?id=1000105 https://bugs.openjdk.java.net/show_bug.cgi?id=1000107 https://bugs.openjdk.java.net/show_bug.cgi?id=1000132 Unfortunately the data was moved somewhere. Do you know, where the data was moved? One of the original bug reports: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6862158 Also I did some work here: https://java.net/projects/java-nio-charset-enhanced -Ulf From ivan.gerasimov at oracle.com Sun May 31 02:19:31 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sun, 31 May 2015 05:19:31 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556625E5.5040806@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> Message-ID: <556A6FB3.3060705@oracle.com> Hi everyone! Here's another webrev, in which replace() is implemented with StringBuilder. On my benchmark it is almost as fast as the version backed with arrays, but this variant is much shorter. Credits to Sherman for combining the general algorithm with the case of empty target. Comments, further suggestions are welcome! BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/04/webrev/ Sincerely yours, Ivan From david.holmes at oracle.com Sun May 31 04:31:25 2015 From: david.holmes at oracle.com (David Holmes) Date: Sun, 31 May 2015 14:31:25 +1000 Subject: Why isn't Object.notify() a synchronized method? In-Reply-To: <5568985C.6050507@CoSoCo.de> References: <55673D97.4010505@CoSoCo.de> <5567420A.9020406@redhat.com> <5568985C.6050507@CoSoCo.de> Message-ID: <556A8E9D.4040407@oracle.com> On 30/05/2015 2:48 AM, Ulf Zibis wrote: > Thanks for your hint David. That's the only reason I could imagine too. > Can somebody tell something about the cost for recursive lock > acquisition in comparison to the whole call, couldn't it be eliminated > by Hotspot? There are a number of fast paths related to recursive locking. Not sure if inlining allows lock elision that something for the compiler folk. > As I recently fell into the trap of forgetting the synchronized block > around a single notifyAll(), I believe, the current situation is just > errorprone. How is it errorprone? You forgot to acquire the lock and you got an IllegalMonitorStateException when you did notifyAll. That's pointing out your error. > Any comments about the Javadoc issue? I did comment - I don't see any issue. David H. > -Ulf > > > Am 28.05.2015 um 18:27 schrieb David M. Lloyd: >> Since most of the time you have to hold the lock anyway for other >> reasons, I think this would generally be an unwelcome change since I >> expect the cost of recursive lock acquisition is nonzero. >> >> On 05/28/2015 11:08 AM, Ulf Zibis wrote: >>> Hi all, >>> >>> in the Javadoc of notify(), notifyAll() and wait(...) I read, that this >>> methods should only be used with synchronisation on it's instance. >>> So I'm wondering, why they don't have the synchronized modifier out of >>> the box in Object class. >>> >>> Also I think, the following note should be moved from wait(long,int) to >>> wait(long): >>> /The current thread must own this object's monitor. The thread releases >>> ownership of this monitor and waits until either of the following two >>> conditions has occurred:// >>> / >>> >>> * /Another thread notifies threads waiting on this object's monitor to >>> wake up either through a >>> call to the notify method or the notifyAll method./ >>> * /The timeout period, specified by timeout milliseconds plus nanos >>> nanoseconds arguments, has >>> elapsed. / >>> >>> >>> >>> Cheers, >>> >>> Ulf >>> >> > From xueming.shen at oracle.com Sun May 31 04:34:10 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Sat, 30 May 2015 21:34:10 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556A6FB3.3060705@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> Message-ID: <556A8F42.8070704@oracle.com> On 5/30/15 7:19 PM, Ivan Gerasimov wrote: > Hi everyone! > > Here's another webrev, in which replace() is implemented with > StringBuilder. > On my benchmark it is almost as fast as the version backed with > arrays, but this variant is much shorter. > > Credits to Sherman for combining the general algorithm with the case > of empty target. > > Comments, further suggestions are welcome! > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 > WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/04/webrev/ > > Sincerely yours, > Ivan > This is one is much better:-) I would suggest to leave the "overflow-conscious" code to the StringBuilder. The same range check is being done inside ABS every time the repl string is appended into the buffer, it does not appear to be very helpful to have a redundant check here. And it seems this check only works for the single appearance of target string. 2260 // overflow-conscious code 2261 if (value.length - targLen > Integer.MAX_VALUE - replValue.length) { 2262 throw new OutOfMemoryError(); 2263 } From peter.levart at gmail.com Sun May 31 06:38:31 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 31 May 2015 08:38:31 +0200 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556A8F42.8070704@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> <556A8F42.8070704@oracle.com> Message-ID: <556AAC67.5050100@gmail.com> On 05/31/2015 06:34 AM, Xueming Shen wrote: > On 5/30/15 7:19 PM, Ivan Gerasimov wrote: >> Hi everyone! >> >> Here's another webrev, in which replace() is implemented with >> StringBuilder. >> On my benchmark it is almost as fast as the version backed with >> arrays, but this variant is much shorter. >> >> Credits to Sherman for combining the general algorithm with the case >> of empty target. >> >> Comments, further suggestions are welcome! >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/04/webrev/ >> >> Sincerely yours, >> Ivan >> > > This is one is much better:-) I would suggest to leave the > "overflow-conscious" code to the StringBuilder. > The same range check is being done inside ABS every time the repl > string is appended into the buffer, > it does not appear to be very helpful to have a redundant check here. > And it seems this check only works > for the single appearance of target string. > > 2260 // overflow-conscious code > 2261 if (value.length - targLen > Integer.MAX_VALUE - > replValue.length) { > 2262 throw new OutOfMemoryError(); > 2263 } > Hi, Yes, this one is much easier to grasp. As I understand the check is to avoid overflow in calculation of StringBuilder initial capacity (newLenHint). If overflow happened, newLenHint would be negative and StringBuilder construction would fail with NegativeArraySizeException. But the calculation of newLenHint: int newLenHint = value.length - targLen + replValue.length; ...considering the following: value.length >= 0 targLength >= 0 replValue.length >= 0 targLength <= value.length in case of overflow, it can only produce a negative value. So the check could simply be: if (newLenHint < 0) { throw new OutOfMemoryError(); } Right? Regards, Peter From xueming.shen at oracle.com Sun May 31 07:01:37 2015 From: xueming.shen at oracle.com (Xueming Shen) Date: Sun, 31 May 2015 00:01:37 -0700 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556AAC67.5050100@gmail.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> <556A8F42.8070704@oracle.com> <556AAC67.5050100@gmail.com> Message-ID: <556AB1D1.30508@oracle.com> On 5/30/2015 11:38 PM, Peter Levart wrote: > > > Hi, > > Yes, this one is much easier to grasp. > > As I understand the check is to avoid overflow in calculation of > StringBuilder initial capacity (newLenHint). If overflow happened, > newLenHint would be negative and StringBuilder construction would fail > with NegativeArraySizeException. But the calculation of newLenHint: > > int newLenHint = value.length - targLen + replValue.length; > > ...considering the following: > > value.length >= 0 > targLength >= 0 > replValue.length >= 0 > targLength <= value.length > > in case of overflow, it can only produce a negative value. So the > check could simply be: > > if (newLenHint < 0) { > throw new OutOfMemoryError(); > } > > Right? > > Regards, Peter > agreed. From forax at univ-mlv.fr Sun May 31 08:43:52 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sun, 31 May 2015 10:43:52 +0200 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556A6FB3.3060705@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> Message-ID: <556AC9C8.3070503@univ-mlv.fr> I agree with the others the code is more readable. There is a slightly difference between the current behavior and the behavior of the proposed code, "foo".replace("bar", null) should throw a NPE because replacement is null but the proposed code will return "foo" because replacement.toString() is called after the short-circuit test (j < 0). so the first part of the code should be: String starget = target.toString(); // implict nullcheck String srepl = replacement.toString(); // implicit nullcheck int j = indexOf(starget); if (j < 0) { return this; } ... also 'i' can be initialized just before the 'do', there is no point to initialize it before. To finish, the two 'final' are useless here but i suppose it's a matter of style :) cheers, R?mi On 05/31/2015 04:19 AM, Ivan Gerasimov wrote: > Hi everyone! > > Here's another webrev, in which replace() is implemented with > StringBuilder. > On my benchmark it is almost as fast as the version backed with > arrays, but this variant is much shorter. > > Credits to Sherman for combining the general algorithm with the case > of empty target. > > Comments, further suggestions are welcome! > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 > WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/04/webrev/ > > Sincerely yours, > Ivan > From Ulf.Zibis at CoSoCo.de Sun May 31 10:28:25 2015 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Sun, 31 May 2015 12:28:25 +0200 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556AAC67.5050100@gmail.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> <556A8F42.8070704@oracle.com> <556AAC67.5050100@gmail.com> Message-ID: <556AE249.4000203@CoSoCo.de> Am 31.05.2015 um 08:38 schrieb Peter Levart: > Hi, > > Yes, this one is much easier to grasp. > > As I understand the check is to avoid overflow in calculation of StringBuilder initial capacity > (newLenHint). If overflow happened, newLenHint would be negative and StringBuilder construction > would fail with NegativeArraySizeException. But the calculation of newLenHint: > > int newLenHint = value.length - targLen + replValue.length; > > ...considering the following: > > value.length >= 0 > targLength >= 0 > replValue.length >= 0 > targLength <= value.length > > in case of overflow, it can only produce a negative value. So the check could simply be: > > if (newLenHint < 0) { > throw new OutOfMemoryError(); > } Hm, what has this situation to do with Out-Of-Memory ? In other words, IMHO NegativeArraySizeException is much better here and additionally saves performance. Additionally you could propagate it to InvalidArgumentException. -Ulf From dmitry.samersoff at oracle.com Sun May 31 11:43:09 2015 From: dmitry.samersoff at oracle.com (Dmitry Samersoff) Date: Sun, 31 May 2015 14:43:09 +0300 Subject: RFR(M, v10): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo In-Reply-To: <55675908.6030406@oracle.com> References: <554894E9.8020908@oracle.com> <1AF219C7-1055-4D97-BB46-2FA390C4135D@oracle.com> <5548D65C.8040304@gmail.com> <554A8CEE.2090009@oracle.com> <55523418.5010708@oracle.com> <55527935.5010408@gmail.com> <5553B552.9060900@oracle.com> <555453BA.2070205@gmail.com> <55567748.6020304@oracle.com> <55567A68.9020802@oracle.com> <5556F34B.5050701@oracle.com> <55573A31.7050306@gmail.com> <55573C86.8030807@gmail.com> <5559D85B.2050500@oracle.com> <6FB8DF19-1D67-4702-9642-4C630765D2D1@oracle.com> <555C2EEB.1050505@oracle.com> <3941B430-FE6C-4AF0-A875-76D24411C654@oracle.com> <5564802A.2010403@oracle.com> <5565738A.4040109@gmail.com> <7EB0BE71-1608-4047-B71D-1A9EAA9083BB@oracle.com> <556727A2.9060209@gmail.com> <55675908.6030406@oracle.com> Message-ID: <556AF3CD.50900@oracle.com> Everyone, Please take a look at new version of the fix. http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.10/ Changes (to previous version) are in Finalizer.java and diagnosticCommand.cpp This version copy data from Map.Entry<> to array of FinalizerHistogramEntry instances then, VM prints content of this array. -Dmitry On 2015-05-28 21:06, Mandy Chung wrote: > > On 05/28/2015 07:35 AM, Peter Levart wrote: >> Hi Mandy, >> >> On 05/27/2015 03:32 PM, Mandy Chung wrote: >>> Taking it further - is it simpler to return String[] of all >>> classnames including the duplicated ones and have the VM do the >>> count? Are you concerned with the size of the String[]? >> >> Yes, the histogram is much smaller than the list of all instances. >> There can be millions of instances waiting in finalizer queue, but >> only a few distinct classes. > > Do you happen to know what libraries are the major contributors to these > millions of finalizers? > > It has been strongly recommended to avoid finalizers (see Effective Java > Item 7). I'm not surprised that existing code is still using > finalizers while we should really encourage them to migrate away from it. > >> What could be done in Java to simplify things in native code but still >> not format the output is to convert the array of Map.Entry(s) into an >> Object[] array of alternating {String, int[], String, int[], .... } >> >> Would this simplify native code for the price of a little extra work >> in Java? The sizes of old and new arrays are not big (# of distinct >> classes of finalizable objects in the queue). > > I also prefer writing in Java and writing less native code (much > simplified). It's an interface that we have to agree upon and keep it > simple. Having the returned Object[] as alternate String and int[] is a > reasonable compromise. > > ReferenceQueue.java - you can move @SuppressWarning from the method to > just the field variable "rn" > @SuppressWarnings("unchecked") > Reference rn = r.next; > > Finalizer.java > It's better to rename printFinalizationQueue as it inspects the > finalizer reference queue (maybe getFinalizerHistogram?). Can you move > this method to the end of this class and add the comment saying that > this is invoked by VM for jcmd -finalizerinfo support and @return to > describe the returned content. I also think you can remove > @SuppressWarnings for this method. > > Mandy -- Dmitry Samersoff Oracle Java development team, Saint Petersburg, Russia * I would love to change the world, but they won't give me the sources. From ivan.gerasimov at oracle.com Sun May 31 15:14:23 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sun, 31 May 2015 18:14:23 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556AB1D1.30508@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> <556A8F42.8070704@oracle.com> <556AAC67.5050100@gmail.com> <556AB1D1.30508@oracle.com> Message-ID: <556B254F.9060402@oracle.com> Thanks! I'll simplify this check for overflow, as you're suggesting. Sincerely yours, Ivan On 31.05.2015 10:01, Xueming Shen wrote: > > On 5/30/2015 11:38 PM, Peter Levart wrote: >> >> >> Hi, >> >> Yes, this one is much easier to grasp. >> >> As I understand the check is to avoid overflow in calculation of >> StringBuilder initial capacity (newLenHint). If overflow happened, >> newLenHint would be negative and StringBuilder construction would >> fail with NegativeArraySizeException. But the calculation of newLenHint: >> >> int newLenHint = value.length - targLen + replValue.length; >> >> ...considering the following: >> >> value.length >= 0 >> targLength >= 0 >> replValue.length >= 0 >> targLength <= value.length >> >> in case of overflow, it can only produce a negative value. So the >> check could simply be: >> >> if (newLenHint < 0) { >> throw new OutOfMemoryError(); >> } >> >> Right? >> >> Regards, Peter >> > > agreed. > From ivan.gerasimov at oracle.com Sun May 31 15:21:23 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sun, 31 May 2015 18:21:23 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556AE249.4000203@CoSoCo.de> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> <556A8F42.8070704@oracle.com> <556AAC67.5050100@gmail.com> <556AE249.4000203@CoSoCo.de> Message-ID: <556B26F3.3030704@oracle.com> On 31.05.2015 13:28, Ulf Zibis wrote: > > Am 31.05.2015 um 08:38 schrieb Peter Levart: >> Hi, >> >> Yes, this one is much easier to grasp. >> >> As I understand the check is to avoid overflow in calculation of >> StringBuilder initial capacity (newLenHint). If overflow happened, >> newLenHint would be negative and StringBuilder construction would >> fail with NegativeArraySizeException. But the calculation of newLenHint: >> >> int newLenHint = value.length - targLen + replValue.length; >> >> ...considering the following: >> >> value.length >= 0 >> targLength >= 0 >> replValue.length >= 0 >> targLength <= value.length >> >> in case of overflow, it can only produce a negative value. So the >> check could simply be: >> >> if (newLenHint < 0) { >> throw new OutOfMemoryError(); >> } > > Hm, what has this situation to do with Out-Of-Memory ? > That should indicate that we were about to try to allocate an array of size > Integer.MAX_VALUE. E.g. java.util.AbstractCollection.java: private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError ("Required array size too large"); > In other words, IMHO NegativeArraySizeException is much better here > and additionally saves performance. > Additionally you could propagate it to InvalidArgumentException. > I don't think it is InvalidArgument case. It just happens that the result is larger then allowed, so let's throw OOM! Sincerely yours, Ivan > -Ulf > > > From ivan.gerasimov at oracle.com Sun May 31 15:54:35 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sun, 31 May 2015 18:54:35 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556AC9C8.3070503@univ-mlv.fr> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> <556AC9C8.3070503@univ-mlv.fr> Message-ID: <556B2EBB.2080503@oracle.com> Hi Remi! On 31.05.2015 11:43, Remi Forax wrote: > I agree with the others the code is more readable. > > There is a slightly difference between the current behavior and the > behavior of the proposed code, > "foo".replace("bar", null) > should throw a NPE because replacement is null but the proposed code > will return "foo" > because replacement.toString() is called after the short-circuit test > (j < 0). > Yes, you're right, thanks for catching it! And the regression test should have caught that, but I only had "a".replace("a", null) there, which passed. I fixed the code and added the case to the regression test in the new webrev. > so the first part of the code should be: > String starget = target.toString(); // implict nullcheck > String srepl = replacement.toString(); // implicit nullcheck > int j = indexOf(starget); > if (j < 0) { > return this; > } > ... > > also 'i' can be initialized just before the 'do', there is no point to > initialize it before. > > To finish, the two 'final' are useless here but i suppose it's a > matter of style :) > I moved declaration of i just to save a line. I don't think it decreased performance. Declaring the 'value' variable final was suggested by Martin, and I think it is reasonable (see http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-March/032601.html). The other variable is final just for symmetry :) Sincerely yours, Ivan > cheers, > R?mi > > > On 05/31/2015 04:19 AM, Ivan Gerasimov wrote: >> Hi everyone! >> >> Here's another webrev, in which replace() is implemented with >> StringBuilder. >> On my benchmark it is almost as fast as the version backed with >> arrays, but this variant is much shorter. >> >> Credits to Sherman for combining the general algorithm with the case >> of empty target. >> >> Comments, further suggestions are welcome! >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/04/webrev/ >> >> Sincerely yours, >> Ivan >> > > > From ivan.gerasimov at oracle.com Sun May 31 16:03:54 2015 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sun, 31 May 2015 19:03:54 +0300 Subject: 8058779: Faster implementation of String.replace(CharSequence, CharSequence) In-Reply-To: <556B2EBB.2080503@oracle.com> References: <556231BE.9050703@oracle.com> <5564FD92.2050408@oracle.com> <556503D8.6000303@oracle.com> <5565E2D6.2070806@oracle.com> <5565E667.4050601@oracle.com> <5565F988.7080209@oracle.com> <55660180.8030003@oracle.com> <556605E9.3010302@oracle.com> <55660805.1030007@oracle.com> <55661E7B.2010405@oracle.com> <556624BA.1030703@oracle.com> <556625E5.5040806@oracle.com> <556A6FB3.3060705@oracle.com> <556AC9C8.3070503@univ-mlv.fr> <556B2EBB.2080503@oracle.com> Message-ID: <556B30EA.5050801@oracle.com> On 31.05.2015 18:54, Ivan Gerasimov wrote: > Hi Remi! > > On 31.05.2015 11:43, Remi Forax wrote: >> I agree with the others the code is more readable. >> >> There is a slightly difference between the current behavior and the >> behavior of the proposed code, >> "foo".replace("bar", null) >> should throw a NPE because replacement is null but the proposed code >> will return "foo" >> because replacement.toString() is called after the short-circuit test >> (j < 0). >> > Yes, you're right, thanks for catching it! > And the regression test should have caught that, but I only had > "a".replace("a", null) there, which passed. > > I fixed the code and added the case to the regression test in the new > webrev. > Which is right here: http://cr.openjdk.java.net/~igerasim/8058779/05/webrev/ >> so the first part of the code should be: >> String starget = target.toString(); // implict nullcheck >> String srepl = replacement.toString(); // implicit nullcheck >> int j = indexOf(starget); >> if (j < 0) { >> return this; >> } >> ... >> >> also 'i' can be initialized just before the 'do', there is no point >> to initialize it before. >> >> To finish, the two 'final' are useless here but i suppose it's a >> matter of style :) >> > I moved declaration of i just to save a line. I don't think it > decreased performance. > > Declaring the 'value' variable final was suggested by Martin, and I > think it is reasonable (see > http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-March/032601.html). > The other variable is final just for symmetry :) > > Sincerely yours, > Ivan > > >> cheers, >> R?mi >> >> >> On 05/31/2015 04:19 AM, Ivan Gerasimov wrote: >>> Hi everyone! >>> >>> Here's another webrev, in which replace() is implemented with >>> StringBuilder. >>> On my benchmark it is almost as fast as the version backed with >>> arrays, but this variant is much shorter. >>> >>> Credits to Sherman for combining the general algorithm with the case >>> of empty target. >>> >>> Comments, further suggestions are welcome! >>> >>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8058779 >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8058779/04/webrev/ >>> >>> Sincerely yours, >>> Ivan >>> >> >> >> > > > From peter.levart at gmail.com Sun May 31 19:32:00 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 31 May 2015 21:32:00 +0200 Subject: JEP 132: More-prompt finalization In-Reply-To: <6882C9A35DFB9B4FA2779F7BF5B9757D20761169A2@GSCMAMP06EX.firmwide.corp.gs.com> References: <55674C6E.8050509@gmail.com> <5567CC5E.7000102@oracle.com> <8DBC7345-09D8-458F-9017-298D1E620F86@gmail.com> <6882C9A35DFB9B4FA2779F7BF5B9757D20761169A2@GSCMAMP06EX.firmwide.corp.gs.com> Message-ID: <556B61B0.5030708@gmail.com> Hi, Thanks for views and opinions. I'll try to confront them in-line... On 05/29/2015 04:18 AM, David Holmes wrote: > Hi Peter, > > I guess I'm very concerned about the premise that finalization should > scale to millions of objects and be performed highly concurrently. To > me that's sending the wrong message about finalization. It also isn't > the most effective use of cpu resources - most people would want to do > useful work on most cpu's most of the time. > > Cheers, > David @David Ok, fair enough. It shouldn't be necessary to scale finalization to millions of objects and be performed concurrently. Normal programs don't need this. But there is a diagnostic command being developed at this moment that displays the finalization queue. The utility of such command, as I understand, is precisely to display when the finalization thread can not cope and Finalizer(s) accumulate. So there must be that some hypothetical programs (ab)use finalization or are buggy (deadlock) so that the queue builds up. To diagnose this, a diagnostic command is helpful. To fix it, one has to fix the code. But what if the problem is not that much about the allocation/death rate of finalizable instances then it is about the heavy code of finalize() methods of those instances. I agree that such programs have a smell and should be rewritten to not use finalization but other means of cleanup such as multiple threads removing WeakReferences from the queue for example or something completely different and not based on Reference(s). But wouldn't it be nice if one could simply set a system property for the max. number of threads processing Finalizer(s)? I have prepared an improved variant of the prototype that employs a single ReferenceHandler thread and adds a ForkJoinPool that by default has a single worker thread which replaces the single finalization thread. So by default, no more threads are used than currently. If one wants (s)he can increase the concurrency of finalization with a system property. I have also improved the benchmarks that now focus on CPU overhead when processing references at more typical rates, rather than maximum throughput. They show that all changes taken together practically half the CPU time overhead of the finalization processing. So freed CPU time can be used for more useful work. I have also benchmarked the typical asynchronous WeakReference processing scenario where one thread removes enqueued WeakReferences from the queue. Results show about 25% decrease of CPU time overhead. Why does the prototype reduce more overhead for finalization than WeakReference processing? The main improvement in the change is the use of multiple doubly-linked lists for registration of Finalizer(s) and the use of lock-less algorithm for the lists. The WeakReference processing benchmark also uses such lists internally to handle registration/deregistration of WeakReferences so that the impact of this part is minimal and the difference of processing overheads between original and changed JDK code more obvious. (De)registration of Finalizer(s) OTOH is part of JDK infrastructure, so the improvement to registration list(s) also shows in the results. The results of WeakReferece processing benchmark also indicate that reverting to the use of a single finalization thread that just removes Finalizer(s) from the ReferenceQueue could lower the overhead even a bit further, but then it would not be possible to leverage FJ pool to simply configure the parallelism of finalization. If parallel processing of Finalizer(s) is an undesirable feature, I could restore the single finalization thread and the CPU overhead of finalization would be reduced to about 40% of current overhead with just the changes to data structures. So, for the curious, here's the improved prototype: http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/webrev.02/ And here are the improved benchmarks (with some results inline): http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/refproc/ The benchmark results in the ThroughputBench.java show the output of the test(s) when run with the Linux "time" command which shows the elapsed real time and the consumed user and system CPU times. I think this is relevant for measuring CPU overhead. So my question is: Is it or is it not desirable to have a configurable means to parallelize the finalization processing? The reduction of CPU overhead of infrastructure code should always be desirable, right? On 05/29/2015 05:57 AM, Kirk Pepperdine wrote: > Hi Peter, > > It is a very interesting proposal but to further David?s comments, the life-cycle costs of reference objects is horrendous of which the actual process of finalizing an object is only a fraction of that total cost. Unfortunately your micro-benchmark only focuses on one aspect of that cost. In other words, it isn?t very representative of a real concern. In the real world the finalizer *must compete with mutator threads and since F-J is an ?all threads on deck? implementation, it doesn?t play well with others. It creates a ?tragedy of the commons?. That is situations where everyone behaves rationally with a common resource but to the detriment of the whole group?. In short, parallelizing (F-Jing) *everything* in an application is simply not a good idea. We do not live in an infinite compute environment which means to have to consider the impact of our actions to the entire group. @Kirk I changed the prototype to only use a single FJ thread by default (configurable with a system property). Lowering the CPU overhead of finalizer processing for 50% is also an improvement. I'm still keeping finalization FJ-pool for now because it is more scaleable and has less overhead than a solution with multiple threads removing references from the same ReferenceQueue. This happens when the FJ-pool is configured with > 1 parallelism or when user code calls Runtime.runFinalization() that translates to ForkJoinPool.awaitQuiescence() which lends the calling thread to help the poll execute the tasks. > This was one of the points of my recent article in Java Magazine which I wrote to try to counter some of the rhetoric I was hearing in conference about the universal benefits of being able easily parallelize streams in Java 8. Yes, I agree it?s a great feature but it must be used with discretion. Case in point. After I finished writing the article, I started running into a couple of early adopters that had swallowed the parallel message whole indiscriminately parallelizing all of their streams. As you can imagine, they were quite surprised by the results and quickly worked to de-parallelize *all* of the streams in the application. > > To add some ability to parallelize the handling of reference objects seems like a good idea if you are collecting large numbers of reference objects (>10,000 per GC cycle). However if you are collecting large numbers of reference objects you?re most likely doing something else wrong. IME, finalization is extremely useful but really only for a limited number of use cases and none of them (to date) have resulted in the app burning through 1000s of final objects / sec. > > It would be interesting to know why why you picked on this particular issue. Well, JEP-132 was filed by Oracle, so I thought I'll try to tackle some of it's goals. I think I at least showed that the VM part of reference handling is mostly not the performance problem (if there is a problem at all), but the Java side could be modernized a bit. > Kind regards, > Kirk On 05/29/2015 07:20 PM, Rezaei, Mohammad A. wrote: > For what it's worth, I fully agree with David and Kirk around finalization not necessarily needing this treatment. > > However, I was hoping this would have the effect of improving (non-finalizable) reference handling. We've seen serious issues in WeakReference handling and have had to write some twisted code to deal with this. @Moh Can you elaborate some more on what twists were necessary or what problems you had? > So I guess the question I have to Kirk and David is: do you feel a GC load of 10K WeakReferences per cycle is also "doing something else wrong"? If there is an elegant way to achieve your goal without using WeakReferences then it might be better to not use them. But it is also true that WeakReferences frequently lend an elegant way to solve a problem. The same goes with finalization which is sometimes even more elegant. > Sorry if this is going off-topic. You're spot on topic and thanks for your comment. > Thanks > Moh > > Regards, Peter From kirk.pepperdine at gmail.com Sat May 30 05:20:20 2015 From: kirk.pepperdine at gmail.com (Kirk Pepperdine) Date: Sat, 30 May 2015 08:20:20 +0300 Subject: JEP 132: More-prompt finalization In-Reply-To: <6882C9A35DFB9B4FA2779F7BF5B9757D20761169A2@GSCMAMP06EX.firmwide.corp.gs.com> References: <55674C6E.8050509@gmail.com> <5567CC5E.7000102@oracle.com> <8DBC7345-09D8-458F-9017-298D1E620F86@gmail.com> <6882C9A35DFB9B4FA2779F7BF5B9757D20761169A2@GSCMAMP06EX.firmwide.corp.gs.com> Message-ID: <9B31A562-E312-4859-B3CE-542673171576@gmail.com> Hi Moh, > > However, I was hoping this would have the effect of improving (non-finalizable) reference handling. We've seen serious issues in WeakReference handling and have had to write some twisted code to deal with this. Better reference life-cycle handling would actually be beneficial IMHO as many cache implementations suffer because of certain aspects of the current implementation. SoftReference is very difficult to use. > > So I guess the question I have to Kirk and David is: do you feel a GC load of 10K WeakReferences per cycle is also "doing something else wrong?? Hard to say as this really has to be eval?ed on a case by case basis. But I?d wonder if the WeakReference was actually needed if you are recycling them so quickly. Regards, Kirk > > Sorry if this is going off-topic. > > Thanks > Moh > >> -----Original Message----- >> From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] On Behalf >> Of Kirk Pepperdine >> Sent: Thursday, May 28, 2015 11:58 PM >> To: david.holmes at oracle.com Holmes >> Cc: hotspot-gc-dev at openjdk.java.net openjdk.java.net; core-libs- >> dev at openjdk.java.net >> Subject: Re: JEP 132: More-prompt finalization >> >> Hi Peter, >> >> It is a very interesting proposal but to further David's comments, the life- >> cycle costs of reference objects is horrendous of which the actual process of >> finalizing an object is only a fraction of that total cost. Unfortunately your >> micro-benchmark only focuses on one aspect of that cost. In other words, it >> isn't very representative of a real concern. In the real world the finalizer >> *must compete with mutator threads and since F-J is an "all threads on deck" >> implementation, it doesn't play well with others. It creates a "tragedy of the >> commons". That is situations where everyone behaves rationally with a common >> resource but to the detriment of the whole group". In short, parallelizing (F- >> Jing) *everything* in an application is simply not a good idea. We do not live >> in an infinite compute environment which means to have to consider the impact >> of our actions to the entire group. >> >> This was one of the points of my recent article in Java Magazine which I wrote >> to try to counter some of the rhetoric I was hearing in conference about the >> universal benefits of being able easily parallelize streams in Java 8. Yes, I >> agree it's a great feature but it must be used with discretion. Case in point. >> After I finished writing the article, I started running into a couple of early >> adopters that had swallowed the parallel message whole indiscriminately >> parallelizing all of their streams. As you can imagine, they were quite >> surprised by the results and quickly worked to de-parallelize *all* of the >> streams in the application. >> >> To add some ability to parallelize the handling of reference objects seems >> like a good idea if you are collecting large numbers of reference objects >> (>10,000 per GC cycle). However if you are collecting large numbers of >> reference objects you're most likely doing something else wrong. IME, >> finalization is extremely useful but really only for a limited number of use >> cases and none of them (to date) have resulted in the app burning through >> 1000s of final objects / sec. >> >> It would be interesting to know why why you picked on this particular issue. >> >> Kind regards, >> Kirk >> >> >> >> On May 29, 2015, at 5:18 AM, David Holmes wrote: >> >>> Hi Peter, >>> >>> I guess I'm very concerned about the premise that finalization should scale >> to millions of objects and be performed highly concurrently. To me that's >> sending the wrong message about finalization. It also isn't the most effective >> use of cpu resources - most people would want to do useful work on most cpu's >> most of the time. >>> >>> Cheers, >>> David >>> >>> On 29/05/2015 3:12 AM, Peter Levart wrote: >>>> Hi, >>>> >>>> Did you know that the following simple loop: >>>> >>>> public class FinalizableBottleneck { >>>> static boolean no; >>>> >>>> @Override >>>> protected void finalize() throws Throwable { >>>> // empty finalize() method does not make the object finalizable >>>> // (it is not even registered on the finalizer's list) >>>> if (no) { >>>> throw new AssertionError(); >>>> } >>>> } >>>> >>>> public static void main(String[] args) { >>>> while (true) { >>>> new FinalizableBottleneck(); >>>> } >>>> } >>>> } >>>> >>>> >>>> ...quickly fills the entire heap with FinalizableBottleneck and internal >>>> Finalizer objects and brings the JVM to a halt? After a few seconds of >>>> running the above program, jmap -histo:live reports: >>>> >>>> num #instances #bytes class name >>>> ---------------------------------------------- >>>> 1: 50048325 2001933000 java.lang.ref.Finalizer >>>> 2: 50048278 800772448 FinalizableBottleneck >>>> >>>> >>>> There are a couple of bottlenecks that make this happen: >>>> >>>> - ReferenceHandler thread synchronizes with VM to unhook Reference(s) >>>> from the pending chain one be one and dispatches them to their respected >>>> ReferenceQueue(s) which also use synchronization for equeueing each >>>> Reference. >>>> - Enqueueing synchronizes with the finalization thread which removes the >>>> Finalizer(s) (FinalReferences) from the finalization queue and executes >>>> them. >>>> - Executing the Finalizer(s) removes them from the doubly-linked list of >>>> all Finalizer(s) which is used to retain them until they are needed and >>>> this synchronizes with the threads that link new Finalizer(s) into the >>>> doubly-linked list as new finalizable objects get registered. >>>> >>>> We see that the creation of a finalizable object only takes one >>>> synchronization (registering into the doubly-linked list) and is >>>> performed synchronously, while finalization takes 4 synchronizations >>>> among 4 different threads (in pairs) and happens when the Finalizer >>>> instance "travels" over from VM thread to ReferenceHandler thread and >>>> then to finalization thread. No wonder that finalization can not keep up >>>> with allocation in a single thread. The situation is even worse when >>>> finalize() methods do some actual work. >>>> >>>> I have experimented with various approaches to widen these bottlenecks >>>> and found out that I can not beat the ForkJoinPool when combined with >>>> some improvements to internal data structures used in reference >>>> processing. Here's a prototype I came up with: >>>> >>>> >> http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/webrev.01/ >>>> >>>> >>>> And this is the benchmark I use for measuring the throughput: >>>> >>>> >> http://cr.openjdk.java.net/~plevart/misc/JEP132/ReferenceHandling/FinalizerThr >> oughput.java >>>> >>>> >>>> The benchmark shows (results inline in source) that using unpatched JDK, >>>> on my PC (i7-2700K, Linux, JDK8) I can not construct more than 1500 >>>> finalizable objects per ms in a single thread and that while doing so, >>>> finalization only manages to process approx. 100 - 120 objects at the >>>> same time. Objects "in-flight" quickly accumulate and bring the VM to a >>>> halt, where it is not doing anything but full GC cycles. >>>> >>>> When constructing in 4 threads, there's not much difference. >>>> Construction of finalizable objects simply doesn't scale. >>>> >>>> Patched JDK shows something completely different. Single thread >>>> construction achieves a rate of 3600 objects / ms. Number of "in-flight" >>>> objects is kept constant at about 5-6M instances which amounts to approx >>>> 1.5 s of allocation. I think this is about the rate of GC cycles during >>>> which VM also processes the references. The benchmark also shows the >>>> ForkJoinPool statistics which shows that the number of queued tasks is >>>> also kept low. >>>> >>>> Increasing the allocation threads to 4 increases allocation rate to >>>> about 4300 objects / ms and finalization keeps up. Increasing allocation >>>> threads to 8, further increases allocation rate to about 4600 objects / >>>> ms and finalization still keeps up. The increase in rate is not linear, >>>> but keep in mind that i7 is a 4-core CPU. >>>> >>>> About the implementation... >>>> >>>> 1st improvement I did was for the doubly-linked list of Finalizer >>>> instances that is used to keep them alive until they are needed. I >>>> ripped-off the wonderful ConcurrentLinkedDeque by Doug Lea and Martin >>>> Buchholz and just kept the internal link/unlink methods while >>>> specializing them to Finalizer entries (very straight-forward). I >>>> experimented with throughput and got some improvement, but throughput >>>> has increased much more when I used several instances of independent >>>> lists and distributed registrations among them randomly (unlinking >>>> consequently is also distributed randomly). >>>> >>>> I found out that no matter how hard I try to optimize ReferenceQueue >>>> while keeping the API unchanged, I can only do so much and that was not >>>> enough. I have been surprised by how well ForkJoinPool distributes tasks >>>> among threads, so I concluded that leveraging it is the best choice. I >>>> re-designed the pending-list unhooking loop to unhook pending references >>>> in chunks which greatly improves the throughput. Since unhooking can be >>>> performed by a single thread while holding a lock which is mandated by >>>> interface between VM and Java, I didn't employ multiple threads, but a >>>> single eternal ForkJoinTask that unhooks in chunks and forks-off other >>>> processing tasks that process chunks. When there are just a couple of >>>> References pending at one time and a not-full chunk is unhooked, then >>>> the processing is performed by the same thread that unhooked the >>>> refrences, but when there are more, worker tasks are forked off and the >>>> unhooking thread continues with full peace. This processing includes >>>> execution of Cleaners, forking the finalizer tasks and enqueue-ing other >>>> references. Finalizer(s) are always executed as separate ForkJoinTask(s). >>>> >>>> It's interesting how Runtime.runFinalizers() is implemented in this >>>> patch - it basically amounts to ForkJoinPool.awaitQuiescence() ... >>>> >>>> I also tweaked the ReferenceQueue implementation a bit (it is still used >>>> for other kinds of references) so that it avoids synchronization with a >>>> monitor lock when there are no blocking waiters and uses CAS to >>>> enqueue/dequeue. This improves throughput when the queue is not empty. >>>> Since in the prototype multiple threads can enqueue into the same queue, >>>> I thought this would improve throughput in such situations. >>>> >>>> Comments, suggestions, criticism are welcome. >>>> >>>> Regards, Peter >>>> >