Mercurial > hg > openjdk > jdk8u > jdk
changeset 13543:8119ddcb3eec jdk8u222-b04
Merge
author | andrew |
---|---|
date | Thu, 23 May 2019 04:01:32 +0100 |
parents | 933f6b06c1cb (current diff) 9fdbdce56577 (diff) |
children | 2d4edd21bb38 |
files | |
diffstat | 8 files changed, 339 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/AbstractTask.java Fri May 17 18:53:33 2019 +0100 +++ b/src/share/classes/java/util/stream/AbstractTask.java Thu May 23 04:01:32 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, 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 @@ -27,6 +27,7 @@ import java.util.Spliterator; import java.util.concurrent.CountedCompleter; import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; /** * Abstract base class for most fork-join tasks used to implement stream ops. @@ -88,13 +89,7 @@ K extends AbstractTask<P_IN, P_OUT, R, K>> extends CountedCompleter<R> { - /** - * Default target factor of leaf tasks for parallel decomposition. - * To allow load balancing, we over-partition, currently to approximately - * four tasks per processor, which enables others to help out - * if leaf tasks are uneven or some processors are otherwise busy. - */ - static final int LEAF_TARGET = ForkJoinPool.getCommonPoolParallelism() << 2; + private static final int LEAF_TARGET = ForkJoinPool.getCommonPoolParallelism() << 2; /** The pipeline helper, common to all tasks in a computation */ protected final PipelineHelper<P_OUT> helper; @@ -157,6 +152,22 @@ } /** + * Default target of leaf tasks for parallel decomposition. + * To allow load balancing, we over-partition, currently to approximately + * four tasks per processor, which enables others to help out + * if leaf tasks are uneven or some processors are otherwise busy. + */ + public static int getLeafTarget() { + Thread t = Thread.currentThread(); + if (t instanceof ForkJoinWorkerThread) { + return ((ForkJoinWorkerThread) t).getPool().getParallelism() << 2; + } + else { + return LEAF_TARGET; + } + } + + /** * Constructs a new node of type T whose parent is the receiver; must call * the AbstractTask(T, Spliterator) constructor with the receiver and the * provided Spliterator. @@ -181,7 +192,7 @@ * @return suggested target leaf size */ public static long suggestTargetSize(long sizeEstimate) { - long est = sizeEstimate / LEAF_TARGET; + long est = sizeEstimate / getLeafTarget(); return est > 0L ? est : 1L; }
--- a/src/share/classes/java/util/stream/ForEachOps.java Fri May 17 18:53:33 2019 +0100 +++ b/src/share/classes/java/util/stream/ForEachOps.java Thu May 23 04:01:32 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, 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,6 @@ import java.util.Spliterator; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountedCompleter; -import java.util.concurrent.ForkJoinTask; import java.util.function.Consumer; import java.util.function.DoubleConsumer; import java.util.function.IntConsumer; @@ -378,7 +377,7 @@ this.spliterator = spliterator; this.targetSize = AbstractTask.suggestTargetSize(spliterator.estimateSize()); // Size map to avoid concurrent re-sizes - this.completionMap = new ConcurrentHashMap<>(Math.max(16, AbstractTask.LEAF_TARGET << 1)); + this.completionMap = new ConcurrentHashMap<>(Math.max(16, AbstractTask.getLeafTarget() << 1)); this.action = action; this.leftPredecessor = null; }
--- a/src/share/classes/java/util/stream/StreamSpliterators.java Fri May 17 18:53:33 2019 +0100 +++ b/src/share/classes/java/util/stream/StreamSpliterators.java Thu May 23 04:01:32 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, 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 @@ -898,7 +898,7 @@ * Note: The source spliterator may report {@code ORDERED} since that * spliterator be the result of a previous pipeline stage that was * collected to a {@code Node}. It is the order of the pipeline stage - * that governs whether the this slice spliterator is to be used or not. + * that governs whether this slice spliterator is to be used or not. */ static abstract class UnorderedSliceSpliterator<T, T_SPLITR extends Spliterator<T>> { static final int CHUNK_SIZE = 1 << 7; @@ -915,7 +915,7 @@ this.unlimited = limit < 0; this.skipThreshold = limit >= 0 ? limit : 0; this.chunkSize = limit >= 0 ? (int)Math.min(CHUNK_SIZE, - ((skip + limit) / AbstractTask.LEAF_TARGET) + 1) : CHUNK_SIZE; + ((skip + limit) / AbstractTask.getLeafTarget()) + 1) : CHUNK_SIZE; this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip); }
--- a/src/share/classes/sun/security/ssl/SessionId.java Fri May 17 18:53:33 2019 +0100 +++ b/src/share/classes/sun/security/ssl/SessionId.java Thu May 23 04:01:32 2019 +0100 @@ -27,6 +27,7 @@ package sun.security.ssl; import java.security.SecureRandom; +import java.util.Arrays; import javax.net.ssl.SSLProtocolException; /** @@ -91,11 +92,7 @@ @Override public int hashCode () { - int retval = 0; - - for (int i = 0; i < sessionId.length; i++) - retval += sessionId [i]; - return retval; + return Arrays.hashCode(sessionId); } /** Returns true if the parameter is the same session ID */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CustomFJPoolTest.java Thu May 23 04:01:32 2019 +0100 @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017, 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. + */ + +package org.openjdk.tests.java.util.stream; + +import org.testng.annotations.Test; + +import java.util.Comparator; +import java.util.Spliterator; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.stream.IntStream; +import java.util.stream.StreamSupport; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +/** + * Tests stream execution in a custom ForkJoinPool. See JDK-8190974. + */ +@Test +public class CustomFJPoolTest { + + // A Spliterator that counts the number of spliterators created + // including itself, thus the count starts at 1 + static class SplitCountingSpliterator<T> implements Spliterator<T> { + final Spliterator<T> s; + final AtomicInteger nsplits; + + // Top-level constructor + public SplitCountingSpliterator(Spliterator<T> s) { + this.s = s; + nsplits = new AtomicInteger(1); + } + + // Splitting constructor + SplitCountingSpliterator(Spliterator<T> s, AtomicInteger nsplits) { + this.s = s; + this.nsplits = nsplits; + } + + int splits() { + return nsplits.get(); + } + + @Override + + public boolean tryAdvance(Consumer<? super T> action) { + return s.tryAdvance(action); + } + + @Override + public void forEachRemaining(Consumer<? super T> action) { + s.forEachRemaining(action); + } + + @Override + public Spliterator<T> trySplit() { + Spliterator<T> split = s.trySplit(); + if (split != null) { + nsplits.incrementAndGet(); + return new SplitCountingSpliterator<>(split, nsplits); + } + else { + return null; + } + } + + @Override + public long estimateSize() { + return s.estimateSize(); + } + + @Override + public long getExactSizeIfKnown() { + return s.getExactSizeIfKnown(); + } + + @Override + public int characteristics() { + return s.characteristics(); + } + + @Override + public boolean hasCharacteristics(int characteristics) { + return s.hasCharacteristics(characteristics); + } + + @Override + public Comparator<? super T> getComparator() { + return s.getComparator(); + } + } + + public void testCustomPools() throws Exception { + int splitsForP1 = countSplits(new ForkJoinPool(1)); + int splitsForP2 = countSplits(new ForkJoinPool(2)); + assertEquals(splitsForP2, splitsForP1 * 2); + + int commonParallelism = ForkJoinPool.getCommonPoolParallelism(); + if (commonParallelism > 1 && commonParallelism < 128) { + int splitsForPHalfC = countSplits(new ForkJoinPool(commonParallelism / 2)); + int splitsForPC = countSplits(ForkJoinPool.commonPool()); + + assertTrue(splitsForPHalfC < splitsForPC); + assertEquals(splitsForPC / splitsForPHalfC, + nearestPowerOfTwo(commonParallelism) / nearestPowerOfTwo(commonParallelism / 2)); + } + } + + static int countSplits(ForkJoinPool fjp) throws Exception { + // The number of splits will be equivalent to the number of leaf nodes + // and will be a power of 2 + ForkJoinTask<Integer> fInteger = fjp.submit(() -> { + Spliterator<Integer> s = IntStream.range(0, 1024).boxed().parallel().spliterator(); + SplitCountingSpliterator<Integer> cs = new SplitCountingSpliterator<>(s); + StreamSupport.stream(cs, true).forEach(e -> {}); + return cs.splits(); + }); + return fInteger.get(); + } + + static int nearestPowerOfTwo(int i) { + return (i & (i - 1)) == 0 + ? i + : 1 << (32 - Integer.numberOfLeadingZeros(i)); + } +}
--- a/test/sun/security/lib/cacerts/VerifyCACerts.java Fri May 17 18:53:33 2019 +0100 +++ b/test/sun/security/lib/cacerts/VerifyCACerts.java Thu May 23 04:01:32 2019 +0100 @@ -26,6 +26,7 @@ * @test * @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923 8195774 8199779 * 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136 + * 8223499 * @summary Check root CA entries in cacerts file */ import java.io.File; @@ -49,7 +50,7 @@ + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 90; + private static final int COUNT = 88; // map of cert alias to SHA-256 fingerprint @SuppressWarnings("serial") @@ -144,10 +145,6 @@ "69:DD:D7:EA:90:BB:57:C9:3E:13:5D:C8:5E:A6:FC:D5:48:0B:60:32:39:BD:C4:54:FC:75:8B:2A:26:CF:7F:79"); put("verisignclass3g5ca [jdk]", "9A:CF:AB:7E:43:C8:D8:80:D0:6B:26:2A:94:DE:EE:E4:B4:65:99:89:C3:D0:CA:F1:9B:AF:64:05:E4:1A:B7:DF"); - put("certplusclass2primaryca [jdk]", - "0F:99:3C:8A:EF:97:BA:AF:56:87:14:0E:D5:9A:D1:82:1B:B4:AF:AC:F0:AA:9A:58:B5:D5:7A:33:8A:3A:FB:CB"); - put("certplusclass3pprimaryca [jdk]", - "CC:C8:94:89:37:1B:AD:11:1C:90:61:9B:EA:24:0A:2E:6D:AD:D9:9F:9F:6E:1D:4D:41:E5:8E:D6:DE:3D:02:85"); put("keynectisrootca [jdk]", "42:10:F1:99:49:9A:9A:C3:3C:8D:E0:2B:A6:DB:AA:14:40:8B:DD:8A:6E:32:46:89:C1:92:2D:06:97:15:A3:32"); put("dtrustclass3ca2 [jdk]", @@ -244,10 +241,6 @@ @SuppressWarnings("serial") private static final HashSet<String> EXPIRY_EXC_ENTRIES = new HashSet<String>() { { - // Valid until: Sat Jul 06 19:59:59 EDT 2019 - add("certplusclass2primaryca [jdk]"); - // Valid until: Sat Jul 06 19:59:59 EDT 2019 - add("certplusclass3pprimaryca [jdk]"); // Valid until: Tue Jul 09 14:40:36 EDT 2019 add("utnuserfirstobjectca [jdk]"); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/ssl/SessionIdCollisionTest.java Thu May 23 04:01:32 2019 +0100 @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2019, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.lang.reflect.Constructor; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * @test + * @bug 8203190 + * @summary Manual test to verify number of collisions in + * sun.security.ssl.SessionId.hashCode() + * @run main/manual SessionIdCollisionTest 100 20480 10000000 + */ + +/** + * + * Notes: + * - This is a manual test, not run automatically. + * - New default value of javax.net.ssl.sessionCacheSize in JDK 12+ is 20480 + * - According to JDK-8210985 24 hours expired cache may exceed several million + * entries = > 10_000_000 + * + * Example usage: java SessionIdCollissionTest 100 20480 10000000 + * + * Expected outcome of running the test is to see fewer collisions and, more + * importantly fewer elements in buckets when there are collisions. See: + * http://mail.openjdk.java.net/pipermail/jdk8u-dev/2019-May/009345.html + * + */ +public class SessionIdCollisionTest { + + private List<Integer> prepareHashCodes(int total) throws Exception { + Class<?> sessionIdClass = Class.forName("sun.security.ssl.SessionId"); + Constructor<?> c = sessionIdClass.getDeclaredConstructor(byte[].class); + c.setAccessible(true); + // case of rejoinable session ids generates 32 random bytes + byte[] sessionIdBytes = new byte[32]; + List<Integer> hashCodes = new ArrayList<>(); + for (int i = 0; i < total; i++) { + SecureRandom random = new SecureRandom(); + random.nextBytes(sessionIdBytes); + Object sessionId = c.newInstance(sessionIdBytes); + int hashCode = sessionId.hashCode(); + hashCodes.add(hashCode); + } + return hashCodes; + } + + private void printSummary(boolean withDistribution, + List<Integer> hashCodes) throws Exception { + final int bound = hashCodes.size(); + Collections.sort(hashCodes); + int collisions = 0; + Map<Integer, List<Integer>> collCountsReverse = new HashMap<>(); + for (int i = 0; i < bound - 1; i++) { + int oldval = hashCodes.get(i); + int nextval = hashCodes.get(i+1); + if (oldval == nextval) { + collisions++; + if (i == bound - 2) { // last elements + updateCollCountsReverse(collisions, collCountsReverse, oldval); + } + } else { + updateCollCountsReverse(collisions, collCountsReverse, oldval); + collisions = 0; + if (i == bound - 2) { // last elements + updateCollCountsReverse(collisions, collCountsReverse, nextval); + } + } + } + if (withDistribution) { + System.out.println("---- distribution ----"); + } + int collCount = 0; + int maxLength = 0; + List<Integer> sorted = new ArrayList<>(collCountsReverse.size()); + sorted.addAll(collCountsReverse.keySet()); + Collections.sort(sorted); + for (Integer coll: sorted) { + List<Integer> hc = collCountsReverse.get(coll); + if (withDistribution) { + System.out.printf("Hashcodes with %02d collisions | " + + "hashCodes: %s\n", coll, hc.toString()); + } + collCount += coll * hc.size(); + if (coll > maxLength) { + maxLength = coll; + } + } + if (withDistribution) { + System.out.println("---- distribution ----"); + } + System.out.println("Total number of collisions: " + collCount); + if (collCount > 0) { + System.out.println("Max length of collision list over all buckets: " + + maxLength); + } + } + + private void updateCollCountsReverse(int collisions, + Map<Integer, List<Integer>> reverse, int val) { + List<Integer> hc = reverse.get(collisions); + if (hc == null) { + hc = new ArrayList<>(); + hc.add(val); + reverse.put(collisions, hc); + } else { + hc.add(val); + } + } + + public void doCollissionTest(int total) throws Exception { + System.out.println("Collision test for " + total + " sessions:"); + System.out.println("------------------------------------------------"); + List<Integer> hashcodes = prepareHashCodes(total); + printSummary(false, hashcodes); + System.out.println(); + } + + public static void main(String[] args) throws Exception { + if (args.length < 1) { + System.err.println("java " + SessionIdCollisionTest.class.getSimpleName() + + "<num-sessions> [<num-sessions> ...]"); + System.exit(1); + } + SessionIdCollisionTest collTest = new SessionIdCollisionTest(); + for (int i = 0; i < args.length; i++) { + int total = Integer.parseInt(args[i]); + collTest.doCollissionTest(total); + } + } + +}