RFR: jsr166 jdk9 integration wave 7
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/ We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in https://bugs.openjdk.java.net/browse/JDK-8157523 Various improvements to ForkJoin/SubmissionPublisher code https://bugs.openjdk.java.net/browse/JDK-8080603 Replace Unsafe with VarHandle in java.util.concurrent classes There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
Hi Martin, Thanks, i will review carefully this week and do the necessary paper work for the FC exception required for API changes and the CCC. I found the cause of the test failure with java/util/Locale/Bug4152725.java. The constructor of VarHandle.AccessMode has some assert statements. These asserts were getting executed and causing locale-based classes to get loaded early in the startup process. I don’t yet know the why the test fails but i am guessing some form of circular dependency in charset related code results in a null value that obliterates any non-default locale data. I will replace the asserts with tests: https://bugs.openjdk.java.net/browse/JDK-8160439 <https://bugs.openjdk.java.net/browse/JDK-8160439> Paul.
On 27 Jun 2016, at 21:38, Martin Buchholz <martinrb@google.com> wrote:
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9.
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/ <http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/>
We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in
https://bugs.openjdk.java.net/browse/JDK-8157523 <https://bugs.openjdk.java.net/browse/JDK-8157523> Various improvements to ForkJoin/SubmissionPublisher code
https://bugs.openjdk.java.net/browse/JDK-8080603 <https://bugs.openjdk.java.net/browse/JDK-8080603> Replace Unsafe with VarHandle in java.util.concurrent classes
There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
Hi, This first the part of my review that concentrates mostly on the implementation. Minor stuff. I don’t claim to know enough about the changes in FJ/CF, so i especially focused on the VH changes for those classes. Paul. CompletableFutureTest — 3383 public void testRejectingExecutor() { 3384 for (Integer v : new Integer[] { 1, null }) { 3385 3386 final CountingRejectingExecutor e = new CountingRejectingExecutor(); 3473 public void testRejectingExecutorNeverInvoked() { 3474 final CountingRejectingExecutor e = new CountingRejectingExecutor(); 3475 3476 for (Integer v : new Integer[] { 1, null }) { 3477 3478 final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v); No indent for code within the for loop block ForkJoin — 571 * Style notes 572 * =========== 573 * 574 * Memory ordering relies mainly on VarHandles. This can be 575 * awkward and ugly, but also reflects the need to control 576 * outcomes across the unusual cases that arise in very racy code 577 * with very few invariants. So these explicit checks would exist 578 * in some form anyway. All fields are read into locals before 579 * use, and null-checked if they are references. This is usually 580 * done in a "C"-like style of listing declarations at the heads 581 * of methods or blocks, and using inline assignments on first 582 * encounter. Nearly all explicit checks lead to bypass/return, 583 * not exception throws, because they may legitimately arise due 584 * to cancellation/revocation during shutdown. The paragraph is referring to explicit checks (null and bounds checks) that were removed when the reference to Unsafe was removed. 2257 * @param saturate if nonnull, a predicate invoked upon attempts s/nonnull/non-null StampedLock — I notice lots of use of @ReservedStackAccess (same for ReentrantReadWriteLock), including Fred who might wanna look too. ConcurrentLinkedDeque — linkFirst uses HEAD.compareAndSet, where as linkLast uses TAIL.weakCompareAndSetVolatile, can the former use the weak variant too since, as commented, failure is OK. AtomicInteger — 185 public final int incrementAndGet() { 186 return (int)VALUE.getAndAdd(this, 1) + 1; 187 } You can use VALUE.addAndGet same for other similar methods here and in other classes.
On 27 Jun 2016, at 21:38, Martin Buchholz <martinrb@google.com> wrote:
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9.
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in
https://bugs.openjdk.java.net/browse/JDK-8157523 Various improvements to ForkJoin/SubmissionPublisher code
https://bugs.openjdk.java.net/browse/JDK-8080603 Replace Unsafe with VarHandle in java.util.concurrent classes
There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
On Tue, Jun 28, 2016 at 5:55 AM, Paul Sandoz <paul.sandoz@oracle.com> wrote:
CompletableFutureTest —
3383 public void testRejectingExecutor() { 3384 for (Integer v : new Integer[] { 1, null }) { 3385 3386 final CountingRejectingExecutor e = new CountingRejectingExecutor();
3473 public void testRejectingExecutorNeverInvoked() { 3474 final CountingRejectingExecutor e = new CountingRejectingExecutor(); 3475 3476 for (Integer v : new Integer[] { 1, null }) { 3477 3478 final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
No indent for code within the for loop block
This test class uses Weird Indentation intentionally. But more locally regular like this: --- src/test/tck/CompletableFutureTest.java 27 Jun 2016 21:41:17 -0000 1.160 +++ src/test/tck/CompletableFutureTest.java 28 Jun 2016 14:46:25 -0000 @@ -3354,8 +3354,8 @@ * Test submissions to an executor that rejects all tasks. */ public void testRejectingExecutor() { - for (Integer v : new Integer[] { 1, null }) { - + for (Integer v : new Integer[] { 1, null }) + { final CountingRejectingExecutor e = new CountingRejectingExecutor(); final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v); @@ -3434,9 +3434,7 @@ checkCompletedWithWrappedException(future, e.ex); assertEquals(futures.size(), e.count.get()); - - } - } + }} /** * Test submissions to an executor that rejects all tasks, but @@ -3444,10 +3442,10 @@ * explicitly completed. */ public void testRejectingExecutorNeverInvoked() { + for (Integer v : new Integer[] { 1, null }) + { final CountingRejectingExecutor e = new CountingRejectingExecutor(); - for (Integer v : new Integer[] { 1, null }) { - final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v); final CompletableFuture<Integer> incomplete = new CompletableFuture<>(); @@ -3495,9 +3493,7 @@ checkCompletedNormally(future, null); assertEquals(0, e.count.get()); - - } - } + }} /** * toCompletableFuture returns this CompletableFuture.
2257 * @param saturate if nonnull, a predicate invoked upon attempts
s/nonnull/non-null
Done. Index: src/main/java/util/concurrent/ForkJoinPool.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/ForkJoinPool.java,v retrieving revision 1.317 diff -u -r1.317 ForkJoinPool.java --- src/main/java/util/concurrent/ForkJoinPool.java 17 Jun 2016 13:03:45 -0000 1.317 +++ src/main/java/util/concurrent/ForkJoinPool.java 28 Jun 2016 14:41:28 -0000 @@ -2225,7 +2225,7 @@ * acceptable when submitted tasks cannot have dependencies * requiring additional threads. * - * @param saturate if nonnull, a predicate invoked upon attempts + * @param saturate if non-null, a predicate invoked upon attempts * to create more than the maximum total allowed threads. By * default, when a thread is about to block on a join or {@link * ManagedBlocker}, but cannot be replaced because the Index: src/main/java/util/concurrent/locks/StampedLock.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/locks/StampedLock.java,v retrieving revision 1.61 diff -u -r1.61 StampedLock.java --- src/main/java/util/concurrent/locks/StampedLock.java 17 Jun 2016 13:03:20 -0000 1.61 +++ src/main/java/util/concurrent/locks/StampedLock.java 28 Jun 2016 14:41:28 -0000 @@ -1310,7 +1310,7 @@ * AbstractQueuedSynchronizer (see its detailed explanation in AQS * internal documentation). * - * @param node if nonnull, the waiter + * @param node if non-null, the waiter * @param group either node or the group node is cowaiting with * @param interrupted if already interrupted * @return INTERRUPTED if interrupted or Thread.interrupted, else zero
On Tue, Jun 28, 2016 at 5:55 AM, Paul Sandoz <paul.sandoz@oracle.com> wrote:
AtomicInteger —
185 public final int incrementAndGet() { 186 return (int)VALUE.getAndAdd(this, 1) + 1; 187 }
You can use VALUE.addAndGet same for other similar methods here and in other classes.
Done: Index: src/main/java/util/concurrent/atomic/AtomicInteger.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/atomic/AtomicInteger.java,v retrieving revision 1.47 diff -u -U 1 -r1.47 AtomicInteger.java --- src/main/java/util/concurrent/atomic/AtomicInteger.java 17 Jun 2016 14:27:58 -0000 1.47 +++ src/main/java/util/concurrent/atomic/AtomicInteger.java 28 Jun 2016 16:28:39 -0000 @@ -156,3 +156,3 @@ public final int incrementAndGet() { - return (int)VALUE.getAndAdd(this, 1) + 1; + return (int)VALUE.addAndGet(this, 1); } @@ -165,3 +165,3 @@ public final int decrementAndGet() { - return (int)VALUE.getAndAdd(this, -1) - 1; + return (int)VALUE.addAndGet(this, -1); } @@ -175,3 +175,3 @@ public final int addAndGet(int delta) { - return (int)VALUE.getAndAdd(this, delta) + delta; + return (int)VALUE.addAndGet(this, delta); } Index: src/main/java/util/concurrent/atomic/AtomicIntegerArray.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/atomic/AtomicIntegerArray.java,v retrieving revision 1.48 diff -u -U 1 -r1.48 AtomicIntegerArray.java --- src/main/java/util/concurrent/atomic/AtomicIntegerArray.java 17 Jun 2016 14:27:58 -0000 1.48 +++ src/main/java/util/concurrent/atomic/AtomicIntegerArray.java 28 Jun 2016 16:28:39 -0000 @@ -170,3 +170,3 @@ public final int incrementAndGet(int i) { - return (int)AA.getAndAdd(array, i, 1) + 1; + return (int)AA.addAndGet(array, i, 1); } @@ -180,3 +180,3 @@ public final int decrementAndGet(int i) { - return (int)AA.getAndAdd(array, i, -1) - 1; + return (int)AA.addAndGet(array, i, -1); } @@ -191,3 +191,3 @@ public final int addAndGet(int i, int delta) { - return (int)AA.getAndAdd(array, i, delta) + delta; + return (int)AA.addAndGet(array, i, delta); } Index: src/main/java/util/concurrent/atomic/AtomicLong.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/atomic/AtomicLong.java,v retrieving revision 1.53 diff -u -U 1 -r1.53 AtomicLong.java --- src/main/java/util/concurrent/atomic/AtomicLong.java 17 Jun 2016 14:27:58 -0000 1.53 +++ src/main/java/util/concurrent/atomic/AtomicLong.java 28 Jun 2016 16:28:39 -0000 @@ -171,3 +171,3 @@ public final long incrementAndGet() { - return (long)VALUE.getAndAdd(this, 1L) + 1L; + return (long)VALUE.addAndGet(this, 1L); } @@ -180,3 +180,3 @@ public final long decrementAndGet() { - return (long)VALUE.getAndAdd(this, -1L) - 1L; + return (long)VALUE.addAndGet(this, -1L); } @@ -190,3 +190,3 @@ public final long addAndGet(long delta) { - return (long)VALUE.getAndAdd(this, delta) + delta; + return (long)VALUE.addAndGet(this, delta); } Index: src/main/java/util/concurrent/atomic/AtomicLongArray.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/atomic/AtomicLongArray.java,v retrieving revision 1.48 diff -u -U 1 -r1.48 AtomicLongArray.java --- src/main/java/util/concurrent/atomic/AtomicLongArray.java 17 Jun 2016 14:27:58 -0000 1.48 +++ src/main/java/util/concurrent/atomic/AtomicLongArray.java 28 Jun 2016 16:28:39 -0000 @@ -169,3 +169,3 @@ public final long incrementAndGet(int i) { - return (long)AA.getAndAdd(array, i, 1L) + 1L; + return (long)AA.addAndGet(array, i, 1L); } @@ -179,3 +179,3 @@ public final long decrementAndGet(int i) { - return (long)AA.getAndAdd(array, i, -1L) - 1L; + return (long)AA.addAndGet(array, i, -1L); } @@ -190,3 +190,3 @@ public long addAndGet(int i, long delta) { - return (long)AA.getAndAdd(array, i, delta) + delta; + return (long)AA.addAndGet(array, i, delta); }
On 06/28/2016 12:38 PM, Martin Buchholz wrote:
On Tue, Jun 28, 2016 at 5:55 AM, Paul Sandoz <paul.sandoz@oracle.com <mailto:paul.sandoz@oracle.com>> wrote:
You can use VALUE.addAndGet same for other similar methods here and in other classes.
Done:
And, amazingly, not in conflict with a pass I just did to delegate all atomics-related specs to VarHandle, so that in the future, all memory-model clarifications can be done in VarHandle without needing to update others. -Doug
On Tue, Jun 28, 2016 at 5:55 AM, Paul Sandoz <paul.sandoz@oracle.com> wrote:
ConcurrentLinkedDeque —
linkFirst uses HEAD.compareAndSet, where as linkLast uses TAIL.weakCompareAndSetVolatile, can the former use the weak variant too since, as commented, failure is OK.
Well spotted! --- src/main/java/util/concurrent/ConcurrentLinkedDeque.java 17 Jun 2016 13:03:45 -0000 1.73 +++ src/main/java/util/concurrent/ConcurrentLinkedDeque.java 28 Jun 2016 16:59:10 -0000 @@ -300,8 +300,8 @@ // Successful CAS is the linearization point // for e to become an element of this deque, // and for newNode to become "live". - if (p != h) // hop two nodes at a time - HEAD.compareAndSet(this, h, newNode); // Failure OK. + if (p != h) // hop two nodes at a time; failure is OK + HEAD.weakCompareAndSetVolatile(this, h, newNode); return; } // Lost CAS race to another thread; re-read prev
Hi Martin, I was looking at the new constructor's API documentation in ForkJoinPool - and somehow got confused by the sentence: 2235 * @param maximumPoolSize [... 2241 * ...] To 2240 * arrange the same value as is used by default for the common 2241 * pool, use {@code 256} plus the parallelism level. I mean - this looks bizarre, until you understand that the common pool has a maxSpares of 256 - which means that its actual max core pool size is 256 + parallelism level (am I getting that part right?). I wonder if it would be worth expanding on the rationale for that value? I mean something like: "The maximum number of spare threads used by the common pool is 256: to arrange the same value as is used by default for the common pool, use {@code 256} plus the parallelism level for {@code maximumPoolSize}." best regards, -- daniel On 27/06/16 20:38, Martin Buchholz wrote:
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9.
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in
https://bugs.openjdk.java.net/browse/JDK-8157523 Various improvements to ForkJoin/SubmissionPublisher code
https://bugs.openjdk.java.net/browse/JDK-8080603 Replace Unsafe with VarHandle in java.util.concurrent classes
There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
Hi, Several constructors of ForkJoinPool are modified with comments like " using defaults for all other parameters". However, there there are no other parameters in each constructor in question. It seems to imply a reference to the new full function constructor, that reference should be explicit complete with a {@link...} $.02, Roger On 6/29/2016 11:38 AM, Daniel Fuchs wrote:
Hi Martin,
I was looking at the new constructor's API documentation in ForkJoinPool - and somehow got confused by the sentence:
2235 * @param maximumPoolSize [... 2241 * ...] To 2240 * arrange the same value as is used by default for the common 2241 * pool, use {@code 256} plus the parallelism level.
I mean - this looks bizarre, until you understand that the common pool has a maxSpares of 256 - which means that its actual max core pool size is 256 + parallelism level (am I getting that part right?).
I wonder if it would be worth expanding on the rationale for that value?
I mean something like: "The maximum number of spare threads used by the common pool is 256: to arrange the same value as is used by default for the common pool, use {@code 256} plus the parallelism level for {@code maximumPoolSize}."
best regards,
-- daniel
On 27/06/16 20:38, Martin Buchholz wrote:
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9.
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in
https://bugs.openjdk.java.net/browse/JDK-8157523 Various improvements to ForkJoin/SubmissionPublisher code
https://bugs.openjdk.java.net/browse/JDK-8080603 Replace Unsafe with VarHandle in java.util.concurrent classes
There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
I agree the ForkJoinPool docs are difficult to understand. It's not immediately obvious that the maximumPoolSize of a user-constructed pool is effectively unlimited, but the maximumPoolSize of the common pool is availableProcessors + maxSpares. It may be better if the common pool and other pools are configured the same way, by having a maxSpares parameter instead of a maximumPoolSize parameter. (Using availableProcessors to size thread pools will increasingly become a resource usage problem) On Wed, Jun 29, 2016 at 8:38 AM, Daniel Fuchs <daniel.fuchs@oracle.com> wrote:
Hi Martin,
I was looking at the new constructor's API documentation in ForkJoinPool - and somehow got confused by the sentence:
2235 * @param maximumPoolSize [... 2241 * ...] To 2240 * arrange the same value as is used by default for the common 2241 * pool, use {@code 256} plus the parallelism level.
I mean - this looks bizarre, until you understand that the common pool has a maxSpares of 256 - which means that its actual max core pool size is 256 + parallelism level (am I getting that part right?).
I wonder if it would be worth expanding on the rationale for that value?
I mean something like: "The maximum number of spare threads used by the common pool is 256: to arrange the same value as is used by default for the common pool, use {@code 256} plus the parallelism level for {@code maximumPoolSize}."
best regards,
-- daniel
On 27/06/16 20:38, Martin Buchholz wrote:
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9.
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in
https://bugs.openjdk.java.net/browse/JDK-8157523 Various improvements to ForkJoin/SubmissionPublisher code
https://bugs.openjdk.java.net/browse/JDK-8080603 Replace Unsafe with VarHandle in java.util.concurrent classes
There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
Responding to ForkJoinPool reviews (thanks for these!)... On 06/29/2016 06:41 PM, Martin Buchholz wrote:
It may be better if the common pool and other pools are configured the same way, by having a maxSpares parameter instead of a maximumPoolSize parameter.
The choice was between being consistent with the common pool property vs the ThreadPoolExecutor constructor. The latter should be easier for users to share configuration across pool classes, so I used it at the expense of harder-to-decode parameter specs, but now made a little cleaeer:
On Wed, Jun 29, 2016 at 8:38 AM, Daniel Fuchs <daniel.fuchs@oracle.com <mailto:daniel.fuchs@oracle.com>> wrote:
I mean something like: "The maximum number of spare threads used by the common pool is 256: to arrange the same value as is used by default for the common pool, use {@code 256} plus the parallelism level for {@code maximumPoolSize}."
Thanks! I added a variant of this sentence. On 06/29/2016 02:13 PM, Roger Riggs wrote:
Hi,
Several constructors of ForkJoinPool are modified with comments like " using defaults for all other parameters". However, there there are no other parameters in each constructor in question.
It seems to imply a reference to the new full function constructor, that reference should be explicit complete with a {@link...}
Thanks!. Done. At least I hope so. Because of https://bugs.openjdk.java.net/browse/JDK-8136503 we can't run javadoc on pre-integrated sources to check how this came out. On 06/28/2016 08:55 AM, Paul Sandoz wrote:
577 * ... So these explicit checks would exist in some form anyway. ...
The paragraph is referring to explicit checks (null and bounds checks) that were removed when the reference to Unsafe was removed.
Thanks. I killed the explicit checks sentence. -Doug
On 30/06/16 01:04, Doug Lea wrote:
On Wed, Jun 29, 2016 at 8:38 AM, Daniel Fuchs <daniel.fuchs@oracle.com <mailto:daniel.fuchs@oracle.com>> wrote:
I mean something like: "The maximum number of spare threads used by the common pool is 256: to arrange the same value as is used by default for the common pool, use {@code 256} plus the parallelism level for {@code maximumPoolSize}."
Thanks! I added a variant of this sentence.
On 30/06/16 12:20, Martin Buchholz wrote:
Webrev regenerated with updates. Lots of rework for the atomic VarHandle specs. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
Thanks Doug, Martin, I find the new text is indeed more clear :-) best regards, -- daniel
Hi Martin, I'm looking at changes in StampedLock. I noticed that you have consistently (in 4 places) replaced usages of the following idiom: 1044 if (LockSupport.nextSecondarySeed() >= 0) 1045 --spins; with the following: 1056 --spins; 1057 Thread.onSpinWait(); Was that intentional? It looks almost like you thought that LockSupport.nextSecondarySeed() >= 0 is always true and that it is used just to introduce some pause into the spin loop. It is only true in roughly half of invocations as nextSecondarySeed() has the full signed int span. Regards, Peter On 06/27/2016 09:38 PM, Martin Buchholz wrote:
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9.
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in
https://bugs.openjdk.java.net/browse/JDK-8157523 Various improvements to ForkJoin/SubmissionPublisher code
https://bugs.openjdk.java.net/browse/JDK-8080603 Replace Unsafe with VarHandle in java.util.concurrent classes
There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
I see it was intentional as it is described in the docs... Is new behavior better? Regards, Peter On 06/29/2016 07:19 PM, Peter Levart wrote:
Hi Martin,
I'm looking at changes in StampedLock. I noticed that you have consistently (in 4 places) replaced usages of the following idiom:
1044 if (LockSupport.nextSecondarySeed() >= 0) 1045 --spins;
with the following:
1056 --spins; 1057 Thread.onSpinWait();
Was that intentional? It looks almost like you thought that LockSupport.nextSecondarySeed() >= 0 is always true and that it is used just to introduce some pause into the spin loop. It is only true in roughly half of invocations as nextSecondarySeed() has the full signed int span.
Regards, Peter
On 06/27/2016 09:38 PM, Martin Buchholz wrote:
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9.
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in
https://bugs.openjdk.java.net/browse/JDK-8157523 Various improvements to ForkJoin/SubmissionPublisher code
https://bugs.openjdk.java.net/browse/JDK-8080603 Replace Unsafe with VarHandle in java.util.concurrent classes
There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
On 06/29/2016 01:28 PM, Peter Levart wrote:
I see it was intentional as it is described in the docs...
Is new behavior better?
In tests so far, I see smaller variances, and approximately same average, so yes, a little better. Other usages of onSpinWait probably have more effect than this one in StampedLock. -Doug
Regards, Peter
On 06/29/2016 07:19 PM, Peter Levart wrote:
Hi Martin,
I'm looking at changes in StampedLock. I noticed that you have consistently (in 4 places) replaced usages of the following idiom:
1044 if (LockSupport.nextSecondarySeed() >= 0) 1045 --spins;
with the following:
1056 --spins; 1057 Thread.onSpinWait();
Was that intentional? It looks almost like you thought that LockSupport.nextSecondarySeed() >= 0 is always true and that it is used just to introduce some pause into the spin loop. It is only true in roughly half of invocations as nextSecondarySeed() has the full signed int span.
Regards, Peter
On 06/27/2016 09:38 PM, Martin Buchholz wrote:
jsr166 has been pervasively modified to use VarHandles, but there are some other pending changes (that cannot be cleanly separated from VarHandle conversion). We expect this to be the last feature integration for jdk9.
http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
We're asking Paul to do most of the review work here, as owner of VarHandles JEP and as Oracle employee. We need approval for API changes in
https://bugs.openjdk.java.net/browse/JDK-8157523 Various improvements to ForkJoin/SubmissionPublisher code
https://bugs.openjdk.java.net/browse/JDK-8080603 Replace Unsafe with VarHandle in java.util.concurrent classes
There is currently a VarHandle bootstrap problem with ThreadLocal/AtomicInteger that causes java/util/Locale/Bug4152725.java to fail. Again I'm hoping that Paul will figure out what to do. In the past rearranging the order of operations in <clinit> has worked for similar problems. It's not surprising we have problems, since j.u.c. needs VarHandles initialized to do work, and j.l.invoke needs j.u.c. (notably AtomicInteger and ConcurrentHashMap) to do work. Maybe we need some very low-level concurrency infrastructure that does not use VarHandles, only for bootstrap?
Webrev regenerated with updates. Lots of rework for the atomic VarHandle specs. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/ In the unlikely case you want the old webrev, it's at http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration....
Hi, I noticed that in ThreadLocalRandom and Striped64, Unsafe remains for the sole purpose of accessing 3 fields in java.lang.Thread class. Now that there are VarHandle(s), they could be combined with SharedSecrets to get rid of Unsafe access in those two classes. For example, in Striped64: http://cr.openjdk.java.net/~plevart/misc/JavaLangThreadAccess/webrev.Striped... This has the added benefit that IDE(s) can search for usages of JavaLangThreadAccess.xxx methods to quickly find all the usages. Note that even though Thread is one of primordial classes, obtaining VarHandle(s) for its fields is lazy and works without problems... Regards, Peter On 06/30/2016 01:20 PM, Martin Buchholz wrote:
Webrev regenerated with updates. Lots of rework for the atomic VarHandle specs. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/ <http://cr.openjdk.java.net/%7Emartin/webrevs/openjdk9/jsr166-jdk9-integration/>
In the unlikely case you want the old webrev, it's at http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration.... <http://cr.openjdk.java.net/%7Emartin/webrevs/openjdk9/jsr166-jdk9-integration.2016-06-29/>
Hi Peter, Thanks, that’s interesting. I am uncertain if our 166 fellows will be reluctant or not to pull in a dependency on jdk.internal.misc.SharedSecrets. But i note the A*FUs already have a dependency on jdk.internal.reflect.Reflection.getCallerClass(). I like the laziness aspect, but i have a preference for Thread to grant it’s lookup to TLR and Striped64, a white list if you like. The pro being Thread’s fields are not exposed to all within java.base the con being that TLR and Striped64 must guard that lookup as they would their own. There is also another use-case here for the A*FUs, which probably less of a priority. What we need is to somehow get the lookup of the caller, perhaps injected as an argument into the caller sensitive method newUpdater methods. Paul.
On 30 Jun 2016, at 14:41, Peter Levart <peter.levart@gmail.com> wrote:
Hi,
I noticed that in ThreadLocalRandom and Striped64, Unsafe remains for the sole purpose of accessing 3 fields in java.lang.Thread class. Now that there are VarHandle(s), they could be combined with SharedSecrets to get rid of Unsafe access in those two classes. For example, in Striped64:
http://cr.openjdk.java.net/~plevart/misc/JavaLangThreadAccess/webrev.Striped...
This has the added benefit that IDE(s) can search for usages of JavaLangThreadAccess.xxx methods to quickly find all the usages. Note that even though Thread is one of primordial classes, obtaining VarHandle(s) for its fields is lazy and works without problems...
Regards, Peter
On 06/30/2016 01:20 PM, Martin Buchholz wrote:
Webrev regenerated with updates. Lots of rework for the atomic VarHandle specs. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
In the unlikely case you want the old webrev, it's at http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration....
On 06/30/2016 10:08 AM, Paul Sandoz wrote:
Hi Peter,
Thanks, that’s interesting. I am uncertain if our 166 fellows will be reluctant or not to pull in a dependency on jdk.internal.misc.SharedSecrets.
Background: we are reluctant to rely on anything that makes sources impossible to use in (usually, upcoming versions of) Android. Which probably doesn't directly apply here. But my main concern in this case is that we need better assurance that there are no possible start-up circularities, since we've already had some near-miss experiences with ThreadLocalRandom. Is there a solid argument? -Doug
On 1 Jul 2016, at 00:53, Doug Lea <dl@cs.oswego.edu> wrote:
On 06/30/2016 10:08 AM, Paul Sandoz wrote:
Hi Peter,
Thanks, that’s interesting. I am uncertain if our 166 fellows will be reluctant or not to pull in a dependency on jdk.internal.misc.SharedSecrets.
Background: we are reluctant to rely on anything that makes sources impossible to use in (usually, upcoming versions of) Android. Which probably doesn't directly apply here.
But my main concern in this case is that we need better assurance that there are no possible start-up circularities, since we've already had some near-miss experiences with ThreadLocalRandom. Is there a solid argument?
I suggest we spin this off from the main issue and investigate afterwards, i have logged an issue: https://bugs.openjdk.java.net/browse/JDK-8160710 <https://bugs.openjdk.java.net/browse/JDK-8160710> Paul.
Hi, On 07/01/2016 10:36 AM, Paul Sandoz wrote:
On 1 Jul 2016, at 00:53, Doug Lea <dl@cs.oswego.edu> wrote:
On 06/30/2016 10:08 AM, Paul Sandoz wrote:
Hi Peter,
Thanks, that’s interesting. I am uncertain if our 166 fellows will be reluctant or not to pull in a dependency on jdk.internal.misc.SharedSecrets.
Background: we are reluctant to rely on anything that makes sources impossible to use in (usually, upcoming versions of) Android. Which probably doesn't directly apply here.
But my main concern in this case is that we need better assurance that there are no possible start-up circularities, since we've already had some near-miss experiences with ThreadLocalRandom. Is there a solid argument?
ThreadLocalRandom was tricky, yes! But I think this one is pretty safe: http://cr.openjdk.java.net/~plevart/misc/JavaLangThreadAccess/webrev.Striped... What it does in Thread.<clinit> is instantiate an anonymous class implementing JavaLangThreadAccess interface and injecting the instance into the SharedSecrets class' static field. This triggers initializing just 3 classes: - JavaLangThreadAccess interface - Thread$NN anonymous class implementing JavaLangThreadAccess - SharedSecrets class That's all. The patch modifies SharedSecrets so that it doesn't initialize anything else (originally it initialized the Unsafe class which was premature and the JVM bootstrap failed because of that). This is the diff between the traces of loading classes on unpatched JDK 9 (jsr166 jdk9 integration wave 7 not applied yet) and with above patch applied when running an empty program: [peter@peterl tmp]$ diff -c cltrace0.txt cltrace1.txt *** cltrace0.txt 2016-07-07 17:04:21.872277904 +0200 --- cltrace1.txt 2016-07-07 17:04:26.368307983 +0200 *************** *** 1,4 **** ! [info][class,load] opened: /home/peter/Apps64/jdk1.9.0.default/lib/modules [info][class,load] java.lang.Object source: jrt:/java.base [info][class,load] java.io.Serializable source: jrt:/java.base [info][class,load] java.lang.Comparable source: jrt:/java.base --- 1,4 ---- ! [info][class,load] opened: /home/peter/work/hg/jdk9-dev/build/linux-x86_64-normal-server-release/images/jdk/lib/modules [info][class,load] java.lang.Object source: jrt:/java.base [info][class,load] java.io.Serializable source: jrt:/java.base [info][class,load] java.lang.Comparable source: jrt:/java.base *************** *** 123,128 **** --- 123,131 ---- [info][class,load] java.security.BasicPermission source: jrt:/java.base [info][class,load] java.lang.RuntimePermission source: jrt:/java.base [info][class,load] java.lang.StringLatin1 source: jrt:/java.base + [info][class,load] jdk.internal.misc.JavaLangThreadAccess source: jrt:/java.base + [info][class,load] java.lang.Thread$2 source: jrt:/java.base + [info][class,load] jdk.internal.misc.SharedSecrets source: jrt:/java.base [info][class,load] java.security.AccessController source: jrt:/java.base [info][class,load] java.util.Collections source: jrt:/java.base [info][class,load] java.lang.Iterable source: jrt:/java.base *************** *** 167,173 **** [info][class,load] java.lang.ref.ReferenceQueue$Lock source: jrt:/java.base [info][class,load] jdk.internal.misc.JavaLangRefAccess source: jrt:/java.base [info][class,load] java.lang.ref.Reference$1 source: jrt:/java.base - [info][class,load] jdk.internal.misc.SharedSecrets source: jrt:/java.base [info][class,load] java.lang.Class$Atomic source: jrt:/java.base [info][class,load] java.lang.reflect.ReflectPermission source: jrt:/java.base [info][class,load] jdk.internal.reflect.ReflectionFactory$GetReflectionFactoryAction source: jrt:/java.base --- 170,175 ---- *************** *** 389,413 **** [info][class,load] jdk.internal.module.SystemModules source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor source: jrt:/java.base [info][class,load] jdk.internal.module.Builder source: jrt:/java.base [info][class,load] jdk.internal.misc.JavaLangModuleAccess source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$1 source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$Requires$Modifier source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$Requires source: jrt:/java.base - [info][class,load] java.util.Collections$EmptyIterator source: jrt:/java.base [info][class,load] java.util.Collections$1 source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$Exports source: jrt:/java.base [info][class,load] java.util.HashMap$TreeNode source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$Version source: jrt:/java.base [info][class,load] java.util.ArrayList source: jrt:/java.base - [info][class,load] java.util.Collections$UnmodifiableCollection source: jrt:/java.base - [info][class,load] java.util.Collections$UnmodifiableSet source: jrt:/java.base [info][class,load] java.util.Collections$UnmodifiableMap source: jrt:/java.base - [info][class,load] java.lang.module.ModuleDescriptor$Provides source: jrt:/java.base [info][class,load] java.util.HashMap$KeySet source: jrt:/java.base [info][class,load] java.util.HashMap$HashIterator source: jrt:/java.base [info][class,load] java.util.HashMap$KeyIterator source: jrt:/java.base - [info][class,load] jdk.internal.module.ModuleHashes source: jrt:/java.base [info][class,load] java.util.LinkedHashSet source: jrt:/java.base [info][class,load] jdk.internal.module.ModuleHashes$HashSupplier source: jrt:/java.base [info][class,load] java.lang.module.SystemModuleFinder$2 source: jrt:/java.base [info][class,load] java.util.function.Supplier source: jrt:/java.base --- 391,416 ---- [info][class,load] jdk.internal.module.SystemModules source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor source: jrt:/java.base [info][class,load] jdk.internal.module.Builder source: jrt:/java.base + [info][class,load] jdk.internal.misc.SharedSecrets$U source: jrt:/java.base [info][class,load] jdk.internal.misc.JavaLangModuleAccess source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$1 source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$Requires$Modifier source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$Requires source: jrt:/java.base [info][class,load] java.util.Collections$1 source: jrt:/java.base + [info][class,load] java.util.Collections$EmptyIterator source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$Exports source: jrt:/java.base + [info][class,load] java.util.Collections$UnmodifiableCollection source: jrt:/java.base + [info][class,load] java.util.Collections$UnmodifiableSet source: jrt:/java.base [info][class,load] java.util.HashMap$TreeNode source: jrt:/java.base + [info][class,load] java.lang.module.ModuleDescriptor$Provides source: jrt:/java.base [info][class,load] java.lang.module.ModuleDescriptor$Version source: jrt:/java.base [info][class,load] java.util.ArrayList source: jrt:/java.base [info][class,load] java.util.Collections$UnmodifiableMap source: jrt:/java.base [info][class,load] java.util.HashMap$KeySet source: jrt:/java.base [info][class,load] java.util.HashMap$HashIterator source: jrt:/java.base [info][class,load] java.util.HashMap$KeyIterator source: jrt:/java.base [info][class,load] java.util.LinkedHashSet source: jrt:/java.base + [info][class,load] jdk.internal.module.ModuleHashes source: jrt:/java.base [info][class,load] jdk.internal.module.ModuleHashes$HashSupplier source: jrt:/java.base [info][class,load] java.lang.module.SystemModuleFinder$2 source: jrt:/java.base [info][class,load] java.util.function.Supplier source: jrt:/java.base ...what we see is that the patch actually delays loading of some classes (except the 3 classes mentioned). Regards, Peter
I suggest we spin this off from the main issue and investigate afterwards, i have logged an issue:
https://bugs.openjdk.java.net/browse/JDK-8160710 <https://bugs.openjdk.java.net/browse/JDK-8160710>
Paul.
On 30 Jun 2016, at 13:20, Martin Buchholz <martinrb@google.com> wrote:
Webrev regenerated with updates. Lots of rework for the atomic VarHandle specs. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
Look good, focusing on the atomics section. I noted that some text has been removed from the package-info.java that should but is not currently on VarHandle. After things have settled down a bit i will do a pass over the non-normative bits. Paul.
In the unlikely case you want the old webrev, it's at http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration....
On 30 Jun 2016, at 13:20, Martin Buchholz <martinrb@google.com> wrote:
Webrev regenerated with updates. Lots of rework for the atomic VarHandle specs. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
Here is a spec diff for the atomics: http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/s... <http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/specdiff/java/util/concurrent/atomic/package-summary.html> Paul.
In the unlikely case you want the old webrev, it's at http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration....
Hi Paul, On 07/07/2016 12:39 PM, Paul Sandoz wrote:
On 30 Jun 2016, at 13:20, Martin Buchholz <martinrb@google.com> wrote:
Webrev regenerated with updates. Lots of rework for the atomic VarHandle specs. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration/
Here is a spec diff for the atomics:
http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/s... <http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/specdiff/java/util/concurrent/atomic/package-summary.html>
Paul.
Why don't javadocs of AtomicXXX.getPlain|setPlain methods refer to VarHandle.get|set like other methods do? Also, I can't seem to understand why the naming of methods on VarHandle vs. the naming of methods on AtomicXXX classes is sometimes so confusingly different and/or the same. For example, the following pairs present equivalent memory effects: VarHandle.getVolatile ~ AtomicInteger.get VarHandle.get ~ AtomicInteger.getPlain I understand that AtomicXXX classes have legacy and we can't change their method names. But why was a method in new class (VarHandle) given the same name as an existing AtomicXXX class method with different memory effects? IMHO, this is just asking for confusion among developers. Why the naming wasn't more like the following: VarHandle.getVolatile ~ @Deprecated AtomicInteger.get ~ /* new method */ AtomicInteger.getVolatile VarHandle.getPlain ~ /* new method */ AtomicInteger.getPlain Why was it chosen that plain VarHandle.get() method is without Plain suffix? Do you expect it will be used more often than other methods? Regards, Peter
In the unlikely case you want the old webrev, it's at http://cr.openjdk.java.net/~martin/webrevs/openjdk9/jsr166-jdk9-integration....
On 07/07/2016 10:06 AM, Peter Levart wrote:
Why the naming wasn't more like the following:
No matter which conventions you choose here, some people will be unhappy or confused. The current scheme seems to make the current users of both Unsafe and AtomicX least unhappy or confused.
VarHandle.getPlain ~ /* new method */ AtomicInteger.getPlain
This is pretty close to original proposal. But ...
Why was it chosen that plain VarHandle.get() method is without Plain suffix?
... a few people complained about the "Plain" (or in one previous guise "Relaxed") suffix being unnecessary and inconsistently applied. For example, should weak-CAS be renamed weakCompareAndSetPlain? -Doug
On Thu, Jul 7, 2016 at 3:39 AM, Paul Sandoz <paul.sandoz@oracle.com> wrote:
Here is a spec diff for the atomics:
http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/s... < http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/s...
I looked at the specdiff - easier to review than the raw text diff. The new spec delegates heavily to the VarHandle spec. Let's make that spec good. Some of the old content, like the guidance on how to store floats/doubles in ints/longs in package-info .java, should probably be migrated to VarHandles, and not just discarded.
On 8 Jul 2016, at 22:10, Martin Buchholz <martinrb@google.com> wrote:
On Thu, Jul 7, 2016 at 3:39 AM, Paul Sandoz <paul.sandoz@oracle.com <mailto:paul.sandoz@oracle.com>> wrote:
Here is a spec diff for the atomics:
http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/s... <http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/specdiff/java/util/concurrent/atomic/package-summary.html> <http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/s... <http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8080603-concurrent-unsafe-vhs/specdiff/java/util/concurrent/atomic/package-summary.html>>
I looked at the specdiff - easier to review than the raw text diff. The new spec delegates heavily to the VarHandle spec. Let's make that spec good. Some of the old content, like the guidance on how to store floats/doubles in ints/longs in package-info .java, should probably be migrated to VarHandles, and not just discarded.
Yes, another pass over the VH documentation is needed. Which hopefully can start soon, given code changes are now settling down. I am thinking about placing the signature-polymorphic stuff on MH and VH into a separate html document, that will then give more room to talk about relevant details on the VH class. Paul.
participants (6)
-
Daniel Fuchs
-
Doug Lea
-
Martin Buchholz
-
Paul Sandoz
-
Peter Levart
-
Roger Riggs