--- a/jdk/make/gensrc/GensrcMisc.gmk Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/make/gensrc/GensrcMisc.gmk Thu Mar 03 12:49:12 2016 -0800
@@ -25,11 +25,11 @@
##########################################################################################
# Install the launcher name, release version string, full version
-# string and the runtime name into the Version.java file.
+# string and the runtime name into the VersionProps.java file.
$(eval $(call SetupTextFileProcessing, BUILD_VERSION_JAVA, \
- SOURCE_FILES := $(JDK_TOPDIR)/src/java.base/share/classes/sun/misc/Version.java.template, \
- OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/misc/Version.java, \
+ SOURCE_FILES := $(JDK_TOPDIR)/src/java.base/share/classes/java/lang/VersionProps.java.template, \
+ OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/java/lang/VersionProps.java, \
REPLACEMENTS := \
@@LAUNCHER_NAME@@ => $(LAUNCHER_NAME) ; \
@@RUNTIME_NAME@@ => $(RUNTIME_NAME) ; \
--- a/jdk/make/mapfiles/libjava/mapfile-vers Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Thu Mar 03 12:49:12 2016 -0800
@@ -268,8 +268,6 @@
Java_sun_reflect_Reflection_getCallerClass__;
Java_sun_reflect_Reflection_getCallerClass__I;
Java_sun_reflect_Reflection_getClassAccessFlags;
- Java_sun_misc_Version_getJdkVersionInfo;
- Java_sun_misc_Version_getJvmVersionInfo;
Java_jdk_internal_misc_VM_latestUserDefinedLoader;
Java_jdk_internal_misc_VM_getuid;
Java_jdk_internal_misc_VM_geteuid;
--- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -133,39 +133,62 @@
}
/**
- * This method has the same contract as ensureCapacity, but is
- * never synchronized.
+ * For positive values of {@code minimumCapacity}, this method
+ * behaves like {@code ensureCapacity}, however it is never
+ * synchronized.
+ * If {@code minimumCapacity} is non positive due to numeric
+ * overflow, this method throws {@code OutOfMemoryError}.
*/
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
- int capacity = value.length >> coder;
- if (minimumCapacity - capacity > 0) {
- expandCapacity(minimumCapacity);
+ int oldCapacity = value.length >> coder;
+ if (minimumCapacity - oldCapacity > 0) {
+ value = Arrays.copyOf(value,
+ newCapacity(minimumCapacity) << coder);
}
}
/**
- * This implements the expansion semantics of ensureCapacity with no
- * size check or synchronization.
+ * The maximum size of array to allocate (unless necessary).
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
*/
- private void expandCapacity(int minimumCapacity) {
- int newCapacity = (value.length >> coder) * 2 + 2;
- if (newCapacity - minimumCapacity < 0) {
- newCapacity = minimumCapacity;
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
+ * Returns a capacity at least as large as the given minimum capacity.
+ * Returns the current capacity increased by the same amount + 2 if
+ * that suffices.
+ * Will not return a capacity greater than
+ * {@code (MAX_ARRAY_SIZE >> coder)} unless the given minimum capacity
+ * is greater than that.
+ *
+ * @param minCapacity the desired minimum capacity
+ * @throws OutOfMemoryError if minCapacity is less than zero or
+ * greater than (Integer.MAX_VALUE >> coder)
+ */
+ private int newCapacity(int minCapacity) {
+ // overflow-conscious code
+ int oldCapacity = value.length >> coder;
+ int newCapacity = (oldCapacity << 1) + 2;
+ if (newCapacity - minCapacity < 0) {
+ newCapacity = minCapacity;
}
- if (newCapacity < 0) {
- if (minimumCapacity < 0) {// overflow
- throw new OutOfMemoryError();
- }
- newCapacity = Integer.MAX_VALUE;
+ int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
+ return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0)
+ ? hugeCapacity(minCapacity)
+ : newCapacity;
+ }
+
+ private int hugeCapacity(int minCapacity) {
+ int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
+ int UNSAFE_BOUND = Integer.MAX_VALUE >> coder;
+ if (UNSAFE_BOUND - minCapacity < 0) { // overflow
+ throw new OutOfMemoryError();
}
- if (coder != LATIN1 && newCapacity > StringUTF16.MAX_LENGTH) {
- if (minimumCapacity >= StringUTF16.MAX_LENGTH) {
- throw new OutOfMemoryError();
- }
- newCapacity = StringUTF16.MAX_LENGTH;
- }
- this.value = Arrays.copyOf(value, newCapacity << coder);
+ return (minCapacity > SAFE_BOUND)
+ ? minCapacity : SAFE_BOUND;
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/System.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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
@@ -1418,8 +1418,7 @@
* for the given {@code caller}.
*
* @param name the name of the logger.
- * @param caller the class for which the logger is being requested;
- * can be {@code null}.
+ * @param caller the class for which the logger is being requested.
*
* @return a {@link Logger logger} suitable for the given caller's
* use.
@@ -1831,7 +1830,7 @@
lineSeparator = props.getProperty("line.separator");
- sun.misc.Version.init();
+ VersionProps.init();
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/VersionProps.java.template Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1999, 2016, 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 java.lang;
+
+import java.io.PrintStream;
+
+class VersionProps {
+
+
+ private static final String launcher_name =
+ "@@LAUNCHER_NAME@@";
+
+ private static final String java_version =
+ "@@VERSION_SHORT@@";
+
+ private static final String java_runtime_name =
+ "@@RUNTIME_NAME@@";
+
+ private static final String java_runtime_version =
+ "@@VERSION_STRING@@";
+
+ static {
+ init();
+ }
+
+ public static void init() {
+ System.setProperty("java.version", java_version);
+ System.setProperty("java.runtime.version", java_runtime_version);
+ System.setProperty("java.runtime.name", java_runtime_name);
+ }
+
+ /**
+ * In case you were wondering this method is called by java -version.
+ * Sad that it prints to stderr; would be nicer if default printed on
+ * stdout.
+ */
+ public static void print() {
+ print(System.err);
+ }
+
+ /**
+ * This is the same as print except that it adds an extra line-feed
+ * at the end, typically used by the -showversion in the launcher
+ */
+ public static void println() {
+ print(System.err);
+ System.err.println();
+ }
+
+ /**
+ * Give a stream, it will print version info on it.
+ */
+ public static void print(PrintStream ps) {
+ boolean isHeadless = false;
+
+ /* Report that we're running headless if the property is true */
+ String headless = System.getProperty("java.awt.headless");
+ if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
+ isHeadless = true;
+ }
+
+ /* First line: platform version. */
+ ps.println(launcher_name + " version \"" + java_version + "\"");
+
+ /* Second line: runtime version (ie, libraries). */
+
+ String jdk_debug_level = System.getProperty("jdk.debug", "release");
+ /* Debug level is not printed for "release" builds */
+ if ("release".equals(jdk_debug_level)) {
+ jdk_debug_level = "";
+ } else {
+ jdk_debug_level = jdk_debug_level + " ";
+ }
+
+ ps.print(java_runtime_name + " (" + jdk_debug_level + "build " + java_runtime_version);
+
+ if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
+ // embedded builds report headless state
+ ps.print(", headless");
+ }
+ ps.println(')');
+
+ /* Third line: JVM information. */
+ String java_vm_name = System.getProperty("java.vm.name");
+ String java_vm_version = System.getProperty("java.vm.version");
+ String java_vm_info = System.getProperty("java.vm.info");
+ ps.println(java_vm_name + " (" + jdk_debug_level + "build " + java_vm_version + ", " +
+ java_vm_info + ")");
+ }
+
+}
\ No newline at end of file
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Mar 03 12:49:12 2016 -0800
@@ -3268,12 +3268,17 @@
* <li>This list of types is called the "common prefix".
* </ol>
* <p>
- * <em>Step 1B: Determine loop parameters.</em><ol type="a">
- * <li>Examine init function parameter lists.
- * <li>Omitted init functions are deemed to have {@code null} parameter lists.
- * <li>All init function parameter lists must be effectively identical.
- * <li>The longest parameter list (which is necessarily unique) is called the "common suffix".
+ * <em>Step 1B: Determine loop parameters.</em><ul>
+ * <li><b>If at least one init function is given,</b><ol type="a">
+ * <li>Examine init function parameter lists.
+ * <li>Omitted init functions are deemed to have {@code null} parameter lists.
+ * <li>All init function parameter lists must be effectively identical.
+ * <li>The longest parameter list (which is necessarily unique) is called the "common suffix".
* </ol>
+ * <li><b>If no init function is given,</b><ol type="a">
+ * <li>Examine the suffixes of the step, pred, and fini parameter lists, after removing the "common prefix".
+ * <li>The longest of these suffixes is taken as the "common suffix".
+ * </ol></ul>
* <p>
* <em>Step 1C: Determine loop return type.</em><ol type="a">
* <li>Examine fini function return types, disregarding omitted fini functions.
@@ -3286,9 +3291,6 @@
* <li>Every non-omitted pred function must have a {@code boolean} return type.
* </ol>
* <p>
- * (Implementation Note: Steps 1A, 1B, 1C, 1D are logically independent of each other, and may be performed in any
- * order.)
- * <p>
* <em>Step 2: Determine parameter lists.</em><ol type="a">
* <li>The parameter list for the resulting loop handle will be the "common suffix".
* <li>The parameter list for init functions will be adjusted to the "common suffix". (Note that their parameter
@@ -3375,10 +3377,10 @@
* <blockquote><pre>{@code
* // iterative implementation of the factorial function as a loop handle
* static int one(int k) { return 1; }
- * int inc(int i, int acc, int k) { return i + 1; }
- * int mult(int i, int acc, int k) { return i * acc; }
- * boolean pred(int i, int acc, int k) { return i < k; }
- * int fin(int i, int acc, int k) { return acc; }
+ * static int inc(int i, int acc, int k) { return i + 1; }
+ * static int mult(int i, int acc, int k) { return i * acc; }
+ * static boolean pred(int i, int acc, int k) { return i < k; }
+ * static int fin(int i, int acc, int k) { return acc; }
* // assume MH_one, MH_inc, MH_mult, MH_pred, and MH_fin are handles to the above methods
* // null initializer for counter, should initialize to 0
* MethodHandle[] counterClause = new MethodHandle[]{null, MH_inc};
@@ -3436,9 +3438,7 @@
collect(Collectors.toList());
// Step 1B: determine loop parameters.
- final List<Class<?>> empty = new ArrayList<>();
- final List<Class<?>> commonSuffix = init.stream().filter(Objects::nonNull).map(MethodHandle::type).
- map(MethodType::parameterList).reduce((p, q) -> p.size() >= q.size() ? p : q).orElse(empty);
+ final List<Class<?>> commonSuffix = buildCommonSuffix(init, step, pred, fini, commonPrefix.size());
checkLoop1b(init, commonSuffix);
// Step 1C: determine loop return type.
@@ -3520,15 +3520,15 @@
* @apiNote Example:
* <blockquote><pre>{@code
* // implement the zip function for lists as a loop handle
- * List<String> initZip(Iterator<String> a, Iterator<String> b) { return new ArrayList<>(); }
- * boolean zipPred(List<String> zip, Iterator<String> a, Iterator<String> b) { return a.hasNext() && b.hasNext(); }
- * List<String> zipStep(List<String> zip, Iterator<String> a, Iterator<String> b) {
+ * static List<String> initZip(Iterator<String> a, Iterator<String> b) { return new ArrayList<>(); }
+ * static boolean zipPred(List<String> zip, Iterator<String> a, Iterator<String> b) { return a.hasNext() && b.hasNext(); }
+ * static List<String> zipStep(List<String> zip, Iterator<String> a, Iterator<String> b) {
* zip.add(a.next());
* zip.add(b.next());
* return zip;
* }
* // assume MH_initZip, MH_zipPred, and MH_zipStep are handles to the above methods
- * MethodHandle loop = MethodHandles.doWhileLoop(MH_initZip, MH_zipStep, MH_zipPred);
+ * MethodHandle loop = MethodHandles.whileLoop(MH_initZip, MH_zipPred, MH_zipStep);
* List<String> a = Arrays.asList("a", "b", "c", "d");
* List<String> b = Arrays.asList("e", "f", "g", "h");
* List<String> zipped = Arrays.asList("a", "e", "b", "f", "c", "g", "d", "h");
@@ -3594,9 +3594,9 @@
* @apiNote Example:
* <blockquote><pre>{@code
* // int i = 0; while (i < limit) { ++i; } return i; => limit
- * int zero(int limit) { return 0; }
- * int step(int i, int limit) { return i + 1; }
- * boolean pred(int i, int limit) { return i < limit; }
+ * static int zero(int limit) { return 0; }
+ * static int step(int i, int limit) { return i + 1; }
+ * static boolean pred(int i, int limit) { return i < limit; }
* // assume MH_zero, MH_step, and MH_pred are handles to the above methods
* MethodHandle loop = MethodHandles.doWhileLoop(MH_zero, MH_step, MH_pred);
* assertEquals(23, loop.invoke(23));
@@ -3664,8 +3664,8 @@
* <blockquote><pre>{@code
* // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s;
* // => a variation on a well known theme
- * String start(String arg) { return arg; }
- * String step(int counter, String v, String arg) { return "na " + v; }
+ * static String start(String arg) { return arg; }
+ * static String step(int counter, String v, String arg) { return "na " + v; }
* // assume MH_start and MH_step are handles to the two methods above
* MethodHandle fit13 = MethodHandles.constant(int.class, 13);
* MethodHandle loop = MethodHandles.countedLoop(fit13, MH_start, MH_step);
@@ -3808,11 +3808,11 @@
* @apiNote Example:
* <blockquote><pre>{@code
* // reverse a list
- * List<String> reverseStep(String e, List<String> r, List<String> l) {
+ * static List<String> reverseStep(String e, List<String> r, List<String> l) {
* r.add(0, e);
* return r;
* }
- * List<String> newArrayList(List<String> l) { return new ArrayList<>(); }
+ * static List<String> newArrayList(List<String> l) { return new ArrayList<>(); }
* // assume MH_reverseStep, MH_newArrayList are handles to the above methods
* MethodHandle loop = MethodHandles.iteratedLoop(null, MH_newArrayList, MH_reverseStep);
* List<String> list = Arrays.asList("a", "b", "c", "d", "e");
@@ -4084,6 +4084,21 @@
}
}
+ private static List<Class<?>> buildCommonSuffix(List<MethodHandle> init, List<MethodHandle> step, List<MethodHandle> pred, List<MethodHandle> fini, int cpSize) {
+ final List<Class<?>> empty = List.of();
+ final List<MethodHandle> nonNullInits = init.stream().filter(Objects::nonNull).collect(Collectors.toList());
+ if (nonNullInits.isEmpty()) {
+ final List<Class<?>> longest = Stream.of(step, pred, fini).flatMap(List::stream).filter(Objects::nonNull).
+ // take only those that can contribute to a common suffix because they are longer than the prefix
+ map(MethodHandle::type).filter(t -> t.parameterCount() > cpSize).map(MethodType::parameterList).
+ reduce((p, q) -> p.size() >= q.size() ? p : q).orElse(empty);
+ return longest.size() == 0 ? empty : longest.subList(cpSize, longest.size());
+ } else {
+ return nonNullInits.stream().map(MethodHandle::type).map(MethodType::parameterList).
+ reduce((p, q) -> p.size() >= q.size() ? p : q).get();
+ }
+ }
+
private static void checkLoop1b(List<MethodHandle> init, List<Class<?>> commonSuffix) {
if (init.stream().filter(Objects::nonNull).map(MethodHandle::type).map(MethodType::parameterList).
anyMatch(pl -> !pl.equals(commonSuffix.subList(0, pl.size())))) {
@@ -4109,8 +4124,10 @@
}
private static void checkLoop2(List<MethodHandle> step, List<MethodHandle> pred, List<MethodHandle> fini, List<Class<?>> commonParameterSequence) {
+ final int cpSize = commonParameterSequence.size();
if (Stream.of(step, pred, fini).flatMap(List::stream).filter(Objects::nonNull).map(MethodHandle::type).
- map(MethodType::parameterList).anyMatch(pl -> !pl.equals(commonParameterSequence.subList(0, pl.size())))) {
+ map(MethodType::parameterList).
+ anyMatch(pl -> pl.size() > cpSize || !pl.equals(commonParameterSequence.subList(0, pl.size())))) {
throw newIllegalArgumentException("found non-effectively identical parameter type lists:\nstep: " + step +
"\npred: " + pred + "\nfini: " + fini + " (common parameter sequence: " + commonParameterSequence + ")");
}
--- a/jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java Thu Mar 03 12:49:12 2016 -0800
@@ -27,9 +27,7 @@
import java.io.FileDescriptor;
import java.io.IOException;
-import java.io.InterruptedIOException;
import java.util.Set;
-import java.util.HashSet;
/**
* Abstract datagram and multicast socket implementation base class.
@@ -352,32 +350,32 @@
}
}
- private static final Set<SocketOption<?>> dgSocketOptions =
- new HashSet<>();
+ private static final Set<SocketOption<?>> dgSocketOptions;
- private static final Set<SocketOption<?>> mcSocketOptions =
- new HashSet<>();
+ private static final Set<SocketOption<?>> mcSocketOptions;
static {
- dgSocketOptions.add(StandardSocketOptions.SO_SNDBUF);
- dgSocketOptions.add(StandardSocketOptions.SO_RCVBUF);
- dgSocketOptions.add(StandardSocketOptions.SO_REUSEADDR);
- dgSocketOptions.add(StandardSocketOptions.IP_TOS);
+ dgSocketOptions = Set.of(StandardSocketOptions.SO_SNDBUF,
+ StandardSocketOptions.SO_RCVBUF,
+ StandardSocketOptions.SO_REUSEADDR,
+ StandardSocketOptions.IP_TOS);
- mcSocketOptions.add(StandardSocketOptions.SO_SNDBUF);
- mcSocketOptions.add(StandardSocketOptions.SO_RCVBUF);
- mcSocketOptions.add(StandardSocketOptions.SO_REUSEADDR);
- mcSocketOptions.add(StandardSocketOptions.IP_TOS);
- mcSocketOptions.add(StandardSocketOptions.IP_MULTICAST_IF);
- mcSocketOptions.add(StandardSocketOptions.IP_MULTICAST_TTL);
- mcSocketOptions.add(StandardSocketOptions.IP_MULTICAST_LOOP);
- };
+ mcSocketOptions = Set.of(StandardSocketOptions.SO_SNDBUF,
+ StandardSocketOptions.SO_RCVBUF,
+ StandardSocketOptions.SO_REUSEADDR,
+ StandardSocketOptions.IP_TOS,
+ StandardSocketOptions.IP_MULTICAST_IF,
+ StandardSocketOptions.IP_MULTICAST_TTL,
+ StandardSocketOptions.IP_MULTICAST_LOOP);
+ }
/**
* Returns a set of SocketOptions supported by this impl
* and by this impl's socket (DatagramSocket or MulticastSocket)
*
* @return a Set of SocketOptions
+ *
+ * @since 9
*/
protected Set<SocketOption<?>> supportedOptions() {
if (getDatagramSocket() instanceof MulticastSocket) {
--- a/jdk/src/java.base/share/classes/java/net/SocketImpl.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/net/SocketImpl.java Thu Mar 03 12:49:12 2016 -0800
@@ -30,8 +30,6 @@
import java.io.OutputStream;
import java.io.FileDescriptor;
import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
/**
* The abstract class {@code SocketImpl} is a common superclass
@@ -445,31 +443,31 @@
}
}
- private static final Set<SocketOption<?>> socketOptions =
- new HashSet<>();
+ private static final Set<SocketOption<?>> socketOptions;
- private static final Set<SocketOption<?>> serverSocketOptions =
- new HashSet<>();
+ private static final Set<SocketOption<?>> serverSocketOptions;
static {
- socketOptions.add(StandardSocketOptions.SO_KEEPALIVE);
- socketOptions.add(StandardSocketOptions.SO_SNDBUF);
- socketOptions.add(StandardSocketOptions.SO_RCVBUF);
- socketOptions.add(StandardSocketOptions.SO_REUSEADDR);
- socketOptions.add(StandardSocketOptions.SO_LINGER);
- socketOptions.add(StandardSocketOptions.IP_TOS);
- socketOptions.add(StandardSocketOptions.TCP_NODELAY);
+ socketOptions = Set.of(StandardSocketOptions.SO_KEEPALIVE,
+ StandardSocketOptions.SO_SNDBUF,
+ StandardSocketOptions.SO_RCVBUF,
+ StandardSocketOptions.SO_REUSEADDR,
+ StandardSocketOptions.SO_LINGER,
+ StandardSocketOptions.IP_TOS,
+ StandardSocketOptions.TCP_NODELAY);
- serverSocketOptions.add(StandardSocketOptions.SO_RCVBUF);
- serverSocketOptions.add(StandardSocketOptions.SO_REUSEADDR);
- serverSocketOptions.add(StandardSocketOptions.IP_TOS);
- };
+ serverSocketOptions = Set.of(StandardSocketOptions.SO_RCVBUF,
+ StandardSocketOptions.SO_REUSEADDR,
+ StandardSocketOptions.IP_TOS);
+ }
/**
* Returns a set of SocketOptions supported by this impl
* and by this impl's socket (Socket or ServerSocket)
*
* @return a Set of SocketOptions
+ *
+ * @since 9
*/
protected Set<SocketOption<?>> supportedOptions() {
if (getSocket() != null) {
--- a/jdk/src/java.base/share/classes/java/nio/Bits.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/nio/Bits.java Thu Mar 03 12:49:12 2016 -0800
@@ -736,202 +736,9 @@
});
}
- // -- Bulk get/put acceleration --
-
// These numbers represent the point at which we have empirically
// determined that the average cost of a JNI call exceeds the expense
// of an element by element copy. These numbers may change over time.
static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6;
static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
-
- // This number limits the number of bytes to copy per call to Unsafe's
- // copyMemory method. A limit is imposed to allow for safepoint polling
- // during a large copy
- static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
-
- // These methods do no bounds checking. Verification that the copy will not
- // result in memory corruption should be done prior to invocation.
- // All positions and lengths are specified in bytes.
-
- /**
- * Copy from given source array to destination address.
- *
- * @param src
- * source array
- * @param srcBaseOffset
- * offset of first element of storage in source array
- * @param srcPos
- * offset within source array of the first element to read
- * @param dstAddr
- * destination address
- * @param length
- * number of bytes to copy
- */
- static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
- long dstAddr, long length)
- {
- long offset = srcBaseOffset + srcPos;
- while (length > 0) {
- long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
- unsafe.copyMemory(src, offset, null, dstAddr, size);
- length -= size;
- offset += size;
- dstAddr += size;
- }
- }
-
- /**
- * Copy from source address into given destination array.
- *
- * @param srcAddr
- * source address
- * @param dst
- * destination array
- * @param dstBaseOffset
- * offset of first element of storage in destination array
- * @param dstPos
- * offset within destination array of the first element to write
- * @param length
- * number of bytes to copy
- */
- static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
- long length)
- {
- long offset = dstBaseOffset + dstPos;
- while (length > 0) {
- long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
- unsafe.copyMemory(null, srcAddr, dst, offset, size);
- length -= size;
- srcAddr += size;
- offset += size;
- }
- }
-
- /**
- * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory
- *
- * @param src
- * the source array, must be a 16-bit primitive array type
- * @param srcPos
- * byte offset within source array of the first element to read
- * @param dstAddr
- * destination address
- * @param length
- * number of bytes to copy
- */
- static void copyFromCharArray(Object src, long srcPos, long dstAddr, long length) {
- unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2);
- }
-
- /**
- * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array
- *
- * @param srcAddr
- * source address
- * @param dst
- * destination array, must be a 16-bit primitive array type
- * @param dstPos
- * byte offset within the destination array of the first element to write
- * @param length
- * number of bytes to copy
- */
- static void copyToCharArray(long srcAddr, Object dst, long dstPos, long length) {
- unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2);
- }
-
- /**
- * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory
- *
- * @param src
- * the source array, must be a 16-bit primitive array type
- * @param srcPos
- * byte offset within source array of the first element to read
- * @param dstAddr
- * destination address
- * @param length
- * number of bytes to copy
- */
- static void copyFromShortArray(Object src, long srcPos, long dstAddr, long length) {
- unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2);
- }
-
- /**
- * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array
- *
- * @param srcAddr
- * source address
- * @param dst
- * destination array, must be a 16-bit primitive array type
- * @param dstPos
- * byte offset within the destination array of the first element to write
- * @param length
- * number of bytes to copy
- */
- static void copyToShortArray(long srcAddr, Object dst, long dstPos, long length) {
- unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2);
- }
-
- /**
- * Copy and unconditionally byte swap 32 bit elements from a heap array to off-heap memory
- *
- * @param src
- * the source array, must be a 32-bit primitive array type
- * @param srcPos
- * byte offset within source array of the first element to read
- * @param dstAddr
- * destination address
- * @param length
- * number of bytes to copy
- */
- static void copyFromIntArray(Object src, long srcPos, long dstAddr, long length) {
- unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 4);
- }
-
- /**
- * Copy and unconditionally byte swap 32 bit elements from off-heap memory to a heap array
- *
- * @param srcAddr
- * source address
- * @param dst
- * destination array, must be a 32-bit primitive array type
- * @param dstPos
- * byte offset within the destination array of the first element to write
- * @param length
- * number of bytes to copy
- */
- static void copyToIntArray(long srcAddr, Object dst, long dstPos, long length) {
- unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 4);
- }
-
- /**
- * Copy and unconditionally byte swap 64 bit elements from a heap array to off-heap memory
- *
- * @param src
- * the source array, must be a 64-bit primitive array type
- * @param srcPos
- * byte offset within source array of the first element to read
- * @param dstAddr
- * destination address
- * @param length
- * number of bytes to copy
- */
- static void copyFromLongArray(Object src, long srcPos, long dstAddr, long length) {
- unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 8);
- }
-
- /**
- * Copy and unconditionally byte swap 64 bit elements from off-heap memory to a heap array
- *
- * @param srcAddr
- * source address
- * @param dst
- * destination array, must be a 64-bit primitive array type
- * @param dstPos
- * byte offset within the destination array of the first element to write
- * @param length
- * number of bytes to copy
- */
- static void copyToLongArray(long srcAddr, Object dst, long dstPos, long length) {
- unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 8);
- }
}
--- a/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -270,16 +270,22 @@
if (length > rem)
throw new BufferUnderflowException();
+ long dstOffset = arrayBaseOffset + ((long)offset << $LG_BYTES_PER_VALUE$);
#if[!byte]
if (order() != ByteOrder.nativeOrder())
- Bits.copyTo$Memtype$Array(ix(pos), dst,
- (long)offset << $LG_BYTES_PER_VALUE$,
- (long)length << $LG_BYTES_PER_VALUE$);
+ unsafe.copySwapMemory(null,
+ ix(pos),
+ dst,
+ dstOffset,
+ (long)length << $LG_BYTES_PER_VALUE$,
+ (long)1 << $LG_BYTES_PER_VALUE$);
else
#end[!byte]
- Bits.copyToArray(ix(pos), dst, arrayBaseOffset,
- (long)offset << $LG_BYTES_PER_VALUE$,
- (long)length << $LG_BYTES_PER_VALUE$);
+ unsafe.copyMemory(null,
+ ix(pos),
+ dst,
+ dstOffset,
+ (long)length << $LG_BYTES_PER_VALUE$);
position(pos + length);
} else {
super.get(dst, offset, length);
@@ -362,18 +368,22 @@
if (length > rem)
throw new BufferOverflowException();
+ long srcOffset = arrayBaseOffset + ((long)offset << $LG_BYTES_PER_VALUE$);
#if[!byte]
if (order() != ByteOrder.nativeOrder())
- Bits.copyFrom$Memtype$Array(src,
- (long)offset << $LG_BYTES_PER_VALUE$,
- ix(pos),
- (long)length << $LG_BYTES_PER_VALUE$);
+ unsafe.copySwapMemory(src,
+ srcOffset,
+ null,
+ ix(pos),
+ (long)length << $LG_BYTES_PER_VALUE$,
+ (long)1 << $LG_BYTES_PER_VALUE$);
else
#end[!byte]
- Bits.copyFromArray(src, arrayBaseOffset,
- (long)offset << $LG_BYTES_PER_VALUE$,
- ix(pos),
- (long)length << $LG_BYTES_PER_VALUE$);
+ unsafe.copyMemory(src,
+ srcOffset,
+ null,
+ ix(pos),
+ (long)length << $LG_BYTES_PER_VALUE$);
position(pos + length);
} else {
super.put(src, offset, length);
--- a/jdk/src/java.base/share/classes/java/util/SplittableRandom.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/SplittableRandom.java Thu Mar 03 12:49:12 2016 -0800
@@ -219,12 +219,20 @@
return seed += gamma;
}
+ // IllegalArgumentException messages
+ static final String BAD_BOUND = "bound must be positive";
+ static final String BAD_RANGE = "bound must be greater than origin";
+ static final String BAD_SIZE = "size must be non-negative";
+
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(initialSeed());
+ private static final AtomicLong defaultGen
+ = new AtomicLong(mix64(System.currentTimeMillis()) ^
+ mix64(System.nanoTime()));
- private static long initialSeed() {
+ // at end of <clinit> to survive static initialization circularity
+ static {
if (java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Boolean>() {
public Boolean run() {
@@ -234,17 +242,10 @@
long s = (long)seedBytes[0] & 0xffL;
for (int i = 1; i < 8; ++i)
s = (s << 8) | ((long)seedBytes[i] & 0xffL);
- return s;
+ defaultGen.set(s);
}
- return (mix64(System.currentTimeMillis()) ^
- mix64(System.nanoTime()));
}
- // IllegalArgumentException messages
- static final String BAD_BOUND = "bound must be positive";
- static final String BAD_RANGE = "bound must be greater than origin";
- static final String BAD_SIZE = "size must be non-negative";
-
/*
* Internal versions of nextX methods used by streams, as well as
* the public nextX(origin, bound) methods. These exist mainly to
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java Thu Mar 03 12:49:12 2016 -0800
@@ -125,53 +125,6 @@
* but we provide identical statistical properties.
*/
- /** Generates per-thread initialization/probe field */
- private static final AtomicInteger probeGenerator = new AtomicInteger();
-
- /**
- * The next seed for default constructors.
- */
- private static final AtomicLong seeder = new AtomicLong(initialSeed());
-
- private static long initialSeed() {
- if (java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Boolean>() {
- public Boolean run() {
- return Boolean.getBoolean("java.util.secureRandomSeed");
- }})) {
- byte[] seedBytes = java.security.SecureRandom.getSeed(8);
- long s = (long)seedBytes[0] & 0xffL;
- for (int i = 1; i < 8; ++i)
- s = (s << 8) | ((long)seedBytes[i] & 0xffL);
- return s;
- }
- return (mix64(System.currentTimeMillis()) ^
- mix64(System.nanoTime()));
- }
-
- /**
- * The seed increment.
- */
- private static final long GAMMA = 0x9e3779b97f4a7c15L;
-
- /**
- * The increment for generating probe values.
- */
- private static final int PROBE_INCREMENT = 0x9e3779b9;
-
- /**
- * The increment of seeder per new instance.
- */
- private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
-
- // Constants from SplittableRandom
- private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
- private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24)
-
- /** Rarely-used holder for the second of a pair of Gaussians */
- private static final ThreadLocal<Double> nextLocalGaussian =
- new ThreadLocal<>();
-
private static long mix64(long z) {
z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
@@ -194,9 +147,6 @@
initialized = true; // false during super() call
}
- /** The common ThreadLocalRandom */
- static final ThreadLocalRandom instance = new ThreadLocalRandom();
-
/**
* Initialize Thread fields for the current thread. Called only
* when Thread.threadLocalRandomProbe is zero, indicating that a
@@ -248,11 +198,6 @@
return (int)(mix64(nextSeed()) >>> (64 - bits));
}
- // IllegalArgumentException messages
- static final String BAD_BOUND = "bound must be positive";
- static final String BAD_RANGE = "bound must be greater than origin";
- static final String BAD_SIZE = "size must be non-negative";
-
/**
* The form of nextLong used by LongStream Spliterators. If
* origin is greater than bound, acts as unbounded form of
@@ -1050,6 +995,32 @@
return current();
}
+ // Static initialization
+
+ /**
+ * The seed increment.
+ */
+ private static final long GAMMA = 0x9e3779b97f4a7c15L;
+
+ /**
+ * The increment for generating probe values.
+ */
+ private static final int PROBE_INCREMENT = 0x9e3779b9;
+
+ /**
+ * The increment of seeder per new instance.
+ */
+ private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
+
+ // Constants from SplittableRandom
+ private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
+ private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24)
+
+ // IllegalArgumentException messages
+ static final String BAD_BOUND = "bound must be positive";
+ static final String BAD_RANGE = "bound must be greater than origin";
+ static final String BAD_SIZE = "size must be non-negative";
+
// Unsafe mechanics
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long SEED;
@@ -1067,4 +1038,36 @@
throw new Error(e);
}
}
+
+ /** Rarely-used holder for the second of a pair of Gaussians */
+ private static final ThreadLocal<Double> nextLocalGaussian =
+ new ThreadLocal<>();
+
+ /** Generates per-thread initialization/probe field */
+ private static final AtomicInteger probeGenerator = new AtomicInteger();
+
+ /** The common ThreadLocalRandom */
+ static final ThreadLocalRandom instance = new ThreadLocalRandom();
+
+ /**
+ * The next seed for default constructors.
+ */
+ private static final AtomicLong seeder
+ = new AtomicLong(mix64(System.currentTimeMillis()) ^
+ mix64(System.nanoTime()));
+
+ // at end of <clinit> to survive static initialization circularity
+ static {
+ if (java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Boolean>() {
+ public Boolean run() {
+ return Boolean.getBoolean("java.util.secureRandomSeed");
+ }})) {
+ byte[] seedBytes = java.security.SecureRandom.getSeed(8);
+ long s = (long)seedBytes[0] & 0xffL;
+ for (int i = 1; i < 8; ++i)
+ s = (s << 8) | ((long)seedBytes[i] & 0xffL);
+ seeder.set(s);
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java Thu Mar 03 12:49:12 2016 -0800
@@ -158,7 +158,7 @@
RUNTIME_VERSION = AccessController.doPrivileged(
new PrivilegedAction<Integer>() {
public Integer run() {
- Integer v = sun.misc.Version.jdkMajorVersion(); // fixme when JEP 223 Version integrated
+ Integer v = jdk.Version.current().major();
Integer i = Integer.getInteger("jdk.util.jar.version", v);
i = i < 0 ? 0 : i;
return i > v ? v : i;
@@ -359,7 +359,7 @@
}
private boolean runtimeVersionExists() {
- int version = sun.misc.Version.jdkMajorVersion(); // fixme when JEP 223 integrated
+ int version = jdk.Version.current().major();
try {
Release.valueOf(version);
return true;
--- a/jdk/src/java.base/share/classes/java/util/stream/AbstractPipeline.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/AbstractPipeline.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -327,6 +327,8 @@
@Override
@SuppressWarnings("unchecked")
public S onClose(Runnable closeHandler) {
+ if (linkedOrConsumed)
+ throw new IllegalStateException(MSG_STREAM_LINKED);
Objects.requireNonNull(closeHandler);
Runnable existingHandler = sourceStage.sourceCloseAction;
sourceStage.sourceCloseAction =
--- a/jdk/src/java.base/share/classes/java/util/stream/DoubleStream.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/DoubleStream.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -949,24 +949,100 @@
*/
public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
Objects.requireNonNull(f);
- final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
- double t = seed;
+ Spliterator.OfDouble spliterator = new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
+ double prev;
+ boolean started;
@Override
- public boolean hasNext() {
+ public boolean tryAdvance(DoubleConsumer action) {
+ Objects.requireNonNull(action);
+ double t;
+ if (started)
+ t = f.applyAsDouble(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ action.accept(prev = t);
+ return true;
+ }
+ };
+ return StreamSupport.doubleStream(spliterator, false);
+ }
+
+ /**
+ * Returns a sequential ordered {@code DoubleStream} produced by iterative
+ * application of a function to an initial element, conditioned on
+ * satisfying the supplied predicate. The stream terminates as soon as
+ * the predicate returns false.
+ *
+ * <p>
+ * {@code DoubleStream.iterate} should produce the same sequence of
+ * elements as produced by the corresponding for-loop:
+ * <pre>{@code
+ * for (double index=seed; predicate.test(index); index = f.apply(index)) {
+ * ...
+ * }
+ * }</pre>
+ *
+ * <p>
+ * The resulting sequence may be empty if the predicate does not hold on
+ * the seed value. Otherwise the first element will be the supplied seed
+ * value, the next element (if present) will be the result of applying the
+ * function f to the seed value, and so on iteratively until the predicate
+ * indicates that the stream should terminate.
+ *
+ * @param seed the initial element
+ * @param predicate a predicate to apply to elements to determine when the
+ * stream must terminate.
+ * @param f a function to be applied to the previous element to produce
+ * a new element
+ * @return a new sequential {@code DoubleStream}
+ * @since 9
+ */
+ public static DoubleStream iterate(double seed, DoublePredicate predicate, DoubleUnaryOperator f) {
+ Objects.requireNonNull(f);
+ Objects.requireNonNull(predicate);
+ Spliterator.OfDouble spliterator = new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
+ double prev;
+ boolean started, finished;
+
+ @Override
+ public boolean tryAdvance(DoubleConsumer action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return false;
+ double t;
+ if (started)
+ t = f.applyAsDouble(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ if (!predicate.test(t)) {
+ finished = true;
+ return false;
+ }
+ action.accept(prev = t);
return true;
}
@Override
- public double nextDouble() {
- double v = t;
- t = f.applyAsDouble(t);
- return v;
+ public void forEachRemaining(DoubleConsumer action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return;
+ finished = true;
+ double t = started ? f.applyAsDouble(prev) : seed;
+ while (predicate.test(t)) {
+ action.accept(t);
+ t = f.applyAsDouble(t);
+ }
}
};
- return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
- iterator,
- Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
+ return StreamSupport.doubleStream(spliterator, false);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/stream/IntStream.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/IntStream.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -885,28 +885,104 @@
* @param seed the initial element
* @param f a function to be applied to the previous element to produce
* a new element
- * @return A new sequential {@code IntStream}
+ * @return a new sequential {@code IntStream}
*/
public static IntStream iterate(final int seed, final IntUnaryOperator f) {
Objects.requireNonNull(f);
- final PrimitiveIterator.OfInt iterator = new PrimitiveIterator.OfInt() {
- int t = seed;
+ Spliterator.OfInt spliterator = new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
+ int prev;
+ boolean started;
@Override
- public boolean hasNext() {
+ public boolean tryAdvance(IntConsumer action) {
+ Objects.requireNonNull(action);
+ int t;
+ if (started)
+ t = f.applyAsInt(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ action.accept(prev = t);
+ return true;
+ }
+ };
+ return StreamSupport.intStream(spliterator, false);
+ }
+
+ /**
+ * Returns a sequential ordered {@code IntStream} produced by iterative
+ * application of a function to an initial element, conditioned on
+ * satisfying the supplied predicate. The stream terminates as soon as
+ * the predicate returns false.
+ *
+ * <p>
+ * {@code IntStream.iterate} should produce the same sequence of elements
+ * as produced by the corresponding for-loop:
+ * <pre>{@code
+ * for (int index=seed; predicate.test(index); index = f.apply(index)) {
+ * ...
+ * }
+ * }</pre>
+ *
+ * <p>
+ * The resulting sequence may be empty if the predicate does not hold on
+ * the seed value. Otherwise the first element will be the supplied seed
+ * value, the next element (if present) will be the result of applying the
+ * function f to the seed value, and so on iteratively until the predicate
+ * indicates that the stream should terminate.
+ *
+ * @param seed the initial element
+ * @param predicate a predicate to apply to elements to determine when the
+ * stream must terminate.
+ * @param f a function to be applied to the previous element to produce
+ * a new element
+ * @return a new sequential {@code IntStream}
+ * @since 9
+ */
+ public static IntStream iterate(int seed, IntPredicate predicate, IntUnaryOperator f) {
+ Objects.requireNonNull(f);
+ Objects.requireNonNull(predicate);
+ Spliterator.OfInt spliterator = new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
+ int prev;
+ boolean started, finished;
+
+ @Override
+ public boolean tryAdvance(IntConsumer action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return false;
+ int t;
+ if (started)
+ t = f.applyAsInt(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ if (!predicate.test(t)) {
+ finished = true;
+ return false;
+ }
+ action.accept(prev = t);
return true;
}
@Override
- public int nextInt() {
- int v = t;
- t = f.applyAsInt(t);
- return v;
+ public void forEachRemaining(IntConsumer action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return;
+ finished = true;
+ int t = started ? f.applyAsInt(prev) : seed;
+ while (predicate.test(t)) {
+ action.accept(t);
+ t = f.applyAsInt(t);
+ }
}
};
- return StreamSupport.intStream(Spliterators.spliteratorUnknownSize(
- iterator,
- Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
+ return StreamSupport.intStream(spliterator, false);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/stream/LongStream.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/LongStream.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -879,24 +879,100 @@
*/
public static LongStream iterate(final long seed, final LongUnaryOperator f) {
Objects.requireNonNull(f);
- final PrimitiveIterator.OfLong iterator = new PrimitiveIterator.OfLong() {
- long t = seed;
+ Spliterator.OfLong spliterator = new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
+ long prev;
+ boolean started;
@Override
- public boolean hasNext() {
+ public boolean tryAdvance(LongConsumer action) {
+ Objects.requireNonNull(action);
+ long t;
+ if (started)
+ t = f.applyAsLong(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ action.accept(prev = t);
+ return true;
+ }
+ };
+ return StreamSupport.longStream(spliterator, false);
+ }
+
+ /**
+ * Returns a sequential ordered {@code LongStream} produced by iterative
+ * application of a function to an initial element, conditioned on
+ * satisfying the supplied predicate. The stream terminates as soon as
+ * the predicate returns false.
+ *
+ * <p>
+ * {@code LongStream.iterate} should produce the same sequence of elements
+ * as produced by the corresponding for-loop:
+ * <pre>{@code
+ * for (long index=seed; predicate.test(index); index = f.apply(index)) {
+ * ...
+ * }
+ * }</pre>
+ *
+ * <p>
+ * The resulting sequence may be empty if the predicate does not hold on
+ * the seed value. Otherwise the first element will be the supplied seed
+ * value, the next element (if present) will be the result of applying the
+ * function f to the seed value, and so on iteratively until the predicate
+ * indicates that the stream should terminate.
+ *
+ * @param seed the initial element
+ * @param predicate a predicate to apply to elements to determine when the
+ * stream must terminate.
+ * @param f a function to be applied to the previous element to produce
+ * a new element
+ * @return a new sequential {@code LongStream}
+ * @since 9
+ */
+ public static LongStream iterate(long seed, LongPredicate predicate, LongUnaryOperator f) {
+ Objects.requireNonNull(f);
+ Objects.requireNonNull(predicate);
+ Spliterator.OfLong spliterator = new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
+ long prev;
+ boolean started, finished;
+
+ @Override
+ public boolean tryAdvance(LongConsumer action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return false;
+ long t;
+ if (started)
+ t = f.applyAsLong(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ if (!predicate.test(t)) {
+ finished = true;
+ return false;
+ }
+ action.accept(prev = t);
return true;
}
@Override
- public long nextLong() {
- long v = t;
- t = f.applyAsLong(t);
- return v;
+ public void forEachRemaining(LongConsumer action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return;
+ finished = true;
+ long t = started ? f.applyAsLong(prev) : seed;
+ while (predicate.test(t)) {
+ action.accept(t);
+ t = f.applyAsLong(t);
+ }
}
};
- return StreamSupport.longStream(Spliterators.spliteratorUnknownSize(
- iterator,
- Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
+ return StreamSupport.longStream(spliterator, false);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/stream/Stream.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/Stream.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -29,7 +29,6 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
-import java.util.Iterator;
import java.util.Objects;
import java.util.Optional;
import java.util.Spliterator;
@@ -1185,23 +1184,103 @@
*/
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
Objects.requireNonNull(f);
- final Iterator<T> iterator = new Iterator<T>() {
- @SuppressWarnings("unchecked")
- T t = (T) Streams.NONE;
+ Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE) {
+ T prev;
+ boolean started;
@Override
- public boolean hasNext() {
+ public boolean tryAdvance(Consumer<? super T> action) {
+ Objects.requireNonNull(action);
+ T t;
+ if (started)
+ t = f.apply(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ action.accept(prev = t);
+ return true;
+ }
+ };
+ return StreamSupport.stream(spliterator, false);
+ }
+
+ /**
+ * Returns a sequential ordered {@code Stream} produced by iterative
+ * application of a function to an initial element, conditioned on
+ * satisfying the supplied predicate. The stream terminates as soon as
+ * the predicate returns false.
+ *
+ * <p>
+ * {@code Stream.iterate} should produce the same sequence of elements as
+ * produced by the corresponding for-loop:
+ * <pre>{@code
+ * for (T index=seed; predicate.test(index); index = f.apply(index)) {
+ * ...
+ * }
+ * }</pre>
+ *
+ * <p>
+ * The resulting sequence may be empty if the predicate does not hold on
+ * the seed value. Otherwise the first element will be the supplied seed
+ * value, the next element (if present) will be the result of applying the
+ * function f to the seed value, and so on iteratively until the predicate
+ * indicates that the stream should terminate.
+ *
+ * @param <T> the type of stream elements
+ * @param seed the initial element
+ * @param predicate a predicate to apply to elements to determine when the
+ * stream must terminate.
+ * @param f a function to be applied to the previous element to produce
+ * a new element
+ * @return a new sequential {@code Stream}
+ * @since 9
+ */
+ public static<T> Stream<T> iterate(T seed, Predicate<? super T> predicate, UnaryOperator<T> f) {
+ Objects.requireNonNull(f);
+ Objects.requireNonNull(predicate);
+ Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE) {
+ T prev;
+ boolean started, finished;
+
+ @Override
+ public boolean tryAdvance(Consumer<? super T> action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return false;
+ T t;
+ if (started)
+ t = f.apply(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ if (!predicate.test(t)) {
+ prev = null;
+ finished = true;
+ return false;
+ }
+ action.accept(prev = t);
return true;
}
@Override
- public T next() {
- return t = (t == Streams.NONE) ? seed : f.apply(t);
+ public void forEachRemaining(Consumer<? super T> action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return;
+ finished = true;
+ T t = started ? f.apply(prev) : seed;
+ prev = null;
+ while (predicate.test(t)) {
+ action.accept(t);
+ t = f.apply(t);
+ }
}
};
- return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
- iterator,
- Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
+ return StreamSupport.stream(spliterator, false);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/stream/Streams.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/Streams.java Thu Mar 03 12:49:12 2016 -0800
@@ -49,14 +49,6 @@
}
/**
- * An object instance representing no value, that cannot be an actual
- * data element of a stream. Used when processing streams that can contain
- * {@code null} elements to distinguish between a {@code null} value and no
- * value.
- */
- static final Object NONE = new Object();
-
- /**
* An {@code int} range spliterator.
*/
static final class RangeIntSpliterator implements Spliterator.OfInt {
--- a/jdk/src/java.base/share/classes/jdk/Version.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/jdk/Version.java Thu Mar 03 12:49:12 2016 -0800
@@ -28,10 +28,10 @@
import java.math.BigInteger;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -208,11 +208,10 @@
+ s + "'");
// $VNUM is a dot-separated list of integers of arbitrary length
- version
- = Collections.unmodifiableList(
- Arrays.stream(m.group(VNUM_GROUP).split("\\."))
- .map(Integer::parseInt)
- .collect(Collectors.toList()));
+ List<Integer> list = new ArrayList<>();
+ for (String i : m.group(VNUM_GROUP).split("\\."))
+ list.add(Integer.parseInt(i));
+ version = Collections.unmodifiableList(list);
pre = Optional.ofNullable(m.group(PRE_GROUP));
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Thu Mar 03 12:49:12 2016 -0800
@@ -118,6 +118,8 @@
}
public static JavaNetInetAddressAccess getJavaNetInetAddressAccess() {
+ if (javaNetInetAddressAccess == null)
+ unsafe.ensureClassInitialized(java.net.InetAddress.class);
return javaNetInetAddressAccess;
}
--- a/jdk/src/java.base/share/classes/sun/misc/Version.java.template Thu Mar 03 12:25:57 2016 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-package sun.misc;
-import java.io.PrintStream;
-
-public class Version {
-
-
- private static final String launcher_name =
- "@@LAUNCHER_NAME@@";
-
- private static final String java_version =
- "@@VERSION_SHORT@@";
-
- private static final String java_runtime_name =
- "@@RUNTIME_NAME@@";
-
- private static final String java_runtime_version =
- "@@VERSION_STRING@@";
-
- static {
- init();
- }
-
- public static void init() {
- System.setProperty("java.version", java_version);
- System.setProperty("java.runtime.version", java_runtime_version);
- System.setProperty("java.runtime.name", java_runtime_name);
- }
-
- private static boolean versionsInitialized = false;
- private static int jvm_major_version = 0;
- private static int jvm_minor_version = 0;
- private static int jvm_security_version = 0;
- private static int jvm_patch_version = 0;
- private static int jvm_build_number = 0;
- private static int jdk_major_version = 0;
- private static int jdk_minor_version = 0;
- private static int jdk_security_version = 0;
- private static int jdk_patch_version = 0;
- private static int jdk_build_number = 0;
-
- /**
- * In case you were wondering this method is called by java -version.
- * Sad that it prints to stderr; would be nicer if default printed on
- * stdout.
- */
- public static void print() {
- print(System.err);
- }
-
- /**
- * This is the same as print except that it adds an extra line-feed
- * at the end, typically used by the -showversion in the launcher
- */
- public static void println() {
- print(System.err);
- System.err.println();
- }
-
- /**
- * Give a stream, it will print version info on it.
- */
- public static void print(PrintStream ps) {
- boolean isHeadless = false;
-
- /* Report that we're running headless if the property is true */
- String headless = System.getProperty("java.awt.headless");
- if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
- isHeadless = true;
- }
-
- /* First line: platform version. */
- ps.println(launcher_name + " version \"" + java_version + "\"");
-
- /* Second line: runtime version (ie, libraries). */
-
- String jdk_debug_level = System.getProperty("jdk.debug", "release");
- /* Debug level is not printed for "release" builds */
- if ("release".equals(jdk_debug_level)) {
- jdk_debug_level = "";
- } else {
- jdk_debug_level = jdk_debug_level + " ";
- }
-
- ps.print(java_runtime_name + " (" + jdk_debug_level + "build " + java_runtime_version);
-
- if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
- // embedded builds report headless state
- ps.print(", headless");
- }
- ps.println(')');
-
- /* Third line: JVM information. */
- String java_vm_name = System.getProperty("java.vm.name");
- String java_vm_version = System.getProperty("java.vm.version");
- String java_vm_info = System.getProperty("java.vm.info");
- ps.println(java_vm_name + " (" + jdk_debug_level + "build " + java_vm_version + ", " +
- java_vm_info + ")");
- }
-
-
- /**
- * Returns the major version of the running JVM.
- * @return the major version of the running JVM
- * @since 1.6
- */
- public static synchronized int jvmMajorVersion() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jvm_major_version;
- }
-
- /**
- * Returns the minor version of the running JVM.
- * @return the minor version of the running JVM
- * @since 1.6
- */
- public static synchronized int jvmMinorVersion() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jvm_minor_version;
- }
-
-
- /**
- * Returns the security version of the running JVM.
- * @return the security version of the running JVM
- * @since 9
- */
- public static synchronized int jvmSecurityVersion() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jvm_security_version;
- }
-
- /**
- * Returns the patch release version of the running JVM.
- * @return the patch release version of the running JVM
- * @since 9
- */
- public static synchronized int jvmPatchVersion() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jvm_patch_version;
- }
-
- /**
- * Returns the build number of the running JVM.
- * @return the build number of the running JVM
- * @since 1.6
- */
- public static synchronized int jvmBuildNumber() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jvm_build_number;
- }
-
- /**
- * Returns the major version of the running JDK.
- * @return the major version of the running JDK
- * @since 1.6
- */
- public static synchronized int jdkMajorVersion() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jdk_major_version;
- }
-
- /**
- * Returns the minor version of the running JDK.
- * @return the minor version of the running JDK
- * @since 1.6
- */
- public static synchronized int jdkMinorVersion() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jdk_minor_version;
- }
-
- /**
- * Returns the security version of the running JDK.
- * @return the security version of the running JDK
- * @since 9
- */
- public static synchronized int jdkSecurityVersion() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jdk_security_version;
- }
-
- /**
- * Returns the patch release version of the running JDK.
- * @return the patch release version of the running JDK
- * @since 9
- */
- public static synchronized int jdkPatchVersion() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jdk_patch_version;
- }
-
- /**
- * Returns the build number of the running JDK.
- * @return the build number of the running JDK
- * @since 1.6
- */
- public static synchronized int jdkBuildNumber() {
- if (!versionsInitialized) {
- initVersions();
- }
- return jdk_build_number;
- }
-
- private static synchronized void initVersions() {
- if (versionsInitialized) {
- return;
- }
- if (!getJvmVersionInfo()) {
- throw new InternalError("Unable to obtain JVM version info");
- }
- getJdkVersionInfo();
- versionsInitialized = true;
- }
-
- // Gets the JVM version info if available and sets the jvm_*_version fields
- // and its capabilities.
- private static native boolean getJvmVersionInfo();
- private static native void getJdkVersionInfo();
-}
-
-// Help Emacs a little because this file doesn't end in .java.
-//
-// Local Variables: ***
-// mode: java ***
-// End: ***
--- a/jdk/src/java.base/share/native/libjava/Version.c Thu Mar 03 12:25:57 2016 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2005, 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 "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jdk_util.h"
-
-#include "sun_misc_Version.h"
-
-static void setStaticIntField(JNIEnv* env, jclass cls, const char* name, jint value)
-{
- jfieldID fid;
- fid = (*env)->GetStaticFieldID(env, cls, name, "I");
- if (fid != 0) {
- (*env)->SetStaticIntField(env, cls, fid, value);
- }
-}
-
-typedef void (JNICALL *GetJvmVersionInfo_fp)(JNIEnv*, jvm_version_info*, size_t);
-
-JNIEXPORT jboolean JNICALL
-Java_sun_misc_Version_getJvmVersionInfo(JNIEnv *env, jclass cls)
-{
- jvm_version_info info;
- GetJvmVersionInfo_fp func_p;
-
- if (!JDK_InitJvmHandle()) {
- JNU_ThrowInternalError(env, "Handle for JVM not found for symbol lookup");
- return JNI_FALSE;
- }
- func_p = (GetJvmVersionInfo_fp) JDK_FindJvmEntry("JVM_GetVersionInfo");
- if (func_p == NULL) {
- return JNI_FALSE;
- }
-
- (*func_p)(env, &info, sizeof(info));
- setStaticIntField(env, cls, "jvm_major_version", JVM_VERSION_MAJOR(info.jvm_version));
- JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
- setStaticIntField(env, cls, "jvm_minor_version", JVM_VERSION_MINOR(info.jvm_version));
- JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
- setStaticIntField(env, cls, "jvm_security_version", JVM_VERSION_SECURITY(info.jvm_version));
- JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
- setStaticIntField(env, cls, "jvm_build_number", JVM_VERSION_BUILD(info.jvm_version));
- JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
- setStaticIntField(env, cls, "jvm_patch_version", info.patch_version);
- JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
-
- return JNI_TRUE;
-}
-
-JNIEXPORT void JNICALL
-Java_sun_misc_Version_getJdkVersionInfo(JNIEnv *env, jclass cls)
-{
- jdk_version_info info;
-
- JDK_GetVersionInfo0(&info, sizeof(info));
- setStaticIntField(env, cls, "jdk_major_version", JDK_VERSION_MAJOR(info.jdk_version));
- JNU_CHECK_EXCEPTION(env);
- setStaticIntField(env, cls, "jdk_minor_version", JDK_VERSION_MINOR(info.jdk_version));
- JNU_CHECK_EXCEPTION(env);
- setStaticIntField(env, cls, "jdk_security_version", JDK_VERSION_SECURITY(info.jdk_version));
- JNU_CHECK_EXCEPTION(env);
- setStaticIntField(env, cls, "jdk_build_number", JDK_VERSION_BUILD(info.jdk_version));
- JNU_CHECK_EXCEPTION(env);
- setStaticIntField(env, cls, "jdk_patch_version", info.patch_version);
- JNU_CHECK_EXCEPTION(env);
-}
--- a/jdk/src/java.base/share/native/libjli/java.c Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.base/share/native/libjli/java.c Thu Mar 03 12:49:12 2016 -0800
@@ -1470,7 +1470,7 @@
jclass ver;
jmethodID print;
- NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
+ NULL_CHECK(ver = FindBootStrapClass(env, "java/lang/VersionProps"));
NULL_CHECK(print = (*env)->GetStaticMethodID(env,
ver,
(extraLF == JNI_TRUE) ? "println" : "print",
--- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java Thu Mar 03 12:49:12 2016 -0800
@@ -839,6 +839,7 @@
* @param level One of the message level identifiers, e.g., SEVERE
* @param msgSupplier A function, which when called, produces the
* desired log message
+ * @since 1.8
*/
public void log(Level level, Supplier<String> msgSupplier) {
if (!isLoggable(level)) {
--- a/jdk/test/java/lang/ProcessHandle/Basic.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/lang/ProcessHandle/Basic.java Thu Mar 03 12:49:12 2016 -0800
@@ -37,7 +37,7 @@
/*
* @test
* @library /test/lib/share/classes
- * @run testng InfoTest
+ * @run testng Basic
* @summary Basic tests for ProcessHandler
* @author Roger Riggs
*/
--- a/jdk/test/java/lang/ProcessHandle/InfoTest.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/lang/ProcessHandle/InfoTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -114,9 +114,13 @@
long cpuLoopTime = 100; // 100 ms
String[] extraArgs = {"pid", "parent", "stdin"};
JavaChild p1 = JavaChild.spawnJavaChild((Object[])extraArgs);
- Instant afterStart = Instant.now();
+ Instant afterStart = null;
try (BufferedReader lines = p1.outputReader()) {
+ // Read the args line to know the subprocess has started
+ lines.readLine();
+ afterStart = Instant.now();
+
Duration lastCpu = Duration.ofMillis(0L);
for (int j = 0; j < 10; j++) {
@@ -126,8 +130,7 @@
// Read cputime from child
Duration childCpuTime = null;
// Read lines from the child until the result from cputime is returned
- String s;
- while ((s = lines.readLine()) != null) {
+ for (String s; (s = lines.readLine()) != null;) {
String[] split = s.trim().split(" ");
if (split.length == 3 && split[1].equals("cputime")) {
long nanos = Long.valueOf(split[2]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuilder/Capacity.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8149330
+ * @summary Basic set of tests of capacity management
+ * @run testng Capacity
+ */
+
+import java.lang.reflect.Field;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.SplittableRandom;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.*;
+
+public class Capacity {
+ static final int DEFAULT_CAPACITY = 16;
+
+ private static int newCapacity(int oldCapacity,
+ int desiredCapacity)
+ {
+ return Math.max(oldCapacity * 2 + 2, desiredCapacity);
+ }
+
+ private static int nextNewCapacity(int oldCapacity) {
+ return newCapacity(oldCapacity, oldCapacity + 1);
+ }
+
+ @Test(dataProvider = "singleChar")
+ public void defaultCapacity(Character ch) {
+ StringBuilder sb = new StringBuilder();
+ assertEquals(sb.capacity(), DEFAULT_CAPACITY);
+ for (int i = 0; i < DEFAULT_CAPACITY; i++) {
+ sb.append(ch);
+ assertEquals(sb.capacity(), DEFAULT_CAPACITY);
+ }
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(DEFAULT_CAPACITY));
+ }
+
+ @Test(dataProvider = "charCapacity")
+ public void explicitCapacity(Character ch, int initCapacity) {
+ StringBuilder sb = new StringBuilder(initCapacity);
+ assertEquals(sb.capacity(), initCapacity);
+ for (int i = 0; i < initCapacity; i++) {
+ sb.append(ch);
+ assertEquals(sb.capacity(), initCapacity);
+ }
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(initCapacity));
+ }
+
+ @Test(dataProvider = "singleChar")
+ public void sbFromString(Character ch) {
+ String s = "string " + ch;
+ int expectedCapacity = s.length() + DEFAULT_CAPACITY;
+ StringBuilder sb = new StringBuilder(s);
+ assertEquals(sb.capacity(), expectedCapacity);
+ for (int i = 0; i < DEFAULT_CAPACITY; i++) {
+ sb.append(ch);
+ assertEquals(sb.capacity(), expectedCapacity);
+ }
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(expectedCapacity));
+ }
+
+ @Test(dataProvider = "singleChar")
+ public void sbFromCharSeq(Character ch) {
+ CharSequence cs = new MyCharSeq("char seq " + ch);
+ int expectedCapacity = cs.length() + DEFAULT_CAPACITY;
+ StringBuilder sb = new StringBuilder(cs);
+ assertEquals(sb.capacity(), expectedCapacity);
+ for (int i = 0; i < DEFAULT_CAPACITY; i++) {
+ sb.append(ch);
+ assertEquals(sb.capacity(), expectedCapacity);
+ }
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(expectedCapacity));
+ }
+
+ @Test(dataProvider = "charCapacity")
+ public void ensureCapacity(Character ch, int cap) {
+ StringBuilder sb = new StringBuilder(0);
+ assertEquals(sb.capacity(), 0);
+ sb.ensureCapacity(cap); // only has effect if cap > 0
+ int newCap = (cap == 0) ? 0 : newCapacity(0, cap);
+ assertEquals(sb.capacity(), newCap);
+ sb.ensureCapacity(newCap + 1);
+ assertEquals(sb.capacity(), nextNewCapacity(newCap));
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(newCap));
+ }
+
+ @Test(dataProvider = "negativeCapacity",
+ expectedExceptions = NegativeArraySizeException.class)
+ public void negativeInitialCapacity(int negCap) {
+ StringBuilder sb = new StringBuilder(negCap);
+ }
+
+ @Test(dataProvider = "negativeCapacity")
+ public void ensureNegativeCapacity(int negCap) {
+ StringBuilder sb = new StringBuilder();
+ sb.ensureCapacity(negCap);
+ assertEquals(sb.capacity(), DEFAULT_CAPACITY);
+ }
+
+ @Test(dataProvider = "charCapacity")
+ public void trimToSize(Character ch, int cap) {
+ StringBuilder sb = new StringBuilder(cap);
+ int halfOfCap = cap / 2;
+ for (int i = 0; i < halfOfCap; i++) {
+ sb.append(ch);
+ }
+ sb.trimToSize();
+ // according to the spec, capacity doesn't have to
+ // become exactly the size
+ assertTrue(sb.capacity() >= halfOfCap);
+ }
+
+ @DataProvider
+ public Object[][] singleChar() {
+ return new Object[][] { {'J'}, {'\u042b'} };
+ }
+
+ @DataProvider
+ public Object[][] charCapacity() {
+ return new Object[][] {
+ {'J', 0},
+ {'J', 1},
+ {'J', 15},
+ {'J', DEFAULT_CAPACITY},
+ {'J', 1024},
+ {'\u042b', 0},
+ {'\u042b', 1},
+ {'\u042b', 15},
+ {'\u042b', DEFAULT_CAPACITY},
+ {'\u042b', 1024},
+ };
+ }
+
+ @DataProvider
+ public Object[][] negativeCapacity() {
+ return new Object[][] { {-1}, {Integer.MIN_VALUE} };
+ }
+
+ private static class MyCharSeq implements CharSequence {
+ private CharSequence s;
+ public MyCharSeq(CharSequence s) { this.s = s; }
+ public char charAt(int i) { return s.charAt(i); }
+ public int length() { return s.length(); }
+ public CharSequence subSequence(int st, int e) {
+ return s.subSequence(st, e);
+ }
+ public String toString() { return s.toString(); }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuilder/HugeCapacity.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8149330
+ * @summary Capacity should not get close to Integer.MAX_VALUE unless
+ * necessary
+ * @run main/othervm -Xmx5G HugeCapacity
+ * @ignore This test has huge memory requirements
+ */
+
+public class HugeCapacity {
+ private static int failures = 0;
+
+ public static void main(String[] args) {
+ testLatin1();
+ testUtf16();
+ if (failures > 0) {
+ throw new RuntimeException(failures + " tests failed");
+ }
+ }
+
+ private static void testLatin1() {
+ try {
+ StringBuilder sb = new StringBuilder();
+ sb.ensureCapacity(Integer.MAX_VALUE / 2);
+ sb.ensureCapacity(Integer.MAX_VALUE / 2 + 1);
+ } catch (OutOfMemoryError oom) {
+ oom.printStackTrace();
+ failures++;
+ }
+ }
+
+ private static void testUtf16() {
+ try {
+ StringBuilder sb = new StringBuilder();
+ sb.append('\u042b');
+ sb.ensureCapacity(Integer.MAX_VALUE / 4);
+ sb.ensureCapacity(Integer.MAX_VALUE / 4 + 1);
+ } catch (OutOfMemoryError oom) {
+ oom.printStackTrace();
+ failures++;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/FindAccessTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ */
+
+/* @test
+ * @bug 8139885
+ * @run testng/othervm -ea -esa test.java.lang.invoke.FindAccessTest
+ */
+
+package test.java.lang.invoke;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.*;
+
+/**
+ * Tests for Lookup.findClass/accessClass extensions added in JEP 274.
+ */
+public class FindAccessTest {
+
+ static final Lookup LOOKUP = MethodHandles.lookup();
+
+ @Test
+ public static void testFindSpecial() throws Throwable {
+ FindSpecial.C c = new FindSpecial.C();
+ assertEquals("I1.m", c.m());
+ MethodType t = MethodType.methodType(String.class);
+ MethodHandle ci1m = LOOKUP.findSpecial(FindSpecial.I1.class, "m", t, FindSpecial.C.class);
+ assertEquals("I1.m", (String) ci1m.invoke(c));
+ }
+
+ @Test
+ public static void testFindSpecialAbstract() throws Throwable {
+ FindSpecial.C c = new FindSpecial.C();
+ assertEquals("q", c.q());
+ MethodType t = MethodType.methodType(String.class);
+ boolean caught = false;
+ try {
+ MethodHandle ci3q = LOOKUP.findSpecial(FindSpecial.I3.class, "q", t, FindSpecial.C.class);
+ } catch (Throwable thrown) {
+ if (!(thrown instanceof IllegalAccessException) || !FindSpecial.ABSTRACT_ERROR.equals(thrown.getMessage())) {
+ throw new AssertionError(thrown.getMessage(), thrown);
+ }
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ @Test(expectedExceptions = {ClassNotFoundException.class})
+ public static void testFindClassCNFE() throws ClassNotFoundException, IllegalAccessException {
+ LOOKUP.findClass("does.not.Exist");
+ }
+
+ static class FindSpecial {
+
+ interface I1 {
+ default String m() {
+ return "I1.m";
+ }
+ }
+
+ interface I2 {
+ default String m() {
+ return "I2.m";
+ }
+ }
+
+ interface I3 {
+ String q();
+ }
+
+ static class C implements I1, I2, I3 {
+ public String m() {
+ return I1.super.m();
+ }
+ public String q() {
+ return "q";
+ }
+ }
+
+ static final String ABSTRACT_ERROR = "no such method: test.java.lang.invoke.FindAccessTest$FindSpecial$I3.q()String/invokeSpecial";
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/FoldTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ */
+
+/* @test
+ * @bug 8139885
+ * @run testng/othervm -ea -esa test.java.lang.invoke.FoldTest
+ */
+
+package test.java.lang.invoke;
+
+import java.io.StringWriter;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.*;
+
+/**
+ * Tests for the new fold method handle combinator added in JEP 274.
+ */
+public class FoldTest {
+
+ static final Lookup LOOKUP = MethodHandles.lookup();
+
+ @Test
+ public static void testFold0a() throws Throwable {
+ // equivalence to foldArguments(MethodHandle,MethodHandle)
+ MethodHandle fold = MethodHandles.foldArguments(Fold.MH_multer, 0, Fold.MH_adder);
+ assertEquals(Fold.MT_folded1, fold.type());
+ assertEquals(720, (int) fold.invoke(3, 4, 5));
+ }
+
+ @Test
+ public static void testFold1a() throws Throwable {
+ // test foldArguments for folding position 1
+ MethodHandle fold = MethodHandles.foldArguments(Fold.MH_multer, 1, Fold.MH_adder1);
+ assertEquals(Fold.MT_folded1, fold.type());
+ assertEquals(540, (int) fold.invoke(3, 4, 5));
+ }
+
+ @Test
+ public static void testFold0b() throws Throwable {
+ // test foldArguments equivalence with multiple types
+ MethodHandle fold = MethodHandles.foldArguments(Fold.MH_str, 0, Fold.MH_comb);
+ assertEquals(Fold.MT_folded2, fold.type());
+ assertEquals(23, (int) fold.invoke("true", true, 23));
+ }
+
+ @Test
+ public static void testFold1b() throws Throwable {
+ // test folgArguments for folding position 1, with multiple types
+ MethodHandle fold = MethodHandles.foldArguments(Fold.MH_str, 1, Fold.MH_comb2);
+ assertEquals(Fold.MT_folded3, fold.type());
+ assertEquals(1, (int) fold.invoke(true, true, 1));
+ assertEquals(-1, (int) fold.invoke(true, false, -1));
+ }
+
+ @Test
+ public static void testFoldArgumentsExample() throws Throwable {
+ // test the JavaDoc foldArguments-with-pos example
+ StringWriter swr = new StringWriter();
+ MethodHandle trace = LOOKUP.findVirtual(StringWriter.class, "write", methodType(void.class, String.class)).bindTo(swr);
+ MethodHandle cat = LOOKUP.findVirtual(String.class, "concat", methodType(String.class, String.class));
+ assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
+ MethodHandle catTrace = MethodHandles.foldArguments(cat, 1, trace);
+ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
+ assertEquals("jum", swr.toString());
+ }
+
+ static class Fold {
+
+ static int adder(int a, int b, int c) {
+ return a + b + c;
+ }
+
+ static int adder1(int a, int b) {
+ return a + b;
+ }
+
+ static int multer(int x, int q, int r, int s) {
+ return x * q * r * s;
+ }
+
+ static int str(boolean b1, String s, boolean b2, int x) {
+ return b1 && s.equals(String.valueOf(b2)) ? x : -x;
+ }
+
+ static boolean comb(String s, boolean b2) {
+ return !s.equals(b2);
+ }
+
+ static String comb2(boolean b2, int x) {
+ int ib = b2 ? 1 : 0;
+ return ib == x ? "true" : "false";
+ }
+
+ static final Class<Fold> FOLD = Fold.class;
+
+ static final MethodType MT_adder = methodType(int.class, int.class, int.class, int.class);
+ static final MethodType MT_adder1 = methodType(int.class, int.class, int.class);
+ static final MethodType MT_multer = methodType(int.class, int.class, int.class, int.class, int.class);
+ static final MethodType MT_str = methodType(int.class, boolean.class, String.class, boolean.class, int.class);
+ static final MethodType MT_comb = methodType(boolean.class, String.class, boolean.class);
+ static final MethodType MT_comb2 = methodType(String.class, boolean.class, int.class);
+
+ static final MethodHandle MH_adder;
+ static final MethodHandle MH_adder1;
+ static final MethodHandle MH_multer;
+ static final MethodHandle MH_str;
+ static final MethodHandle MH_comb;
+ static final MethodHandle MH_comb2;
+
+ static final MethodType MT_folded1 = methodType(int.class, int.class, int.class, int.class);
+ static final MethodType MT_folded2 = methodType(int.class, String.class, boolean.class, int.class);
+ static final MethodType MT_folded3 = methodType(int.class, boolean.class, boolean.class, int.class);
+
+ static {
+ try {
+ MH_adder = LOOKUP.findStatic(FOLD, "adder", MT_adder);
+ MH_adder1 = LOOKUP.findStatic(FOLD, "adder1", MT_adder1);
+ MH_multer = LOOKUP.findStatic(FOLD, "multer", MT_multer);
+ MH_str = LOOKUP.findStatic(FOLD, "str", MT_str);
+ MH_comb = LOOKUP.findStatic(FOLD, "comb", MT_comb);
+ MH_comb2 = LOOKUP.findStatic(FOLD, "comb2", MT_comb2);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+ }
+
+}
--- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -690,7 +690,7 @@
{{
{} /// JAVADOC
// implement the zip function for lists as a loop handle
-MethodHandle loop = MethodHandles.doWhileLoop(MH_initZip, MH_zipStep, MH_zipPred);
+MethodHandle loop = MethodHandles.whileLoop(MH_initZip, MH_zipPred, MH_zipStep);
List<String> a = Arrays.asList("a", "b", "c", "d");
List<String> b = Arrays.asList("e", "f", "g", "h");
List<String> zipped = Arrays.asList("a", "e", "b", "f", "c", "g", "d", "h");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/LoopCombinatorTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ */
+
+/* @test
+ * @bug 8139885
+ * @bug 8150635
+ * @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest
+ */
+
+package test.java.lang.invoke;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.util.*;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.*;
+
+/**
+ * Tests for the loop combinators introduced in JEP 274.
+ */
+public class LoopCombinatorTest {
+
+ static final Lookup LOOKUP = MethodHandles.lookup();
+
+ @Test
+ public static void testLoopFac() throws Throwable {
+ MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc};
+ MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
+ MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
+ assertEquals(Fac.MT_fac, loop.type());
+ assertEquals(120, loop.invoke(5));
+ }
+
+ @Test
+ public static void testLoopFacNullInit() throws Throwable {
+ // null initializer for counter, should initialize to 0
+ MethodHandle[] counterClause = new MethodHandle[]{null, Fac.MH_inc};
+ MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
+ MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
+ assertEquals(Fac.MT_fac, loop.type());
+ assertEquals(120, loop.invoke(5));
+ }
+
+ @Test
+ public static void testLoopNullInit() throws Throwable {
+ // null initializer for counter, should initialize to 0, one-clause loop
+ MethodHandle[] counterClause = new MethodHandle[]{null, Loop.MH_inc, Loop.MH_pred, Loop.MH_fin};
+ MethodHandle loop = MethodHandles.loop(counterClause);
+ assertEquals(Loop.MT_loop, loop.type());
+ assertEquals(10, loop.invoke(10));
+ }
+
+ @Test
+ public static void testLoopVoid1() throws Throwable {
+ // construct a post-checked loop that only does one iteration and has a void body and void local state
+ MethodHandle loop = MethodHandles.loop(new MethodHandle[]{Empty.MH_f, Empty.MH_f, Empty.MH_pred, null});
+ assertEquals(MethodType.methodType(void.class), loop.type());
+ loop.invoke();
+ }
+
+ @Test
+ public static void testLoopVoid2() throws Throwable {
+ // construct a post-checked loop that only does one iteration and has a void body and void local state,
+ // initialized implicitly from the step type
+ MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, null});
+ assertEquals(MethodType.methodType(void.class), loop.type());
+ loop.invoke();
+ }
+
+ @Test
+ public static void testLoopVoid3() throws Throwable {
+ // construct a post-checked loop that only does one iteration and has a void body and void local state,
+ // and that has a void finalizer
+ MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, Empty.MH_f});
+ assertEquals(MethodType.methodType(void.class), loop.type());
+ loop.invoke();
+ }
+
+ @Test
+ public static void testLoopFacWithVoidState() throws Throwable {
+ // like testLoopFac, but with additional void state that outputs a dot
+ MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc};
+ MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
+ MethodHandle[] dotClause = new MethodHandle[]{null, Fac.MH_dot};
+ MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause, dotClause);
+ assertEquals(Fac.MT_fac, loop.type());
+ assertEquals(120, loop.invoke(5));
+ }
+
+ @Test
+ public static void testLoopVoidInt() throws Throwable {
+ // construct a post-checked loop that only does one iteration and has a void body and void local state,
+ // and that returns a constant
+ MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, Empty.MH_c});
+ assertEquals(MethodType.methodType(int.class), loop.type());
+ assertEquals(23, loop.invoke());
+ }
+
+ @Test
+ public static void testLoopWithVirtuals() throws Throwable {
+ // construct a loop (to calculate factorial) that uses a mix of static and virtual methods
+ MethodHandle[] counterClause = new MethodHandle[]{null, LoopWithVirtuals.permute(LoopWithVirtuals.MH_inc)};
+ MethodHandle[] accumulatorClause = new MethodHandle[]{
+ // init function must indicate the loop arguments (there is no other means to determine them)
+ MethodHandles.dropArguments(LoopWithVirtuals.MH_one, 0, LoopWithVirtuals.class),
+ LoopWithVirtuals.permute(LoopWithVirtuals.MH_mult),
+ LoopWithVirtuals.permute(LoopWithVirtuals.MH_pred),
+ LoopWithVirtuals.permute(LoopWithVirtuals.MH_fin)
+ };
+ MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
+ assertEquals(LoopWithVirtuals.MT_loop, loop.type());
+ assertEquals(120, loop.invoke(new LoopWithVirtuals(), 5));
+ }
+
+ @DataProvider
+ static Object[][] negativeTestData() {
+ MethodHandle i0 = MethodHandles.constant(int.class, 0);
+ MethodHandle ii = MethodHandles.dropArguments(i0, 0, int.class, int.class);
+ MethodHandle id = MethodHandles.dropArguments(i0, 0, int.class, double.class);
+ MethodHandle i3 = MethodHandles.dropArguments(i0, 0, int.class, int.class, int.class);
+ List<MethodHandle> inits = Arrays.asList(ii, id, i3);
+ List<Class<?>> ints = Arrays.asList(int.class, int.class, int.class);
+ List<MethodHandle> finis = Arrays.asList(Fac.MH_fin, Fac.MH_inc, Counted.MH_step);
+ List<MethodHandle> preds1 = Arrays.asList(null, null, null);
+ List<MethodHandle> preds2 = Arrays.asList(null, Fac.MH_fin, null);
+ MethodHandle eek = MethodHandles.dropArguments(i0, 0, int.class, int.class, double.class);
+ List<MethodHandle> nesteps = Arrays.asList(Fac.MH_inc, eek, Fac.MH_dot);
+ List<MethodHandle> nepreds = Arrays.asList(null, Fac.MH_pred, null);
+ List<MethodHandle> nefinis = Arrays.asList(null, Fac.MH_fin, null);
+ List<MethodHandle> lvsteps = Arrays.asList(LoopWithVirtuals.MH_inc, LoopWithVirtuals.MH_mult);
+ List<MethodHandle> lvpreds = Arrays.asList(null, LoopWithVirtuals.MH_pred);
+ List<MethodHandle> lvfinis = Arrays.asList(null, LoopWithVirtuals.MH_fin);
+ return new Object[][] {
+ {null, "null or no clauses passed"},
+ {new MethodHandle[][]{}, "null or no clauses passed"},
+ {new MethodHandle[][]{{null, Fac.MH_inc}, {Fac.MH_one, null, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin}},
+ "All loop clauses must be represented as MethodHandle arrays with at most 4 elements."},
+ {new MethodHandle[][]{{null, Fac.MH_inc}, null}, "null clauses are not allowed"},
+ {new MethodHandle[][]{{Fac.MH_zero, Fac.MH_dot}},
+ "clause 0: init and step return types must match: int != void"},
+ {new MethodHandle[][]{{ii}, {id}, {i3}},
+ "found non-effectively identical init parameter type lists: " + inits +
+ " (common suffix: " + ints + ")"},
+ {new MethodHandle[][]{{null, Fac.MH_inc, null, Fac.MH_fin}, {null, Fac.MH_inc, null, Fac.MH_inc},
+ {null, Counted.MH_start, null, Counted.MH_step}},
+ "found non-identical finalizer return types: " + finis + " (return type: int)"},
+ {new MethodHandle[][]{{Fac.MH_zero, Fac.MH_inc}, {Fac.MH_one, Fac.MH_mult, null, Fac.MH_fin},
+ {null, Fac.MH_dot}}, "no predicate found: " + preds1},
+ {new MethodHandle[][]{{Fac.MH_zero, Fac.MH_inc}, {Fac.MH_one, Fac.MH_mult, Fac.MH_fin, Fac.MH_fin},
+ {null, Fac.MH_dot}}, "predicates must have boolean return type: " + preds2},
+ {new MethodHandle[][]{{Fac.MH_zero, Fac.MH_inc}, {Fac.MH_one, eek, Fac.MH_pred, Fac.MH_fin},
+ {null, Fac.MH_dot}},
+ "found non-effectively identical parameter type lists:\nstep: " + nesteps +
+ "\npred: " + nepreds + "\nfini: " + nefinis + " (common parameter sequence: " + ints + ")"},
+ {new MethodHandle[][]{{null, LoopWithVirtuals.MH_inc},
+ {LoopWithVirtuals.MH_one, LoopWithVirtuals.MH_mult, LoopWithVirtuals.MH_pred, LoopWithVirtuals.MH_fin}},
+ "found non-effectively identical parameter type lists:\nstep: " + lvsteps +
+ "\npred: " + lvpreds + "\nfini: " + lvfinis + " (common parameter sequence: " + ints + ")"}
+ };
+ }
+
+ static final MethodHandle MH_loop;
+
+ static {
+ try {
+ MH_loop = LOOKUP.findStatic(MethodHandles.class, "loop", methodType(MethodHandle.class, MethodHandle[][].class));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ @Test(dataProvider = "negativeTestData")
+ public static void testLoopNegative(MethodHandle[][] clauses, String expectedMessage) throws Throwable {
+ boolean caught = false;
+ try {
+ MH_loop.invokeWithArguments(clauses);
+ } catch (IllegalArgumentException iae) {
+ assertEquals(expectedMessage, iae.getMessage());
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ @Test
+ public static void testWhileLoop() throws Throwable {
+ // int i = 0; while (i < limit) { ++i; } return i; => limit
+ MethodHandle loop = MethodHandles.whileLoop(While.MH_zero, While.MH_pred, While.MH_step);
+ assertEquals(While.MT_while, loop.type());
+ assertEquals(23, loop.invoke(23));
+ }
+
+ @Test
+ public static void testWhileLoopNoIteration() throws Throwable {
+ // a while loop that never executes its body because the predicate evaluates to false immediately
+ MethodHandle loop = MethodHandles.whileLoop(While.MH_initString, While.MH_predString, While.MH_stepString);
+ assertEquals(While.MT_string, loop.type());
+ assertEquals("a", loop.invoke());
+ }
+
+ @Test
+ public static void testDoWhileLoop() throws Throwable {
+ // int i = 0; do { ++i; } while (i < limit); return i; => limit
+ MethodHandle loop = MethodHandles.doWhileLoop(While.MH_zero, While.MH_step, While.MH_pred);
+ assertEquals(While.MT_while, loop.type());
+ assertEquals(23, loop.invoke(23));
+ }
+
+ @Test
+ public static void testDoWhileNullInit() throws Throwable {
+ While w = new While();
+ int v = 5;
+ MethodHandle loop = MethodHandles.doWhileLoop(null, While.MH_voidBody.bindTo(w), While.MH_voidPred.bindTo(w));
+ assertEquals(While.MT_void, loop.type());
+ loop.invoke(v);
+ assertEquals(v, w.i);
+ }
+
+ @Test
+ public static void testWhileZip() throws Throwable {
+ MethodHandle loop = MethodHandles.doWhileLoop(While.MH_zipInitZip, While.MH_zipStep, While.MH_zipPred);
+ assertEquals(While.MT_zip, loop.type());
+ List<String> a = Arrays.asList("a", "b", "c", "d");
+ List<String> b = Arrays.asList("e", "f", "g", "h");
+ List<String> zipped = Arrays.asList("a", "e", "b", "f", "c", "g", "d", "h");
+ assertEquals(zipped, (List<String>) loop.invoke(a.iterator(), b.iterator()));
+ }
+
+ @Test
+ public static void testWhileNullInit() throws Throwable {
+ While w = new While();
+ int v = 5;
+ MethodHandle loop = MethodHandles.whileLoop(null, While.MH_voidPred.bindTo(w), While.MH_voidBody.bindTo(w));
+ assertEquals(While.MT_void, loop.type());
+ loop.invoke(v);
+ assertEquals(v, w.i);
+ }
+
+ @Test
+ public static void testCountedLoop() throws Throwable {
+ // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s; => a variation on a well known theme
+ MethodHandle fit13 = MethodHandles.constant(int.class, 13);
+ MethodHandle loop = MethodHandles.countedLoop(fit13, Counted.MH_start, Counted.MH_step);
+ assertEquals(Counted.MT_counted, loop.type());
+ assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
+ }
+
+ @Test
+ public static void testCountedArrayLoop() throws Throwable {
+ // int[] a = new int[]{0}; for (int i = 0; i < 13; ++i) { ++a[0]; } => a[0] == 13
+ MethodHandle fit13 = MethodHandles.dropArguments(MethodHandles.constant(int.class, 13), 0, int[].class);
+ MethodHandle loop = MethodHandles.countedLoop(fit13, null, Counted.MH_stepUpdateArray);
+ assertEquals(Counted.MT_arrayCounted, loop.type());
+ int[] a = new int[]{0};
+ loop.invoke(a);
+ assertEquals(13, a[0]);
+ }
+
+ @Test
+ public static void testCountedPrintingLoop() throws Throwable {
+ MethodHandle fit5 = MethodHandles.constant(int.class, 5);
+ MethodHandle loop = MethodHandles.countedLoop(fit5, null, Counted.MH_printHello);
+ assertEquals(Counted.MT_countedPrinting, loop.type());
+ loop.invoke();
+ }
+
+ @Test
+ public static void testCountedRangeLoop() throws Throwable {
+ // String s = "Lambdaman!"; for (int i = -5; i < 8; ++i) { s = "na " + s; } return s; => a well known theme
+ MethodHandle fitm5 = MethodHandles.dropArguments(Counted.MH_m5, 0, String.class);
+ MethodHandle fit8 = MethodHandles.dropArguments(Counted.MH_8, 0, String.class);
+ MethodHandle loop = MethodHandles.countedLoop(fitm5, fit8, Counted.MH_start, Counted.MH_step);
+ assertEquals(Counted.MT_counted, loop.type());
+ assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
+ }
+
+ @Test
+ public static void testIterateSum() throws Throwable {
+ // Integer[] a = new Integer[]{1,2,3,4,5,6}; int sum = 0; for (int e : a) { sum += e; } return sum; => 21
+ MethodHandle loop = MethodHandles.iteratedLoop(Iterate.MH_sumIterator, Iterate.MH_sumInit, Iterate.MH_sumStep);
+ assertEquals(Iterate.MT_sum, loop.type());
+ assertEquals(21, loop.invoke(new Integer[]{1, 2, 3, 4, 5, 6}));
+ }
+
+ @Test
+ public static void testIterateReverse() throws Throwable {
+ MethodHandle loop = MethodHandles.iteratedLoop(null, Iterate.MH_reverseInit, Iterate.MH_reverseStep);
+ assertEquals(Iterate.MT_reverse, loop.type());
+ List<String> list = Arrays.asList("a", "b", "c", "d", "e");
+ List<String> reversedList = Arrays.asList("e", "d", "c", "b", "a");
+ assertEquals(reversedList, (List<String>) loop.invoke(list));
+ }
+
+ @Test
+ public static void testIterateLength() throws Throwable {
+ MethodHandle loop = MethodHandles.iteratedLoop(null, Iterate.MH_lengthInit, Iterate.MH_lengthStep);
+ assertEquals(Iterate.MT_length, loop.type());
+ List<Double> list = Arrays.asList(23.0, 148.0, 42.0);
+ assertEquals(list.size(), (int) loop.invoke(list));
+ }
+
+ @Test
+ public static void testIterateMap() throws Throwable {
+ MethodHandle loop = MethodHandles.iteratedLoop(null, Iterate.MH_mapInit, Iterate.MH_mapStep);
+ assertEquals(Iterate.MT_map, loop.type());
+ List<String> list = Arrays.asList("Hello", "world", "!");
+ List<String> upList = Arrays.asList("HELLO", "WORLD", "!");
+ assertEquals(upList, (List<String>) loop.invoke(list));
+ }
+
+ @Test
+ public static void testIteratePrint() throws Throwable {
+ MethodHandle loop = MethodHandles.iteratedLoop(null, null, Iterate.MH_printStep);
+ assertEquals(Iterate.MT_print, loop.type());
+ loop.invoke(Arrays.asList("hello", "world"));
+ }
+
+ @Test
+ public static void testIterateNullBody() {
+ boolean caught = false;
+ try {
+ MethodHandles.iteratedLoop(MethodHandles.identity(int.class), MethodHandles.identity(int.class), null);
+ } catch (IllegalArgumentException iae) {
+ assertEquals("iterated loop body must not be null", iae.getMessage());
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ static class Empty {
+
+ static void f() { }
+
+ static boolean pred() {
+ return false;
+ }
+
+ static int c() {
+ return 23;
+ }
+
+ static final Class<Empty> EMPTY = Empty.class;
+
+ static final MethodType MT_f = methodType(void.class);
+ static final MethodType MT_pred = methodType(boolean.class);
+ static final MethodType MT_c = methodType(int.class);
+
+ static final MethodHandle MH_f;
+ static final MethodHandle MH_pred;
+ static final MethodHandle MH_c;
+
+ static {
+ try {
+ MH_f = LOOKUP.findStatic(EMPTY, "f", MT_f);
+ MH_pred = LOOKUP.findStatic(EMPTY, "pred", MT_pred);
+ MH_c = LOOKUP.findStatic(EMPTY, "c", MT_c);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+ }
+
+ static class Fac {
+
+ static int zero(int k) {
+ return 0;
+ }
+
+ static int one(int k) {
+ return 1;
+ }
+
+ static boolean pred(int i, int acc, int k) {
+ return i < k;
+ }
+
+ static int inc(int i, int acc, int k) {
+ return i + 1;
+ }
+
+ static int mult(int i, int acc, int k) {
+ return i * acc;
+ }
+
+ static void dot(int i, int acc, int k) {
+ System.out.print('.');
+ }
+
+ static int fin(int i, int acc, int k) {
+ return acc;
+ }
+
+ static final Class<Fac> FAC = Fac.class;
+
+ static final MethodType MT_init = methodType(int.class, int.class);
+ static final MethodType MT_fn = methodType(int.class, int.class, int.class, int.class);
+ static final MethodType MT_dot = methodType(void.class, int.class, int.class, int.class);
+ static final MethodType MT_pred = methodType(boolean.class, int.class, int.class, int.class);
+
+ static final MethodHandle MH_zero;
+ static final MethodHandle MH_one;
+ static final MethodHandle MH_pred;
+ static final MethodHandle MH_inc;
+ static final MethodHandle MH_mult;
+ static final MethodHandle MH_dot;
+ static final MethodHandle MH_fin;
+
+ static final MethodType MT_fac = methodType(int.class, int.class);
+
+ static {
+ try {
+ MH_zero = LOOKUP.findStatic(FAC, "zero", MT_init);
+ MH_one = LOOKUP.findStatic(FAC, "one", MT_init);
+ MH_pred = LOOKUP.findStatic(FAC, "pred", MT_pred);
+ MH_inc = LOOKUP.findStatic(FAC, "inc", MT_fn);
+ MH_mult = LOOKUP.findStatic(FAC, "mult", MT_fn);
+ MH_dot = LOOKUP.findStatic(FAC, "dot", MT_dot);
+ MH_fin = LOOKUP.findStatic(FAC, "fin", MT_fn);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ }
+
+ static class Loop {
+
+ static int inc(int i, int k) {
+ return i + 1;
+ }
+
+ static boolean pred(int i, int k) {
+ return i < k;
+ }
+
+ static int fin(int i, int k) {
+ return k;
+ }
+
+ static final Class<Loop> LOOP = Loop.class;
+
+ static final MethodType MT_inc = methodType(int.class, int.class, int.class);
+ static final MethodType MT_pred = methodType(boolean.class, int.class, int.class);
+ static final MethodType MT_fin = methodType(int.class, int.class, int.class);
+
+ static final MethodHandle MH_inc;
+ static final MethodHandle MH_pred;
+ static final MethodHandle MH_fin;
+
+ static final MethodType MT_loop = methodType(int.class, int.class);
+
+ static {
+ try {
+ MH_inc = LOOKUP.findStatic(LOOP, "inc", MT_inc);
+ MH_pred = LOOKUP.findStatic(LOOP, "pred", MT_pred);
+ MH_fin = LOOKUP.findStatic(LOOP, "fin", MT_fin);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ }
+
+ static class LoopWithVirtuals {
+
+ static int one(int k) {
+ return 1;
+ }
+
+ int inc(int i, int acc, int k) {
+ return i + 1;
+ }
+
+ int mult(int i, int acc, int k) {
+ return i * acc;
+ }
+
+ boolean pred(int i, int acc, int k) {
+ return i < k;
+ }
+
+ int fin(int i, int acc, int k) {
+ return acc;
+ }
+
+ static final Class<LoopWithVirtuals> LOOP_WITH_VIRTUALS = LoopWithVirtuals.class;
+
+ static final MethodType MT_one = methodType(int.class, int.class);
+ static final MethodType MT_inc = methodType(int.class, int.class, int.class, int.class);
+ static final MethodType MT_mult = methodType(int.class, int.class, int.class, int.class);
+ static final MethodType MT_pred = methodType(boolean.class, int.class, int.class, int.class);
+ static final MethodType MT_fin = methodType(int.class, int.class, int.class, int.class);
+
+ static final MethodHandle MH_one;
+ static final MethodHandle MH_inc;
+ static final MethodHandle MH_mult;
+ static final MethodHandle MH_pred;
+ static final MethodHandle MH_fin;
+
+ static final MethodType MT_loop = methodType(int.class, LOOP_WITH_VIRTUALS, int.class);
+
+ static {
+ try {
+ MH_one = LOOKUP.findStatic(LOOP_WITH_VIRTUALS, "one", MT_one);
+ MH_inc = LOOKUP.findVirtual(LOOP_WITH_VIRTUALS, "inc", MT_inc);
+ MH_mult = LOOKUP.findVirtual(LOOP_WITH_VIRTUALS, "mult", MT_mult);
+ MH_pred = LOOKUP.findVirtual(LOOP_WITH_VIRTUALS, "pred", MT_pred);
+ MH_fin = LOOKUP.findVirtual(LOOP_WITH_VIRTUALS, "fin", MT_fin);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ static MethodHandle permute(MethodHandle h) {
+ // The handles representing virtual methods need to be rearranged to match the required order of arguments
+ // (loop-local state comes first, then loop arguments). As the receiver comes first in the signature but is
+ // a loop argument, it must be moved to the appropriate position in the signature.
+ return MethodHandles.permuteArguments(h,
+ methodType(h.type().returnType(), int.class, int.class, LOOP_WITH_VIRTUALS, int.class), 2, 0, 1, 3);
+ }
+
+ }
+
+ static class While {
+
+ static int zero(int limit) {
+ return 0;
+ }
+
+ static boolean pred(int i, int limit) {
+ return i < limit;
+ }
+
+ static int step(int i, int limit) {
+ return i + 1;
+ }
+
+ static String initString() {
+ return "a";
+ }
+
+ static boolean predString(String s) {
+ return s.length() != 1;
+ }
+
+ static String stepString(String s) {
+ return s + "a";
+ }
+
+ static List<String> zipInitZip(Iterator<String> a, Iterator<String> b) {
+ return new ArrayList<>();
+ }
+
+ static boolean zipPred(List<String> zip, Iterator<String> a, Iterator<String> b) {
+ return a.hasNext() && b.hasNext();
+ }
+
+ static List<String> zipStep(List<String> zip, Iterator<String> a, Iterator<String> b) {
+ zip.add(a.next());
+ zip.add(b.next());
+ return zip;
+ }
+
+ private int i = 0;
+
+ void voidBody(int k) {
+ ++i;
+ }
+
+ boolean voidPred(int k) {
+ return i < k;
+ }
+
+ static final Class<While> WHILE = While.class;
+
+ static final MethodType MT_zero = methodType(int.class, int.class);
+ static final MethodType MT_pred = methodType(boolean.class, int.class, int.class);
+ static final MethodType MT_fn = methodType(int.class, int.class, int.class);
+ static final MethodType MT_initString = methodType(String.class);
+ static final MethodType MT_predString = methodType(boolean.class, String.class);
+ static final MethodType MT_stepString = methodType(String.class, String.class);
+ static final MethodType MT_zipInitZip = methodType(List.class, Iterator.class, Iterator.class);
+ static final MethodType MT_zipPred = methodType(boolean.class, List.class, Iterator.class, Iterator.class);
+ static final MethodType MT_zipStep = methodType(List.class, List.class, Iterator.class, Iterator.class);
+ static final MethodType MT_voidBody = methodType(void.class, int.class);
+ static final MethodType MT_voidPred = methodType(boolean.class, int.class);
+
+ static final MethodHandle MH_zero;
+ static final MethodHandle MH_pred;
+ static final MethodHandle MH_step;
+ static final MethodHandle MH_initString;
+ static final MethodHandle MH_predString;
+ static final MethodHandle MH_stepString;
+ static final MethodHandle MH_zipInitZip;
+ static final MethodHandle MH_zipPred;
+ static final MethodHandle MH_zipStep;
+ static final MethodHandle MH_voidBody;
+ static final MethodHandle MH_voidPred;
+
+ static final MethodType MT_while = methodType(int.class, int.class);
+ static final MethodType MT_string = methodType(String.class);
+ static final MethodType MT_zip = methodType(List.class, Iterator.class, Iterator.class);
+ static final MethodType MT_void = methodType(void.class, int.class);
+
+ static {
+ try {
+ MH_zero = LOOKUP.findStatic(WHILE, "zero", MT_zero);
+ MH_pred = LOOKUP.findStatic(WHILE, "pred", MT_pred);
+ MH_step = LOOKUP.findStatic(WHILE, "step", MT_fn);
+ MH_initString = LOOKUP.findStatic(WHILE, "initString", MT_initString);
+ MH_predString = LOOKUP.findStatic(WHILE, "predString", MT_predString);
+ MH_stepString = LOOKUP.findStatic(WHILE, "stepString", MT_stepString);
+ MH_zipInitZip = LOOKUP.findStatic(WHILE, "zipInitZip", MT_zipInitZip);
+ MH_zipPred = LOOKUP.findStatic(WHILE, "zipPred", MT_zipPred);
+ MH_zipStep = LOOKUP.findStatic(WHILE, "zipStep", MT_zipStep);
+ MH_voidBody = LOOKUP.findVirtual(WHILE, "voidBody", MT_voidBody);
+ MH_voidPred = LOOKUP.findVirtual(WHILE, "voidPred", MT_voidPred);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ }
+
+ static class Counted {
+
+ static String start(String arg) {
+ return arg;
+ }
+
+ static String step(int counter, String v, String arg) {
+ return "na " + v;
+ }
+
+ static void stepUpdateArray(int counter, int[] a) {
+ ++a[0];
+ }
+
+ static void printHello(int counter) {
+ System.out.print("hello");
+ }
+
+ static final Class<Counted> COUNTED = Counted.class;
+
+ static final MethodType MT_start = methodType(String.class, String.class);
+ static final MethodType MT_step = methodType(String.class, int.class, String.class, String.class);
+ static final MethodType MT_stepUpdateArray = methodType(void.class, int.class, int[].class);
+ static final MethodType MT_printHello = methodType(void.class, int.class);
+
+ static final MethodHandle MH_13;
+ static final MethodHandle MH_m5;
+ static final MethodHandle MH_8;
+ static final MethodHandle MH_start;
+ static final MethodHandle MH_step;
+ static final MethodHandle MH_stepUpdateArray;
+ static final MethodHandle MH_printHello;
+
+ static final MethodType MT_counted = methodType(String.class, String.class);
+ static final MethodType MT_arrayCounted = methodType(void.class, int[].class);
+ static final MethodType MT_countedPrinting = methodType(void.class);
+
+ static {
+ try {
+ MH_13 = MethodHandles.constant(int.class, 13);
+ MH_m5 = MethodHandles.constant(int.class, -5);
+ MH_8 = MethodHandles.constant(int.class, 8);
+ MH_start = LOOKUP.findStatic(COUNTED, "start", MT_start);
+ MH_step = LOOKUP.findStatic(COUNTED, "step", MT_step);
+ MH_stepUpdateArray = LOOKUP.findStatic(COUNTED, "stepUpdateArray", MT_stepUpdateArray);
+ MH_printHello = LOOKUP.findStatic(COUNTED, "printHello", MT_printHello);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ }
+
+ static class Iterate {
+
+ static Iterator<Integer> sumIterator(Integer[] a) {
+ return Arrays.asList(a).iterator();
+ }
+
+ static int sumInit(Integer[] a) {
+ return 0;
+ }
+
+ static int sumStep(int s, int e, Integer[] a) {
+ return s + e;
+ }
+
+ static List<String> reverseInit(List<String> l) {
+ return new ArrayList<>();
+ }
+
+ static List<String> reverseStep(String e, List<String> r, List<String> l) {
+ r.add(0, e);
+ return r;
+ }
+
+ static int lengthInit(List<Double> l) {
+ return 0;
+ }
+
+ static int lengthStep(Object o, int len, List<Double> l) {
+ return len + 1;
+ }
+
+ static List<String> mapInit(List<String> l) {
+ return new ArrayList<>();
+ }
+
+ static List<String> mapStep(String e, List<String> r, List<String> l) {
+ r.add(e.toUpperCase());
+ return r;
+ }
+
+ static void printStep(String s, List<String> l) {
+ System.out.print(s);
+ }
+
+ static final Class<Iterate> ITERATE = Iterate.class;
+
+ static final MethodType MT_sumIterator = methodType(Iterator.class, Integer[].class);
+
+ static final MethodType MT_sumInit = methodType(int.class, Integer[].class);
+ static final MethodType MT_reverseInit = methodType(List.class, List.class);
+ static final MethodType MT_lenghInit = methodType(int.class, List.class);
+ static final MethodType MT_mapInit = methodType(List.class, List.class);
+
+ static final MethodType MT_sumStep = methodType(int.class, int.class, int.class, Integer[].class);
+ static final MethodType MT_reverseStep = methodType(List.class, String.class, List.class, List.class);
+ static final MethodType MT_lengthStep = methodType(int.class, Object.class, int.class, List.class);
+ static final MethodType MT_mapStep = methodType(List.class, String.class, List.class, List.class);
+ static final MethodType MT_printStep = methodType(void.class, String.class, List.class);
+
+ static final MethodHandle MH_sumIterator;
+ static final MethodHandle MH_sumInit;
+ static final MethodHandle MH_sumStep;
+ static final MethodHandle MH_printStep;
+
+ static final MethodHandle MH_reverseInit;
+ static final MethodHandle MH_reverseStep;
+
+ static final MethodHandle MH_lengthInit;
+ static final MethodHandle MH_lengthStep;
+
+ static final MethodHandle MH_mapInit;
+ static final MethodHandle MH_mapStep;
+
+ static final MethodType MT_sum = methodType(int.class, Integer[].class);
+ static final MethodType MT_reverse = methodType(List.class, List.class);
+ static final MethodType MT_length = methodType(int.class, List.class);
+ static final MethodType MT_map = methodType(List.class, List.class);
+ static final MethodType MT_print = methodType(void.class, List.class);
+
+ static {
+ try {
+ MH_sumIterator = LOOKUP.findStatic(ITERATE, "sumIterator", MT_sumIterator);
+ MH_sumInit = LOOKUP.findStatic(ITERATE, "sumInit", MT_sumInit);
+ MH_sumStep = LOOKUP.findStatic(ITERATE, "sumStep", MT_sumStep);
+ MH_reverseInit = LOOKUP.findStatic(ITERATE, "reverseInit", MT_reverseInit);
+ MH_reverseStep = LOOKUP.findStatic(ITERATE, "reverseStep", MT_reverseStep);
+ MH_lengthInit = LOOKUP.findStatic(ITERATE, "lengthInit", MT_lenghInit);
+ MH_lengthStep = LOOKUP.findStatic(ITERATE, "lengthStep", MT_lengthStep);
+ MH_mapInit = LOOKUP.findStatic(ITERATE, "mapInit", MT_mapInit);
+ MH_mapStep = LOOKUP.findStatic(ITERATE, "mapStep", MT_mapStep);
+ MH_printStep = LOOKUP.findStatic(ITERATE, "printStep", MT_printStep);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/SpreadCollectTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ */
+
+/* @test
+ * @bug 8139885
+ * @bug 8143798
+ * @run testng/othervm -ea -esa test.java.lang.invoke.SpreadCollectTest
+ */
+
+package test.java.lang.invoke;
+
+import java.io.StringWriter;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.WrongMethodTypeException;
+import java.util.*;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.*;
+
+/**
+ * Tests for the new asSpreader/asCollector API added in JEP 274.
+ */
+public class SpreadCollectTest {
+
+ static final Lookup LOOKUP = MethodHandles.lookup();
+
+ @Test
+ public static void testAsSpreader() throws Throwable {
+ MethodHandle spreader = SpreadCollect.MH_forSpreading.asSpreader(1, int[].class, 3);
+ assertEquals(SpreadCollect.MT_spreader, spreader.type());
+ assertEquals("A456B", (String) spreader.invoke("A", new int[]{4, 5, 6}, "B"));
+ }
+
+ @Test
+ public static void testAsSpreaderExample() throws Throwable {
+ // test the JavaDoc asSpreader-with-pos example
+ MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class));
+ MethodHandle compare2FromArray = compare.asSpreader(0, Object[].class, 2);
+ Object[] ints = new Object[]{3, 9, 7, 7};
+ Comparator<Integer> cmp = (a, b) -> a - b;
+ assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 0, 2), cmp) < 0);
+ assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 1, 3), cmp) > 0);
+ assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 2, 4), cmp) == 0);
+ }
+
+ @DataProvider
+ static Object[][] asSpreaderIllegalPositions() {
+ return new Object[][]{{-7}, {3}, {19}};
+ }
+
+ @Test(dataProvider = "asSpreaderIllegalPositions")
+ public static void testAsSpreaderIllegalPos(int p) throws Throwable {
+ boolean caught = false;
+ try {
+ SpreadCollect.MH_forSpreading.asSpreader(p, Object[].class, 3);
+ } catch (IllegalArgumentException iae) {
+ assertEquals("bad spread position", iae.getMessage());
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ @Test(expectedExceptions = {WrongMethodTypeException.class})
+ public static void testAsSpreaderIllegalMethodType() {
+ MethodHandle h = MethodHandles.dropArguments(MethodHandles.constant(String.class, ""), 0, int.class, int.class);
+ MethodHandle s = h.asSpreader(String[].class, 1);
+ }
+
+ @Test
+ public static void testAsCollector() throws Throwable {
+ MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1);
+ assertEquals(SpreadCollect.MT_collector1, collector.type());
+ assertEquals("A4B", (String) collector.invoke("A", 4, "B"));
+ collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 2);
+ assertEquals(SpreadCollect.MT_collector2, collector.type());
+ assertEquals("A45B", (String) collector.invoke("A", 4, 5, "B"));
+ collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 3);
+ assertEquals(SpreadCollect.MT_collector3, collector.type());
+ assertEquals("A456B", (String) collector.invoke("A", 4, 5, 6, "B"));
+ }
+
+ @Test
+ public static void testAsCollectorInvokeWithArguments() throws Throwable {
+ MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1);
+ assertEquals(SpreadCollect.MT_collector1, collector.type());
+ assertEquals("A4B", (String) collector.invokeWithArguments("A", 4, "B"));
+ collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 2);
+ assertEquals(SpreadCollect.MT_collector2, collector.type());
+ assertEquals("A45B", (String) collector.invokeWithArguments("A", 4, 5, "B"));
+ collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 3);
+ assertEquals(SpreadCollect.MT_collector3, collector.type());
+ assertEquals("A456B", (String) collector.invokeWithArguments("A", 4, 5, 6, "B"));
+ }
+
+ @Test
+ public static void testAsCollectorLeading() throws Throwable {
+ MethodHandle collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 1);
+ assertEquals(SpreadCollect.MT_collectorLeading1, collector.type());
+ assertEquals("7Q", (String) collector.invoke(7, "Q"));
+ collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 2);
+ assertEquals(SpreadCollect.MT_collectorLeading2, collector.type());
+ assertEquals("78Q", (String) collector.invoke(7, 8, "Q"));
+ collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 3);
+ assertEquals(SpreadCollect.MT_collectorLeading3, collector.type());
+ assertEquals("789Q", (String) collector.invoke(7, 8, 9, "Q"));
+ }
+
+ @Test
+ public static void testAsCollectorLeadingInvokeWithArguments() throws Throwable {
+ MethodHandle collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 1);
+ assertEquals(SpreadCollect.MT_collectorLeading1, collector.type());
+ assertEquals("7Q", (String) collector.invokeWithArguments(7, "Q"));
+ collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 2);
+ assertEquals(SpreadCollect.MT_collectorLeading2, collector.type());
+ assertEquals("78Q", (String) collector.invokeWithArguments(7, 8, "Q"));
+ collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 3);
+ assertEquals(SpreadCollect.MT_collectorLeading3, collector.type());
+ assertEquals("789Q", (String) collector.invokeWithArguments(7, 8, 9, "Q"));
+ }
+
+ @Test
+ public static void testAsCollectorNone() throws Throwable {
+ MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 0);
+ assertEquals(SpreadCollect.MT_collector0, collector.type());
+ assertEquals("AB", (String) collector.invoke("A", "B"));
+ }
+
+ @DataProvider
+ static Object[][] asCollectorIllegalPositions() {
+ return new Object[][]{{-1}, {17}};
+ }
+
+ @Test(dataProvider = "asCollectorIllegalPositions")
+ public static void testAsCollectorIllegalPos(int p) {
+ boolean caught = false;
+ try {
+ SpreadCollect.MH_forCollecting.asCollector(p, int[].class, 0);
+ } catch (IllegalArgumentException iae) {
+ assertEquals("bad collect position", iae.getMessage());
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ @Test
+ public static void testAsCollectorExample() throws Throwable {
+ // test the JavaDoc asCollector-with-pos example
+ StringWriter swr = new StringWriter();
+ MethodHandle swWrite = LOOKUP.
+ findVirtual(StringWriter.class, "write", methodType(void.class, char[].class, int.class, int.class)).
+ bindTo(swr);
+ MethodHandle swWrite4 = swWrite.asCollector(0, char[].class, 4);
+ swWrite4.invoke('A', 'B', 'C', 'D', 1, 2);
+ assertEquals("BC", swr.toString());
+ swWrite4.invoke('P', 'Q', 'R', 'S', 0, 4);
+ assertEquals("BCPQRS", swr.toString());
+ swWrite4.invoke('W', 'X', 'Y', 'Z', 3, 1);
+ assertEquals("BCPQRSZ", swr.toString());
+ }
+
+ static class SpreadCollect {
+
+ static String forSpreading(String s1, int i1, int i2, int i3, String s2) {
+ return s1 + i1 + i2 + i3 + s2;
+ }
+
+ static String forCollecting(String s1, int[] is, String s2) {
+ StringBuilder sb = new StringBuilder(s1);
+ for (int i : is) {
+ sb.append(i);
+ }
+ return sb.append(s2).toString();
+ }
+
+ static String forCollectingLeading(int[] is, String s) {
+ return forCollecting("", is, s);
+ }
+
+ static final Class<SpreadCollect> SPREAD_COLLECT = SpreadCollect.class;
+
+ static final MethodType MT_forSpreading = methodType(String.class, String.class, int.class, int.class, int.class, String.class);
+ static final MethodType MT_forCollecting = methodType(String.class, String.class, int[].class, String.class);
+ static final MethodType MT_forCollectingLeading = methodType(String.class, int[].class, String.class);
+
+ static final MethodHandle MH_forSpreading;
+ static final MethodHandle MH_forCollecting;
+ static final MethodHandle MH_forCollectingLeading;
+
+ static final MethodType MT_spreader = methodType(String.class, String.class, int[].class, String.class);
+ static final MethodType MT_collector0 = methodType(String.class, String.class, String.class);
+ static final MethodType MT_collector1 = methodType(String.class, String.class, int.class, String.class);
+ static final MethodType MT_collector2 = methodType(String.class, String.class, int.class, int.class, String.class);
+ static final MethodType MT_collector3 = methodType(String.class, String.class, int.class, int.class, int.class, String.class);
+ static final MethodType MT_collectorLeading1 = methodType(String.class, int.class, String.class);
+ static final MethodType MT_collectorLeading2 = methodType(String.class, int.class, int.class, String.class);
+ static final MethodType MT_collectorLeading3 = methodType(String.class, int.class, int.class, int.class, String.class);
+
+ static final String NONE_ERROR = "zero array length in MethodHandle.asCollector";
+
+ static {
+ try {
+ MH_forSpreading = LOOKUP.findStatic(SPREAD_COLLECT, "forSpreading", MT_forSpreading);
+ MH_forCollecting = LOOKUP.findStatic(SPREAD_COLLECT, "forCollecting", MT_forCollecting);
+ MH_forCollectingLeading = LOOKUP.findStatic(SPREAD_COLLECT, "forCollectingLeading", MT_forCollectingLeading);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ }
+
+}
--- a/jdk/test/java/lang/invoke/T8139885.java Thu Mar 03 12:25:57 2016 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1111 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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.
- */
-
-/* @test
- * @bug 8139885
- * @bug 8143798
- * @bug 8150825
- * @run testng/othervm -ea -esa test.java.lang.invoke.T8139885
- */
-
-package test.java.lang.invoke;
-
-import java.io.StringWriter;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.invoke.MethodType;
-import java.lang.invoke.WrongMethodTypeException;
-import java.util.*;
-
-import static java.lang.invoke.MethodType.methodType;
-
-import static org.testng.AssertJUnit.*;
-
-import org.testng.annotations.*;
-
-/**
- * Example-scale and negative tests for JEP 274 extensions.
- */
-public class T8139885 {
-
- static final Lookup LOOKUP = MethodHandles.lookup();
-
- //
- // Tests.
- //
-
- @Test
- public static void testLoopFac() throws Throwable {
- MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc};
- MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
- MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
- assertEquals(Fac.MT_fac, loop.type());
- assertEquals(120, loop.invoke(5));
- }
-
- @Test
- public static void testLoopFacNullInit() throws Throwable {
- // null initializer for counter, should initialize to 0
- MethodHandle[] counterClause = new MethodHandle[]{null, Fac.MH_inc};
- MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
- MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
- assertEquals(Fac.MT_fac, loop.type());
- assertEquals(120, loop.invoke(5));
- }
-
- @Test
- public static void testLoopVoid1() throws Throwable {
- // construct a post-checked loop that only does one iteration and has a void body and void local state
- MethodHandle loop = MethodHandles.loop(new MethodHandle[]{Empty.MH_f, Empty.MH_f, Empty.MH_pred, null});
- assertEquals(MethodType.methodType(void.class), loop.type());
- loop.invoke();
- }
-
- @Test
- public static void testLoopVoid2() throws Throwable {
- // construct a post-checked loop that only does one iteration and has a void body and void local state,
- // initialized implicitly from the step type
- MethodHandle loop = MethodHandles.loop(new MethodHandle[]{null, Empty.MH_f, Empty.MH_pred, null});
- assertEquals(MethodType.methodType(void.class), loop.type());
- loop.invoke();
- }
-
- @Test
- public static void testLoopFacWithVoidState() throws Throwable {
- // like testLoopFac, but with additional void state that outputs a dot
- MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc};
- MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin};
- MethodHandle[] dotClause = new MethodHandle[]{null, Fac.MH_dot};
- MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause, dotClause);
- assertEquals(Fac.MT_fac, loop.type());
- assertEquals(120, loop.invoke(5));
- }
-
- @Test
- public static void testLoopNegative() throws Throwable {
- MethodHandle mh_loop =
- LOOKUP.findStatic(MethodHandles.class, "loop", methodType(MethodHandle.class, MethodHandle[][].class));
- MethodHandle i0 = MethodHandles.constant(int.class, 0);
- MethodHandle ii = MethodHandles.dropArguments(i0, 0, int.class, int.class);
- MethodHandle id = MethodHandles.dropArguments(i0, 0, int.class, double.class);
- MethodHandle i3 = MethodHandles.dropArguments(i0, 0, int.class, int.class, int.class);
- List<MethodHandle> inits = Arrays.asList(ii, id, i3);
- List<Class<?>> ints = Arrays.asList(int.class, int.class, int.class);
- List<MethodHandle> finis = Arrays.asList(Fac.MH_fin, Fac.MH_inc, Counted.MH_step);
- List<MethodHandle> preds1 = Arrays.asList(null, null, null);
- List<MethodHandle> preds2 = Arrays.asList(null, Fac.MH_fin, null);
- MethodHandle eek = MethodHandles.dropArguments(i0, 0, int.class, int.class, double.class);
- List<MethodHandle> nesteps = Arrays.asList(Fac.MH_inc, eek, Fac.MH_dot);
- List<MethodHandle> nepreds = Arrays.asList(null, Fac.MH_pred, null);
- List<MethodHandle> nefinis = Arrays.asList(null, Fac.MH_fin, null);
- MethodHandle[][][] cases = {
- null,
- {},
- {{null, Fac.MH_inc}, {Fac.MH_one, null, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin}},
- {{null, Fac.MH_inc}, null},
- {{Fac.MH_zero, Fac.MH_dot}},
- {{ii}, {id}, {i3}},
- {{null, Fac.MH_inc, null, Fac.MH_fin}, {null, Fac.MH_inc, null, Fac.MH_inc},
- {null, Counted.MH_start, null, Counted.MH_step}},
- {{Fac.MH_zero, Fac.MH_inc}, {Fac.MH_one, Fac.MH_mult, null, Fac.MH_fin}, {null, Fac.MH_dot}},
- {{Fac.MH_zero, Fac.MH_inc}, {Fac.MH_one, Fac.MH_mult, Fac.MH_fin, Fac.MH_fin}, {null, Fac.MH_dot}},
- {{Fac.MH_zero, Fac.MH_inc}, {Fac.MH_one, eek, Fac.MH_pred, Fac.MH_fin}, {null, Fac.MH_dot}}
- };
- String[] messages = {
- "null or no clauses passed",
- "null or no clauses passed",
- "All loop clauses must be represented as MethodHandle arrays with at most 4 elements.",
- "null clauses are not allowed",
- "clause 0: init and step return types must match: int != void",
- "found non-effectively identical init parameter type lists: " + inits + " (common suffix: " + ints + ")",
- "found non-identical finalizer return types: " + finis + " (return type: int)",
- "no predicate found: " + preds1,
- "predicates must have boolean return type: " + preds2,
- "found non-effectively identical parameter type lists:\nstep: " + nesteps + "\npred: " + nepreds +
- "\nfini: " + nefinis + " (common parameter sequence: " + ints + ")"
- };
- for (int i = 0; i < cases.length; ++i) {
- boolean caught = false;
- try {
- mh_loop.invokeWithArguments(cases[i]);
- } catch (IllegalArgumentException iae) {
- assertEquals(messages[i], iae.getMessage());
- caught = true;
- }
- assertTrue(caught);
- }
- }
-
- @Test
- public static void testWhileLoop() throws Throwable {
- // int i = 0; while (i < limit) { ++i; } return i; => limit
- MethodHandle loop = MethodHandles.whileLoop(While.MH_zero, While.MH_pred, While.MH_step);
- assertEquals(While.MT_while, loop.type());
- assertEquals(23, loop.invoke(23));
- }
-
- @Test
- public static void testWhileLoopNoIteration() throws Throwable {
- // a while loop that never executes its body because the predicate evaluates to false immediately
- MethodHandle loop = MethodHandles.whileLoop(While.MH_initString, While.MH_predString, While.MH_stepString);
- assertEquals(While.MT_string, loop.type());
- assertEquals("a", loop.invoke());
- }
-
- @Test
- public static void testDoWhileLoop() throws Throwable {
- // int i = 0; do { ++i; } while (i < limit); return i; => limit
- MethodHandle loop = MethodHandles.doWhileLoop(While.MH_zero, While.MH_step, While.MH_pred);
- assertEquals(While.MT_while, loop.type());
- assertEquals(23, loop.invoke(23));
- }
-
- @Test
- public static void testWhileZip() throws Throwable {
- MethodHandle loop = MethodHandles.doWhileLoop(While.MH_zipInitZip, While.MH_zipStep, While.MH_zipPred);
- assertEquals(While.MT_zip, loop.type());
- List<String> a = Arrays.asList("a", "b", "c", "d");
- List<String> b = Arrays.asList("e", "f", "g", "h");
- List<String> zipped = Arrays.asList("a", "e", "b", "f", "c", "g", "d", "h");
- assertEquals(zipped, (List<String>) loop.invoke(a.iterator(), b.iterator()));
- }
-
- @Test
- public static void testCountedLoop() throws Throwable {
- // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s; => a variation on a well known theme
- MethodHandle fit13 = MethodHandles.constant(int.class, 13);
- MethodHandle loop = MethodHandles.countedLoop(fit13, Counted.MH_start, Counted.MH_step);
- assertEquals(Counted.MT_counted, loop.type());
- assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
- }
-
- @Test
- public static void testCountedArrayLoop() throws Throwable {
- // int[] a = new int[]{0}; for (int i = 0; i < 13; ++i) { ++a[0]; } => a[0] == 13
- MethodHandle fit13 = MethodHandles.dropArguments(MethodHandles.constant(int.class, 13), 0, int[].class);
- MethodHandle loop = MethodHandles.countedLoop(fit13, null, Counted.MH_stepUpdateArray);
- assertEquals(Counted.MT_arrayCounted, loop.type());
- int[] a = new int[]{0};
- loop.invoke(a);
- assertEquals(13, a[0]);
- }
-
- @Test
- public static void testCountedPrintingLoop() throws Throwable {
- MethodHandle fit5 = MethodHandles.constant(int.class, 5);
- MethodHandle loop = MethodHandles.countedLoop(fit5, null, Counted.MH_printHello);
- assertEquals(Counted.MT_countedPrinting, loop.type());
- loop.invoke();
- }
-
- @Test
- public static void testCountedRangeLoop() throws Throwable {
- // String s = "Lambdaman!"; for (int i = -5; i < 8; ++i) { s = "na " + s; } return s; => a well known theme
- MethodHandle fitm5 = MethodHandles.dropArguments(Counted.MH_m5, 0, String.class);
- MethodHandle fit8 = MethodHandles.dropArguments(Counted.MH_8, 0, String.class);
- MethodHandle loop = MethodHandles.countedLoop(fitm5, fit8, Counted.MH_start, Counted.MH_step);
- assertEquals(Counted.MT_counted, loop.type());
- assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
- }
-
- @Test
- public static void testIterateSum() throws Throwable {
- // Integer[] a = new Integer[]{1,2,3,4,5,6}; int sum = 0; for (int e : a) { sum += e; } return sum; => 21
- MethodHandle loop = MethodHandles.iteratedLoop(Iterate.MH_sumIterator, Iterate.MH_sumInit, Iterate.MH_sumStep);
- assertEquals(Iterate.MT_sum, loop.type());
- assertEquals(21, loop.invoke(new Integer[]{1, 2, 3, 4, 5, 6}));
- }
-
- @Test
- public static void testIterateReverse() throws Throwable {
- MethodHandle loop = MethodHandles.iteratedLoop(null, Iterate.MH_reverseInit, Iterate.MH_reverseStep);
- assertEquals(Iterate.MT_reverse, loop.type());
- List<String> list = Arrays.asList("a", "b", "c", "d", "e");
- List<String> reversedList = Arrays.asList("e", "d", "c", "b", "a");
- assertEquals(reversedList, (List<String>) loop.invoke(list));
- }
-
- @Test
- public static void testIterateLength() throws Throwable {
- MethodHandle loop = MethodHandles.iteratedLoop(null, Iterate.MH_lengthInit, Iterate.MH_lengthStep);
- assertEquals(Iterate.MT_length, loop.type());
- List<Double> list = Arrays.asList(23.0, 148.0, 42.0);
- assertEquals(list.size(), (int) loop.invoke(list));
- }
-
- @Test
- public static void testIterateMap() throws Throwable {
- MethodHandle loop = MethodHandles.iteratedLoop(null, Iterate.MH_mapInit, Iterate.MH_mapStep);
- assertEquals(Iterate.MT_map, loop.type());
- List<String> list = Arrays.asList("Hello", "world", "!");
- List<String> upList = Arrays.asList("HELLO", "WORLD", "!");
- assertEquals(upList, (List<String>) loop.invoke(list));
- }
-
- @Test
- public static void testIteratePrint() throws Throwable {
- MethodHandle loop = MethodHandles.iteratedLoop(null, null, Iterate.MH_printStep);
- assertEquals(Iterate.MT_print, loop.type());
- loop.invoke(Arrays.asList("hello", "world"));
- }
-
- @Test
- public static void testIterateNullBody() {
- boolean caught = false;
- try {
- MethodHandles.iteratedLoop(MethodHandles.identity(int.class), MethodHandles.identity(int.class), null);
- } catch (IllegalArgumentException iae) {
- assertEquals("iterated loop body must not be null", iae.getMessage());
- caught = true;
- }
- assertTrue(caught);
- }
-
- @Test
- public static void testTryFinally() throws Throwable {
- MethodHandle hello = MethodHandles.tryFinally(TryFinally.MH_greet, TryFinally.MH_exclaim);
- assertEquals(TryFinally.MT_hello, hello.type());
- assertEquals("Hello, world!", hello.invoke("world"));
- }
-
- @Test
- public static void testTryFinallyVoid() throws Throwable {
- MethodHandle tfVoid = MethodHandles.tryFinally(TryFinally.MH_print, TryFinally.MH_printMore);
- assertEquals(TryFinally.MT_printHello, tfVoid.type());
- tfVoid.invoke("world");
- }
-
- @Test
- public static void testTryFinallySublist() throws Throwable {
- MethodHandle helloMore = MethodHandles.tryFinally(TryFinally.MH_greetMore, TryFinally.MH_exclaimMore);
- assertEquals(TryFinally.MT_moreHello, helloMore.type());
- assertEquals("Hello, world and universe (but world first)!", helloMore.invoke("world", "universe"));
- }
-
- @Test
- public static void testTryFinallyNegative() {
- MethodHandle intid = MethodHandles.identity(int.class);
- MethodHandle intco = MethodHandles.constant(int.class, 0);
- MethodHandle errTarget = MethodHandles.dropArguments(intco, 0, int.class, double.class, String.class, int.class);
- MethodHandle errCleanup = MethodHandles.dropArguments(MethodHandles.constant(int.class, 0), 0, Throwable.class,
- int.class, double.class, Object.class);
- MethodHandle[][] cases = {
- {intid, MethodHandles.identity(double.class)},
- {intid, MethodHandles.dropArguments(intid, 0, String.class)},
- {intid, MethodHandles.dropArguments(intid, 0, Throwable.class, double.class)},
- {errTarget, errCleanup},
- {TryFinally.MH_voidTarget, TryFinally.MH_voidCleanup}
- };
- String[] messages = {
- "target and return types must match: double != int",
- "cleanup first argument and Throwable must match: (String,int)int != class java.lang.Throwable",
- "cleanup second argument and target return type must match: (Throwable,double,int)int != int",
- "cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
- errCleanup.type() + " != " + errTarget.type(),
- "cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
- TryFinally.MH_voidCleanup.type() + " != " + TryFinally.MH_voidTarget.type()
- };
- for (int i = 0; i < cases.length; ++i) {
- boolean caught = false;
- try {
- MethodHandles.tryFinally(cases[i][0], cases[i][1]);
- } catch (IllegalArgumentException iae) {
- assertEquals(messages[i], iae.getMessage());
- caught = true;
- }
- assertTrue(caught);
- }
- }
-
- @Test
- public static void testFold0a() throws Throwable {
- // equivalence to foldArguments(MethodHandle,MethodHandle)
- MethodHandle fold = MethodHandles.foldArguments(Fold.MH_multer, 0, Fold.MH_adder);
- assertEquals(Fold.MT_folded1, fold.type());
- assertEquals(720, (int) fold.invoke(3, 4, 5));
- }
-
- @Test
- public static void testFold1a() throws Throwable {
- // test foldArguments for folding position 1
- MethodHandle fold = MethodHandles.foldArguments(Fold.MH_multer, 1, Fold.MH_adder1);
- assertEquals(Fold.MT_folded1, fold.type());
- assertEquals(540, (int) fold.invoke(3, 4, 5));
- }
-
- @Test
- public static void testFold0b() throws Throwable {
- // test foldArguments equivalence with multiple types
- MethodHandle fold = MethodHandles.foldArguments(Fold.MH_str, 0, Fold.MH_comb);
- assertEquals(Fold.MT_folded2, fold.type());
- assertEquals(23, (int) fold.invoke("true", true, 23));
- }
-
- @Test
- public static void testFold1b() throws Throwable {
- // test folgArguments for folding position 1, with multiple types
- MethodHandle fold = MethodHandles.foldArguments(Fold.MH_str, 1, Fold.MH_comb2);
- assertEquals(Fold.MT_folded3, fold.type());
- assertEquals(1, (int) fold.invoke(true, true, 1));
- assertEquals(-1, (int) fold.invoke(true, false, -1));
- }
-
- @Test
- public static void testFoldArgumentsExample() throws Throwable {
- // test the JavaDoc foldArguments-with-pos example
- StringWriter swr = new StringWriter();
- MethodHandle trace = LOOKUP.findVirtual(StringWriter.class, "write", methodType(void.class, String.class)).bindTo(swr);
- MethodHandle cat = LOOKUP.findVirtual(String.class, "concat", methodType(String.class, String.class));
- assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
- MethodHandle catTrace = MethodHandles.foldArguments(cat, 1, trace);
- assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
- assertEquals("jum", swr.toString());
- }
-
- @Test
- public static void testAsSpreader() throws Throwable {
- MethodHandle spreader = SpreadCollect.MH_forSpreading.asSpreader(1, int[].class, 3);
- assertEquals(SpreadCollect.MT_spreader, spreader.type());
- assertEquals("A456B", (String) spreader.invoke("A", new int[]{4, 5, 6}, "B"));
- }
-
- @Test
- public static void testAsSpreaderExample() throws Throwable {
- // test the JavaDoc asSpreader-with-pos example
- MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class));
- MethodHandle compare2FromArray = compare.asSpreader(0, Object[].class, 2);
- Object[] ints = new Object[]{3, 9, 7, 7};
- Comparator<Integer> cmp = (a, b) -> a - b;
- assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 0, 2), cmp) < 0);
- assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 1, 3), cmp) > 0);
- assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 2, 4), cmp) == 0);
- }
-
- @Test
- public static void testAsSpreaderIllegalPos() throws Throwable {
- int[] illegalPos = {-7, 3, 19};
- int caught = 0;
- for (int p : illegalPos) {
- try {
- SpreadCollect.MH_forSpreading.asSpreader(p, Object[].class, 3);
- } catch (IllegalArgumentException iae) {
- assertEquals("bad spread position", iae.getMessage());
- ++caught;
- }
- }
- assertEquals(illegalPos.length, caught);
- }
-
- @Test
- public static void testAsSpreaderIllegalMethodType() throws Throwable {
- MethodHandle h = MethodHandles.dropArguments(MethodHandles.constant(String.class, ""), 0, int.class, int.class);
- boolean caught = false;
- try {
- MethodHandle s = h.asSpreader(String[].class, 1);
- } catch (WrongMethodTypeException wmte) {
- caught = true;
- }
- assertTrue(caught);
- }
-
- @Test
- public static void testAsCollector() throws Throwable {
- MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1);
- assertEquals(SpreadCollect.MT_collector1, collector.type());
- assertEquals("A4B", (String) collector.invoke("A", 4, "B"));
- collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 2);
- assertEquals(SpreadCollect.MT_collector2, collector.type());
- assertEquals("A45B", (String) collector.invoke("A", 4, 5, "B"));
- collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 3);
- assertEquals(SpreadCollect.MT_collector3, collector.type());
- assertEquals("A456B", (String) collector.invoke("A", 4, 5, 6, "B"));
- }
-
- @Test
- public static void testAsCollectorInvokeWithArguments() throws Throwable {
- MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1);
- assertEquals(SpreadCollect.MT_collector1, collector.type());
- assertEquals("A4B", (String) collector.invokeWithArguments("A", 4, "B"));
- collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 2);
- assertEquals(SpreadCollect.MT_collector2, collector.type());
- assertEquals("A45B", (String) collector.invokeWithArguments("A", 4, 5, "B"));
- collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 3);
- assertEquals(SpreadCollect.MT_collector3, collector.type());
- assertEquals("A456B", (String) collector.invokeWithArguments("A", 4, 5, 6, "B"));
- }
-
- @Test
- public static void testAsCollectorLeading() throws Throwable {
- MethodHandle collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 1);
- assertEquals(SpreadCollect.MT_collectorLeading1, collector.type());
- assertEquals("7Q", (String) collector.invoke(7, "Q"));
- collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 2);
- assertEquals(SpreadCollect.MT_collectorLeading2, collector.type());
- assertEquals("78Q", (String) collector.invoke(7, 8, "Q"));
- collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 3);
- assertEquals(SpreadCollect.MT_collectorLeading3, collector.type());
- assertEquals("789Q", (String) collector.invoke(7, 8, 9, "Q"));
- }
-
- @Test
- public static void testAsCollectorLeadingInvokeWithArguments() throws Throwable {
- MethodHandle collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 1);
- assertEquals(SpreadCollect.MT_collectorLeading1, collector.type());
- assertEquals("7Q", (String) collector.invokeWithArguments(7, "Q"));
- collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 2);
- assertEquals(SpreadCollect.MT_collectorLeading2, collector.type());
- assertEquals("78Q", (String) collector.invokeWithArguments(7, 8, "Q"));
- collector = SpreadCollect.MH_forCollectingLeading.asCollector(0, int[].class, 3);
- assertEquals(SpreadCollect.MT_collectorLeading3, collector.type());
- assertEquals("789Q", (String) collector.invokeWithArguments(7, 8, 9, "Q"));
- }
-
- @Test
- public static void testAsCollectorNone() throws Throwable {
- MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 0);
- assertEquals(SpreadCollect.MT_collector0, collector.type());
- assertEquals("AB", (String) collector.invoke("A", "B"));
- }
-
- @Test
- public static void testAsCollectorIllegalPos() throws Throwable {
- int[] illegalPos = {-1, 17};
- int caught = 0;
- for (int p : illegalPos) {
- try {
- SpreadCollect.MH_forCollecting.asCollector(p, int[].class, 0);
- } catch (IllegalArgumentException iae) {
- assertEquals("bad collect position", iae.getMessage());
- ++caught;
- }
- }
- assertEquals(illegalPos.length, caught);
- }
-
- @Test
- public static void testAsCollectorExample() throws Throwable {
- // test the JavaDoc asCollector-with-pos example
- StringWriter swr = new StringWriter();
- MethodHandle swWrite = LOOKUP.
- findVirtual(StringWriter.class, "write", methodType(void.class, char[].class, int.class, int.class)).
- bindTo(swr);
- MethodHandle swWrite4 = swWrite.asCollector(0, char[].class, 4);
- swWrite4.invoke('A', 'B', 'C', 'D', 1, 2);
- assertEquals("BC", swr.toString());
- swWrite4.invoke('P', 'Q', 'R', 'S', 0, 4);
- assertEquals("BCPQRS", swr.toString());
- swWrite4.invoke('W', 'X', 'Y', 'Z', 3, 1);
- assertEquals("BCPQRSZ", swr.toString());
- }
-
- @Test
- public static void testFindSpecial() throws Throwable {
- FindSpecial.C c = new FindSpecial.C();
- assertEquals("I1.m", c.m());
- MethodType t = MethodType.methodType(String.class);
- MethodHandle ci1m = LOOKUP.findSpecial(FindSpecial.I1.class, "m", t, FindSpecial.C.class);
- assertEquals("I1.m", (String) ci1m.invoke(c));
- }
-
- @Test
- public static void testFindSpecialAbstract() throws Throwable {
- FindSpecial.C c = new FindSpecial.C();
- assertEquals("q", c.q());
- MethodType t = MethodType.methodType(String.class);
- boolean caught = false;
- try {
- MethodHandle ci3q = LOOKUP.findSpecial(FindSpecial.I3.class, "q", t, FindSpecial.C.class);
- } catch (Throwable thrown) {
- if (!(thrown instanceof IllegalAccessException) || !FindSpecial.ABSTRACT_ERROR.equals(thrown.getMessage())) {
- throw new AssertionError(thrown.getMessage(), thrown);
- }
- caught = true;
- }
- assertTrue(caught);
- }
-
- @Test
- public static void testFindClassCNFE() throws Throwable {
- boolean caught = false;
- try {
- LOOKUP.findClass("does.not.Exist");
- } catch (ClassNotFoundException cnfe) {
- caught = true;
- }
- assertTrue(caught);
- }
-
- //
- // Methods used to assemble tests.
- //
-
- static class Empty {
-
- static void f() { }
-
- static boolean pred() {
- return false;
- }
-
- static final Class<Empty> EMPTY = Empty.class;
-
- static final MethodType MT_f = methodType(void.class);
- static final MethodType MT_pred = methodType(boolean.class);
-
- static final MethodHandle MH_f;
- static final MethodHandle MH_pred;
-
- static {
- try {
- MH_f = LOOKUP.findStatic(EMPTY, "f", MT_f);
- MH_pred = LOOKUP.findStatic(EMPTY, "pred", MT_pred);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
- }
-
- static class Fac {
-
- static int zero(int k) {
- return 0;
- }
-
- static int one(int k) {
- return 1;
- }
-
- static boolean pred(int i, int acc, int k) {
- return i < k;
- }
-
- static int inc(int i, int acc, int k) {
- return i + 1;
- }
-
- static int mult(int i, int acc, int k) {
- return i * acc;
- }
-
- static void dot(int i, int acc, int k) {
- System.out.print('.');
- }
-
- static int fin(int i, int acc, int k) {
- return acc;
- }
-
- static final Class<Fac> FAC = Fac.class;
-
- static final MethodType MT_init = methodType(int.class, int.class);
- static final MethodType MT_fn = methodType(int.class, int.class, int.class, int.class);
- static final MethodType MT_dot = methodType(void.class, int.class, int.class, int.class);
- static final MethodType MT_pred = methodType(boolean.class, int.class, int.class, int.class);
-
- static final MethodHandle MH_zero;
- static final MethodHandle MH_one;
- static final MethodHandle MH_pred;
- static final MethodHandle MH_inc;
- static final MethodHandle MH_mult;
- static final MethodHandle MH_dot;
- static final MethodHandle MH_fin;
-
- static final MethodType MT_fac = methodType(int.class, int.class);
-
- static {
- try {
- MH_zero = LOOKUP.findStatic(FAC, "zero", MT_init);
- MH_one = LOOKUP.findStatic(FAC, "one", MT_init);
- MH_pred = LOOKUP.findStatic(FAC, "pred", MT_pred);
- MH_inc = LOOKUP.findStatic(FAC, "inc", MT_fn);
- MH_mult = LOOKUP.findStatic(FAC, "mult", MT_fn);
- MH_dot = LOOKUP.findStatic(FAC, "dot", MT_dot);
- MH_fin = LOOKUP.findStatic(FAC, "fin", MT_fn);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- }
-
- static class While {
-
- static int zero(int limit) {
- return 0;
- }
-
- static boolean pred(int i, int limit) {
- return i < limit;
- }
-
- static int step(int i, int limit) {
- return i + 1;
- }
-
- static String initString() {
- return "a";
- }
-
- static boolean predString(String s) {
- return s.length() != 1;
- }
-
- static String stepString(String s) {
- return s + "a";
- }
-
- static List<String> zipInitZip(Iterator<String> a, Iterator<String> b) {
- return new ArrayList<>();
- }
-
- static boolean zipPred(List<String> zip, Iterator<String> a, Iterator<String> b) {
- return a.hasNext() && b.hasNext();
- }
-
- static List<String> zipStep(List<String> zip, Iterator<String> a, Iterator<String> b) {
- zip.add(a.next());
- zip.add(b.next());
- return zip;
- }
-
- static final Class<While> WHILE = While.class;
-
- static final MethodType MT_zero = methodType(int.class, int.class);
- static final MethodType MT_pred = methodType(boolean.class, int.class, int.class);
- static final MethodType MT_fn = methodType(int.class, int.class, int.class);
- static final MethodType MT_initString = methodType(String.class);
- static final MethodType MT_predString = methodType(boolean.class, String.class);
- static final MethodType MT_stepString = methodType(String.class, String.class);
- static final MethodType MT_zipInitZip = methodType(List.class, Iterator.class, Iterator.class);
- static final MethodType MT_zipPred = methodType(boolean.class, List.class, Iterator.class, Iterator.class);
- static final MethodType MT_zipStep = methodType(List.class, List.class, Iterator.class, Iterator.class);
-
- static final MethodHandle MH_zero;
- static final MethodHandle MH_pred;
- static final MethodHandle MH_step;
- static final MethodHandle MH_initString;
- static final MethodHandle MH_predString;
- static final MethodHandle MH_stepString;
- static final MethodHandle MH_zipInitZip;
- static final MethodHandle MH_zipPred;
- static final MethodHandle MH_zipStep;
-
- static final MethodType MT_while = methodType(int.class, int.class);
- static final MethodType MT_string = methodType(String.class);
- static final MethodType MT_zip = methodType(List.class, Iterator.class, Iterator.class);
-
- static {
- try {
- MH_zero = LOOKUP.findStatic(WHILE, "zero", MT_zero);
- MH_pred = LOOKUP.findStatic(WHILE, "pred", MT_pred);
- MH_step = LOOKUP.findStatic(WHILE, "step", MT_fn);
- MH_initString = LOOKUP.findStatic(WHILE, "initString", MT_initString);
- MH_predString = LOOKUP.findStatic(WHILE, "predString", MT_predString);
- MH_stepString = LOOKUP.findStatic(WHILE, "stepString", MT_stepString);
- MH_zipInitZip = LOOKUP.findStatic(WHILE, "zipInitZip", MT_zipInitZip);
- MH_zipPred = LOOKUP.findStatic(WHILE, "zipPred", MT_zipPred);
- MH_zipStep = LOOKUP.findStatic(WHILE, "zipStep", MT_zipStep);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- }
-
- static class Counted {
-
- static String start(String arg) {
- return arg;
- }
-
- static String step(int counter, String v, String arg) {
- return "na " + v;
- }
-
- static void stepUpdateArray(int counter, int[] a) {
- ++a[0];
- }
-
- static void printHello(int counter) {
- System.out.print("hello");
- }
-
- static final Class<Counted> COUNTED = Counted.class;
-
- static final MethodType MT_start = methodType(String.class, String.class);
- static final MethodType MT_step = methodType(String.class, int.class, String.class, String.class);
- static final MethodType MT_stepUpdateArray = methodType(void.class, int.class, int[].class);
- static final MethodType MT_printHello = methodType(void.class, int.class);
-
- static final MethodHandle MH_13;
- static final MethodHandle MH_m5;
- static final MethodHandle MH_8;
- static final MethodHandle MH_start;
- static final MethodHandle MH_step;
- static final MethodHandle MH_stepUpdateArray;
- static final MethodHandle MH_printHello;
-
- static final MethodType MT_counted = methodType(String.class, String.class);
- static final MethodType MT_arrayCounted = methodType(void.class, int[].class);
- static final MethodType MT_countedPrinting = methodType(void.class);
-
- static {
- try {
- MH_13 = MethodHandles.constant(int.class, 13);
- MH_m5 = MethodHandles.constant(int.class, -5);
- MH_8 = MethodHandles.constant(int.class, 8);
- MH_start = LOOKUP.findStatic(COUNTED, "start", MT_start);
- MH_step = LOOKUP.findStatic(COUNTED, "step", MT_step);
- MH_stepUpdateArray = LOOKUP.findStatic(COUNTED, "stepUpdateArray", MT_stepUpdateArray);
- MH_printHello = LOOKUP.findStatic(COUNTED, "printHello", MT_printHello);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- }
-
- static class Iterate {
-
- static Iterator<Integer> sumIterator(Integer[] a) {
- return Arrays.asList(a).iterator();
- }
-
- static int sumInit(Integer[] a) {
- return 0;
- }
-
- static int sumStep(int s, int e, Integer[] a) {
- return s + e;
- }
-
- static List<String> reverseInit(List<String> l) {
- return new ArrayList<>();
- }
-
- static List<String> reverseStep(String e, List<String> r, List<String> l) {
- r.add(0, e);
- return r;
- }
-
- static int lengthInit(List<Double> l) {
- return 0;
- }
-
- static int lengthStep(Object o, int len, List<Double> l) {
- return len + 1;
- }
-
- static List<String> mapInit(List<String> l) {
- return new ArrayList<>();
- }
-
- static List<String> mapStep(String e, List<String> r, List<String> l) {
- r.add(e.toUpperCase());
- return r;
- }
-
- static void printStep(String s, List<String> l) {
- System.out.print(s);
- }
-
- static final Class<Iterate> ITERATE = Iterate.class;
-
- static final MethodType MT_sumIterator = methodType(Iterator.class, Integer[].class);
-
- static final MethodType MT_sumInit = methodType(int.class, Integer[].class);
- static final MethodType MT_reverseInit = methodType(List.class, List.class);
- static final MethodType MT_lenghInit = methodType(int.class, List.class);
- static final MethodType MT_mapInit = methodType(List.class, List.class);
-
- static final MethodType MT_sumStep = methodType(int.class, int.class, int.class, Integer[].class);
- static final MethodType MT_reverseStep = methodType(List.class, String.class, List.class, List.class);
- static final MethodType MT_lengthStep = methodType(int.class, Object.class, int.class, List.class);
- static final MethodType MT_mapStep = methodType(List.class, String.class, List.class, List.class);
- static final MethodType MT_printStep = methodType(void.class, String.class, List.class);
-
- static final MethodHandle MH_sumIterator;
- static final MethodHandle MH_sumInit;
- static final MethodHandle MH_sumStep;
- static final MethodHandle MH_printStep;
-
- static final MethodHandle MH_reverseInit;
- static final MethodHandle MH_reverseStep;
-
- static final MethodHandle MH_lengthInit;
- static final MethodHandle MH_lengthStep;
-
- static final MethodHandle MH_mapInit;
- static final MethodHandle MH_mapStep;
-
- static final MethodType MT_sum = methodType(int.class, Integer[].class);
- static final MethodType MT_reverse = methodType(List.class, List.class);
- static final MethodType MT_length = methodType(int.class, List.class);
- static final MethodType MT_map = methodType(List.class, List.class);
- static final MethodType MT_print = methodType(void.class, List.class);
-
- static {
- try {
- MH_sumIterator = LOOKUP.findStatic(ITERATE, "sumIterator", MT_sumIterator);
- MH_sumInit = LOOKUP.findStatic(ITERATE, "sumInit", MT_sumInit);
- MH_sumStep = LOOKUP.findStatic(ITERATE, "sumStep", MT_sumStep);
- MH_reverseInit = LOOKUP.findStatic(ITERATE, "reverseInit", MT_reverseInit);
- MH_reverseStep = LOOKUP.findStatic(ITERATE, "reverseStep", MT_reverseStep);
- MH_lengthInit = LOOKUP.findStatic(ITERATE, "lengthInit", MT_lenghInit);
- MH_lengthStep = LOOKUP.findStatic(ITERATE, "lengthStep", MT_lengthStep);
- MH_mapInit = LOOKUP.findStatic(ITERATE, "mapInit", MT_mapInit);
- MH_mapStep = LOOKUP.findStatic(ITERATE, "mapStep", MT_mapStep);
- MH_printStep = LOOKUP.findStatic(ITERATE, "printStep", MT_printStep);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- }
-
- static class TryFinally {
-
- static String greet(String whom) {
- return "Hello, " + whom;
- }
-
- static String exclaim(Throwable t, String r, String whom) {
- return r + "!";
- }
-
- static void print(String what) {
- System.out.print("Hello, " + what);
- }
-
- static void printMore(Throwable t, String what) {
- System.out.println("!");
- }
-
- static String greetMore(String first, String second) {
- return "Hello, " + first + " and " + second;
- }
-
- static String exclaimMore(Throwable t, String r, String first) {
- return r + " (but " + first + " first)!";
- }
-
- static void voidTarget() {}
-
- static void voidCleanup(Throwable t, int a) {}
-
- static final Class<TryFinally> TRY_FINALLY = TryFinally.class;
-
- static final MethodType MT_greet = methodType(String.class, String.class);
- static final MethodType MT_exclaim = methodType(String.class, Throwable.class, String.class, String.class);
- static final MethodType MT_print = methodType(void.class, String.class);
- static final MethodType MT_printMore = methodType(void.class, Throwable.class, String.class);
- static final MethodType MT_greetMore = methodType(String.class, String.class, String.class);
- static final MethodType MT_exclaimMore = methodType(String.class, Throwable.class, String.class, String.class);
- static final MethodType MT_voidTarget = methodType(void.class);
- static final MethodType MT_voidCleanup = methodType(void.class, Throwable.class, int.class);
-
- static final MethodHandle MH_greet;
- static final MethodHandle MH_exclaim;
- static final MethodHandle MH_print;
- static final MethodHandle MH_printMore;
- static final MethodHandle MH_greetMore;
- static final MethodHandle MH_exclaimMore;
- static final MethodHandle MH_voidTarget;
- static final MethodHandle MH_voidCleanup;
-
- static final MethodType MT_hello = methodType(String.class, String.class);
- static final MethodType MT_printHello = methodType(void.class, String.class);
- static final MethodType MT_moreHello = methodType(String.class, String.class, String.class);
-
- static {
- try {
- MH_greet = LOOKUP.findStatic(TRY_FINALLY, "greet", MT_greet);
- MH_exclaim = LOOKUP.findStatic(TRY_FINALLY, "exclaim", MT_exclaim);
- MH_print = LOOKUP.findStatic(TRY_FINALLY, "print", MT_print);
- MH_printMore = LOOKUP.findStatic(TRY_FINALLY, "printMore", MT_printMore);
- MH_greetMore = LOOKUP.findStatic(TRY_FINALLY, "greetMore", MT_greetMore);
- MH_exclaimMore = LOOKUP.findStatic(TRY_FINALLY, "exclaimMore", MT_exclaimMore);
- MH_voidTarget = LOOKUP.findStatic(TRY_FINALLY, "voidTarget", MT_voidTarget);
- MH_voidCleanup = LOOKUP.findStatic(TRY_FINALLY, "voidCleanup", MT_voidCleanup);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- }
-
- static class Fold {
-
- static int adder(int a, int b, int c) {
- return a + b + c;
- }
-
- static int adder1(int a, int b) {
- return a + b;
- }
-
- static int multer(int x, int q, int r, int s) {
- return x * q * r * s;
- }
-
- static int str(boolean b1, String s, boolean b2, int x) {
- return b1 && s.equals(String.valueOf(b2)) ? x : -x;
- }
-
- static boolean comb(String s, boolean b2) {
- return !s.equals(b2);
- }
-
- static String comb2(boolean b2, int x) {
- int ib = b2 ? 1 : 0;
- return ib == x ? "true" : "false";
- }
-
- static final Class<Fold> FOLD = Fold.class;
-
- static final MethodType MT_adder = methodType(int.class, int.class, int.class, int.class);
- static final MethodType MT_adder1 = methodType(int.class, int.class, int.class);
- static final MethodType MT_multer = methodType(int.class, int.class, int.class, int.class, int.class);
- static final MethodType MT_str = methodType(int.class, boolean.class, String.class, boolean.class, int.class);
- static final MethodType MT_comb = methodType(boolean.class, String.class, boolean.class);
- static final MethodType MT_comb2 = methodType(String.class, boolean.class, int.class);
-
- static final MethodHandle MH_adder;
- static final MethodHandle MH_adder1;
- static final MethodHandle MH_multer;
- static final MethodHandle MH_str;
- static final MethodHandle MH_comb;
- static final MethodHandle MH_comb2;
-
- static final MethodType MT_folded1 = methodType(int.class, int.class, int.class, int.class);
- static final MethodType MT_folded2 = methodType(int.class, String.class, boolean.class, int.class);
- static final MethodType MT_folded3 = methodType(int.class, boolean.class, boolean.class, int.class);
-
- static {
- try {
- MH_adder = LOOKUP.findStatic(FOLD, "adder", MT_adder);
- MH_adder1 = LOOKUP.findStatic(FOLD, "adder1", MT_adder1);
- MH_multer = LOOKUP.findStatic(FOLD, "multer", MT_multer);
- MH_str = LOOKUP.findStatic(FOLD, "str", MT_str);
- MH_comb = LOOKUP.findStatic(FOLD, "comb", MT_comb);
- MH_comb2 = LOOKUP.findStatic(FOLD, "comb2", MT_comb2);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
- }
-
- static class SpreadCollect {
-
- static String forSpreading(String s1, int i1, int i2, int i3, String s2) {
- return s1 + i1 + i2 + i3 + s2;
- }
-
- static String forCollecting(String s1, int[] is, String s2) {
- StringBuilder sb = new StringBuilder(s1);
- for (int i : is) {
- sb.append(i);
- }
- return sb.append(s2).toString();
- }
-
- static String forCollectingLeading(int[] is, String s) {
- return forCollecting("", is, s);
- }
-
- static final Class<SpreadCollect> SPREAD_COLLECT = SpreadCollect.class;
-
- static final MethodType MT_forSpreading = methodType(String.class, String.class, int.class, int.class, int.class, String.class);
- static final MethodType MT_forCollecting = methodType(String.class, String.class, int[].class, String.class);
- static final MethodType MT_forCollectingLeading = methodType(String.class, int[].class, String.class);
-
- static final MethodHandle MH_forSpreading;
- static final MethodHandle MH_forCollecting;
- static final MethodHandle MH_forCollectingLeading;
-
- static final MethodType MT_spreader = methodType(String.class, String.class, int[].class, String.class);
- static final MethodType MT_collector0 = methodType(String.class, String.class, String.class);
- static final MethodType MT_collector1 = methodType(String.class, String.class, int.class, String.class);
- static final MethodType MT_collector2 = methodType(String.class, String.class, int.class, int.class, String.class);
- static final MethodType MT_collector3 = methodType(String.class, String.class, int.class, int.class, int.class, String.class);
- static final MethodType MT_collectorLeading1 = methodType(String.class, int.class, String.class);
- static final MethodType MT_collectorLeading2 = methodType(String.class, int.class, int.class, String.class);
- static final MethodType MT_collectorLeading3 = methodType(String.class, int.class, int.class, int.class, String.class);
-
- static final String NONE_ERROR = "zero array length in MethodHandle.asCollector";
-
- static {
- try {
- MH_forSpreading = LOOKUP.findStatic(SPREAD_COLLECT, "forSpreading", MT_forSpreading);
- MH_forCollecting = LOOKUP.findStatic(SPREAD_COLLECT, "forCollecting", MT_forCollecting);
- MH_forCollectingLeading = LOOKUP.findStatic(SPREAD_COLLECT, "forCollectingLeading", MT_forCollectingLeading);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- }
-
- static class FindSpecial {
-
- interface I1 {
- default String m() {
- return "I1.m";
- }
- }
-
- interface I2 {
- default String m() {
- return "I2.m";
- }
- }
-
- interface I3 {
- String q();
- }
-
- static class C implements I1, I2, I3 {
- public String m() {
- return I1.super.m();
- }
- public String q() {
- return "q";
- }
- }
-
- static final String ABSTRACT_ERROR = "no such method: test.java.lang.invoke.T8139885$FindSpecial$I3.q()String/invokeSpecial";
-
- }
-
- //
- // Auxiliary methods.
- //
-
- static MethodHandle[] mha(MethodHandle... mhs) {
- return mhs;
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/TryFinallyTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ */
+
+/* @test
+ * @bug 8139885
+ * @bug 8150825
+ * @run testng/othervm -ea -esa test.java.lang.invoke.TryFinallyTest
+ */
+
+package test.java.lang.invoke;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.*;
+
+/**
+ * Tests for the tryFinally method handle combinator introduced in JEP 274.
+ */
+public class TryFinallyTest {
+
+ static final Lookup LOOKUP = MethodHandles.lookup();
+
+ @Test
+ public static void testTryFinally() throws Throwable {
+ MethodHandle hello = MethodHandles.tryFinally(TryFinally.MH_greet, TryFinally.MH_exclaim);
+ assertEquals(TryFinally.MT_hello, hello.type());
+ assertEquals("Hello, world!", hello.invoke("world"));
+ }
+
+ @Test
+ public static void testTryFinallyVoid() throws Throwable {
+ MethodHandle tfVoid = MethodHandles.tryFinally(TryFinally.MH_print, TryFinally.MH_printMore);
+ assertEquals(TryFinally.MT_printHello, tfVoid.type());
+ tfVoid.invoke("world");
+ }
+
+ @Test
+ public static void testTryFinallySublist() throws Throwable {
+ MethodHandle helloMore = MethodHandles.tryFinally(TryFinally.MH_greetMore, TryFinally.MH_exclaimMore);
+ assertEquals(TryFinally.MT_moreHello, helloMore.type());
+ assertEquals("Hello, world and universe (but world first)!", helloMore.invoke("world", "universe"));
+ }
+
+ @DataProvider
+ static Object[][] negativeTestData() {
+ MethodHandle intid = MethodHandles.identity(int.class);
+ MethodHandle intco = MethodHandles.constant(int.class, 0);
+ MethodHandle errTarget = MethodHandles.dropArguments(intco, 0, int.class, double.class, String.class, int.class);
+ MethodHandle errCleanup = MethodHandles.dropArguments(MethodHandles.constant(int.class, 0), 0, Throwable.class,
+ int.class, double.class, Object.class);
+ return new Object[][]{
+ {intid, MethodHandles.identity(double.class),
+ "target and return types must match: double != int"},
+ {intid, MethodHandles.dropArguments(intid, 0, String.class),
+ "cleanup first argument and Throwable must match: (String,int)int != class java.lang.Throwable"},
+ {intid, MethodHandles.dropArguments(intid, 0, Throwable.class, double.class),
+ "cleanup second argument and target return type must match: (Throwable,double,int)int != int"},
+ {errTarget, errCleanup,
+ "cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
+ errCleanup.type() + " != " + errTarget.type()},
+ {TryFinally.MH_voidTarget, TryFinally.MH_voidCleanup,
+ "cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
+ TryFinally.MH_voidCleanup.type() + " != " + TryFinally.MH_voidTarget.type()}
+ };
+ }
+
+ @Test(dataProvider = "negativeTestData")
+ public static void testTryFinallyNegative(MethodHandle target, MethodHandle cleanup, String expectedMessage) {
+ boolean caught = false;
+ try {
+ MethodHandles.tryFinally(target, cleanup);
+ } catch (IllegalArgumentException iae) {
+ assertEquals(expectedMessage, iae.getMessage());
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ static class TryFinally {
+
+ static String greet(String whom) {
+ return "Hello, " + whom;
+ }
+
+ static String exclaim(Throwable t, String r, String whom) {
+ return r + "!";
+ }
+
+ static void print(String what) {
+ System.out.print("Hello, " + what);
+ }
+
+ static void printMore(Throwable t, String what) {
+ System.out.println("!");
+ }
+
+ static String greetMore(String first, String second) {
+ return "Hello, " + first + " and " + second;
+ }
+
+ static String exclaimMore(Throwable t, String r, String first) {
+ return r + " (but " + first + " first)!";
+ }
+
+ static void voidTarget() {}
+
+ static void voidCleanup(Throwable t, int a) {}
+
+ static final Class<TryFinally> TRY_FINALLY = TryFinally.class;
+
+ static final MethodType MT_greet = methodType(String.class, String.class);
+ static final MethodType MT_exclaim = methodType(String.class, Throwable.class, String.class, String.class);
+ static final MethodType MT_print = methodType(void.class, String.class);
+ static final MethodType MT_printMore = methodType(void.class, Throwable.class, String.class);
+ static final MethodType MT_greetMore = methodType(String.class, String.class, String.class);
+ static final MethodType MT_exclaimMore = methodType(String.class, Throwable.class, String.class, String.class);
+ static final MethodType MT_voidTarget = methodType(void.class);
+ static final MethodType MT_voidCleanup = methodType(void.class, Throwable.class, int.class);
+
+ static final MethodHandle MH_greet;
+ static final MethodHandle MH_exclaim;
+ static final MethodHandle MH_print;
+ static final MethodHandle MH_printMore;
+ static final MethodHandle MH_greetMore;
+ static final MethodHandle MH_exclaimMore;
+ static final MethodHandle MH_voidTarget;
+ static final MethodHandle MH_voidCleanup;
+
+ static final MethodType MT_hello = methodType(String.class, String.class);
+ static final MethodType MT_printHello = methodType(void.class, String.class);
+ static final MethodType MT_moreHello = methodType(String.class, String.class, String.class);
+
+ static {
+ try {
+ MH_greet = LOOKUP.findStatic(TRY_FINALLY, "greet", MT_greet);
+ MH_exclaim = LOOKUP.findStatic(TRY_FINALLY, "exclaim", MT_exclaim);
+ MH_print = LOOKUP.findStatic(TRY_FINALLY, "print", MT_print);
+ MH_printMore = LOOKUP.findStatic(TRY_FINALLY, "printMore", MT_printMore);
+ MH_greetMore = LOOKUP.findStatic(TRY_FINALLY, "greetMore", MT_greetMore);
+ MH_exclaimMore = LOOKUP.findStatic(TRY_FINALLY, "exclaimMore", MT_exclaimMore);
+ MH_voidTarget = LOOKUP.findStatic(TRY_FINALLY, "voidTarget", MT_voidTarget);
+ MH_voidCleanup = LOOKUP.findStatic(TRY_FINALLY, "voidCleanup", MT_voidCleanup);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/SocketOption/ImmutableOptions.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @bug 8148609
+ * @run testng/othervm ImmutableOptions
+ * @summary Assert that the set of socket options are immutable
+ */
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.*;
+import java.util.Set;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+public class ImmutableOptions {
+
+ @BeforeTest
+ void setupServerSocketFactory() throws IOException {
+ ServerSocket.setSocketFactory(new ServerSocketImplFactory());
+ }
+
+ @Test(expectedExceptions = UnsupportedOperationException.class)
+ public void socketThrows() throws IOException {
+ CustomSocketImpl impl = new CustomSocketImpl();
+ Socket socket = new CustomSocket(impl);
+ socket.supportedOptions().clear();
+ }
+
+ @Test(expectedExceptions = UnsupportedOperationException.class)
+ public void socketImplThrows() throws IOException {
+ CustomSocketImpl impl = new CustomSocketImpl();
+ impl.supportedOptions().clear();
+ }
+
+ @Test(expectedExceptions = UnsupportedOperationException.class)
+ public void serverSocketThrows() throws IOException {
+ ServerSocket ss = new ServerSocket();
+ ss.supportedOptions().clear();
+ }
+
+ @Test(expectedExceptions = UnsupportedOperationException.class)
+ public void serverSocketImplThrows() throws IOException {
+ ServerSocket ss = new ServerSocket();
+ ServerSocketImplFactory.mostRecentlyCreated.supportedOptions().clear();
+ }
+
+ @Test(expectedExceptions = UnsupportedOperationException.class)
+ public void datagramSocketThrows() throws IOException {
+ CustomDatagramSocketImpl impl = new CustomDatagramSocketImpl();
+ DatagramSocket socket = new CustomDatagramSocket(impl);
+ socket.supportedOptions().clear();
+ }
+
+ @Test(expectedExceptions = UnsupportedOperationException.class)
+ public void datagramSocketImplThrows() throws IOException {
+ CustomDatagramSocketImpl impl = new CustomDatagramSocketImpl();
+ impl.supportedOptions().clear();
+ }
+
+
+ // Socket descendants
+ static class CustomSocket extends Socket {
+ public CustomSocket(SocketImpl impl) throws IOException {
+ super(impl);
+ }
+ }
+
+ static class CustomDatagramSocket extends DatagramSocket {
+ public CustomDatagramSocket(DatagramSocketImpl impl) {
+ super(impl);
+ }
+ }
+
+ static class ServerSocketImplFactory implements SocketImplFactory {
+ static volatile CustomSocketImpl mostRecentlyCreated;
+
+ @Override public SocketImpl createSocketImpl() {
+ return mostRecentlyCreated = new CustomSocketImpl();
+ }
+ }
+
+ // Custom impl's
+ static class CustomSocketImpl extends SocketImpl {
+ // The only method interesting to this test.
+ @Override public Set<SocketOption<?>> supportedOptions() {
+ return super.supportedOptions();
+ }
+
+ public void create(boolean stream) throws IOException { }
+
+ public void connect(String host, int port) throws IOException { }
+
+ public void connect(InetAddress addr, int port) throws IOException { }
+
+ public void connect(SocketAddress addr, int timeout) throws IOException { }
+
+ public void bind(InetAddress host, int port) throws IOException { }
+
+ public void listen(int backlog) throws IOException { }
+
+ public void accept(SocketImpl s) throws IOException { }
+
+ public InputStream getInputStream() throws IOException { return null; }
+
+ public OutputStream getOutputStream() throws IOException { return null; }
+
+ public int available() throws IOException { return 0; }
+
+ public void close() throws IOException { }
+
+ public void sendUrgentData(int data) throws IOException { }
+
+ public Object getOption(int i) throws SocketException { return null; }
+
+ public void setOption(int i, Object o) throws SocketException { }
+ }
+
+ static class CustomDatagramSocketImpl extends DatagramSocketImpl {
+ // The only method interesting to this test.
+ @Override public Set<SocketOption<?>> supportedOptions() {
+ return super.supportedOptions();
+ }
+
+ protected void create() throws SocketException { }
+
+ protected void bind(int lport, InetAddress laddr) throws SocketException { }
+
+ protected void send(DatagramPacket p) throws IOException { }
+
+ protected int peek(InetAddress i) throws IOException { return 0; }
+
+ protected int peekData(DatagramPacket p) throws IOException { return 0; }
+
+ protected void receive(DatagramPacket p) throws IOException { }
+
+ protected void setTTL(byte ttl) throws IOException { }
+
+ protected byte getTTL() throws IOException { return 0; }
+
+ protected void setTimeToLive(int ttl) throws IOException { }
+
+ protected int getTimeToLive() throws IOException { return 0; }
+
+ protected void join(InetAddress inetaddr) throws IOException { }
+
+ protected void leave(InetAddress inetaddr) throws IOException { }
+
+ protected void joinGroup(SocketAddress x, NetworkInterface y)
+ throws IOException { }
+
+ protected void leaveGroup(SocketAddress x, NetworkInterface y)
+ throws IOException { }
+
+ protected void close() { }
+
+ public void setOption(int optID, Object value) throws SocketException { }
+
+ public Object getOption(int optID) throws SocketException { return null; }
+ }
+}
--- a/jdk/test/java/util/WeakHashMap/GCDuringIteration.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/WeakHashMap/GCDuringIteration.java Thu Mar 03 12:49:12 2016 -0800
@@ -29,26 +29,50 @@
* @run main GCDuringIteration
* @summary Check that iterators work properly in the presence of
* concurrent finalization and removal of elements.
- * @key randomness intermittent
+ * @key randomness
*/
-import java.util.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.WeakHashMap;
import java.util.concurrent.CountDownLatch;
+import java.util.function.BooleanSupplier;
import jdk.testlibrary.RandomFactory;
public class GCDuringIteration {
- private static void waitForFinalizersToRun() {
- for (int i = 0; i < 2; i++)
- tryWaitForFinalizersToRun();
+
+ /** No guarantees, but effective in practice. */
+ static void forceFullGc() {
+ CountDownLatch finalizeDone = new CountDownLatch(1);
+ WeakReference<?> ref = new WeakReference<Object>(new Object() {
+ protected void finalize() { finalizeDone.countDown(); }});
+ try {
+ for (int i = 0; i < 10; i++) {
+ System.gc();
+ if (finalizeDone.await(1L, SECONDS) && ref.get() == null) {
+ System.runFinalization(); // try to pick up stragglers
+ return;
+ }
+ }
+ } catch (InterruptedException unexpected) {
+ throw new AssertionError("unexpected InterruptedException");
+ }
+ throw new AssertionError("failed to do a \"full\" gc");
}
- private static void tryWaitForFinalizersToRun() {
- System.gc();
- final CountDownLatch fin = new CountDownLatch(1);
- new Object() { protected void finalize() { fin.countDown(); }};
- System.gc();
- try { fin.await(); }
- catch (InterruptedException ie) { throw new Error(ie); }
+ static void gcAwait(BooleanSupplier s) {
+ for (int i = 0; i < 10; i++) {
+ if (s.getAsBoolean())
+ return;
+ forceFullGc();
+ }
+ throw new AssertionError("failed to satisfy condition");
}
// A class with the traditional pessimal hashCode implementation,
@@ -76,9 +100,13 @@
if (rnd.nextBoolean()) check(it.hasNext());
equal(it.next().getValue(), i);
}
- if (rnd.nextBoolean())
- THROWS(NoSuchElementException.class,
- new F(){void f(){it.next();}});
+ if (rnd.nextBoolean()) {
+ try {
+ it.next();
+ throw new AssertionError("should throw");
+ } catch (NoSuchElementException success) {}
+ }
+
if (rnd.nextBoolean())
check(! it.hasNext());
}
@@ -106,9 +134,7 @@
int first = firstValue(map);
final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
foos[first] = null;
- for (int i = 0; i < 10 && map.size() != first; i++)
- tryWaitForFinalizersToRun();
- equal(map.size(), first);
+ gcAwait(() -> map.size() == first);
checkIterator(it, first-1);
equal(map.size(), first);
equal(firstValue(map), first-1);
@@ -119,15 +145,14 @@
final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
it.next(); // protects first entry
System.out.println(map.values());
+ int oldSize = map.size();
foos[first] = null;
- tryWaitForFinalizersToRun();
- equal(map.size(), first+1);
+ forceFullGc();
+ equal(map.size(), oldSize);
System.out.println(map.values());
checkIterator(it, first-1);
// first entry no longer protected
- for (int i = 0; i < 10 && map.size() != first; i++)
- tryWaitForFinalizersToRun();
- equal(map.size(), first);
+ gcAwait(() -> map.size() == first);
equal(firstValue(map), first-1);
}
@@ -137,15 +162,12 @@
it.next(); // protects first entry
System.out.println(map.values());
foos[first] = foos[first-1] = null;
- tryWaitForFinalizersToRun();
- equal(map.size(), first);
+ gcAwait(() -> map.size() == first);
equal(firstValue(map), first);
System.out.println(map.values());
checkIterator(it, first-2);
// first entry no longer protected
- for (int i = 0; i < 10 && map.size() != first-1; i++)
- tryWaitForFinalizersToRun();
- equal(map.size(), first-1);
+ gcAwait(() -> map.size() == first-1);
equal(firstValue(map), first-2);
}
@@ -155,16 +177,15 @@
it.next(); // protects first entry
it.hasNext(); // protects second entry
System.out.println(map.values());
+ int oldSize = map.size();
foos[first] = foos[first-1] = null;
- tryWaitForFinalizersToRun();
+ forceFullGc();
+ equal(map.size(), oldSize);
equal(firstValue(map), first);
- equal(map.size(), first+1);
System.out.println(map.values());
checkIterator(it, first-1);
// first entry no longer protected
- for (int i = 0; i < 10 && map.size() != first-1; i++)
- tryWaitForFinalizersToRun();
- equal(map.size(), first-1);
+ gcAwait(() -> map.size() == first-1);
equal(firstValue(map), first-2);
}
@@ -173,17 +194,16 @@
final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
it.next(); // protects first entry
System.out.println(map.values());
+ equal(map.size(), first+1);
foos[first] = foos[first-1] = null;
- tryWaitForFinalizersToRun();
+ gcAwait(() -> map.size() == first);
it.remove();
equal(firstValue(map), first-2);
equal(map.size(), first-1);
System.out.println(map.values());
checkIterator(it, first-2);
// first entry no longer protected
- for (int i = 0; i < 10 && map.size() != first-1; i++)
- tryWaitForFinalizersToRun();
- equal(map.size(), first-1);
+ gcAwait(() -> map.size() == first-1);
equal(firstValue(map), first-2);
}
@@ -194,15 +214,14 @@
it.remove();
it.hasNext(); // protects second entry
System.out.println(map.values());
+ equal(map.size(), first);
foos[first] = foos[first-1] = null;
- tryWaitForFinalizersToRun();
+ forceFullGc();
equal(firstValue(map), first-1);
equal(map.size(), first);
System.out.println(map.values());
checkIterator(it, first-1);
- for (int i = 0; i < 10 && map.size() != first-1; i++)
- tryWaitForFinalizersToRun();
- equal(map.size(), first-1);
+ gcAwait(() -> map.size() == first-1);
equal(firstValue(map), first-2);
}
@@ -211,14 +230,11 @@
final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
it.hasNext(); // protects first entry
Arrays.fill(foos, null);
- tryWaitForFinalizersToRun();
- equal(map.size(), 1);
+ gcAwait(() -> map.size() == 1);
System.out.println(map.values());
equal(it.next().getValue(), first);
check(! it.hasNext());
- for (int i = 0; i < 10 && map.size() != 0; i++)
- tryWaitForFinalizersToRun();
- equal(map.size(), 0);
+ gcAwait(() -> map.size() == 0);
check(map.isEmpty());
}
}
@@ -239,11 +255,4 @@
try {test(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- abstract class F {abstract void f() throws Throwable;}
- void THROWS(Class<? extends Throwable> k, F... fs) {
- for (F f : fs)
- try {f.f(); fail("Expected " + k.getName() + " not thrown");}
- catch (Throwable t) {
- if (k.isAssignableFrom(t.getClass())) pass();
- else unexpected(t);}}
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,8 +35,11 @@
* @test
* @bug 4486658
* @summary Checks for responsiveness of blocking queues to cancellation.
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.ArrayList;
import java.util.List;
import java.util.SplittableRandom;
@@ -53,8 +56,10 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
+import jdk.testlibrary.Utils;
public class CancelledProducerConsumerLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static ExecutorService pool;
public static void main(String[] args) throws Exception {
@@ -73,7 +78,7 @@
new CancelledProducerConsumerLoops(i, queue).run();
}
pool.shutdown();
- if (! pool.awaitTermination(10L, TimeUnit.SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new AssertionError("timed out");
pool = null;
}
@@ -117,18 +122,18 @@
assertCancelled(cons[i]);
}
- if (!producersInterrupted.await(10L, TimeUnit.SECONDS))
+ if (!producersInterrupted.await(LONG_DELAY_MS, MILLISECONDS))
throw new AssertionError("timed out");
- if (!consumersInterrupted.await(10L, TimeUnit.SECONDS))
+ if (!consumersInterrupted.await(LONG_DELAY_MS, MILLISECONDS))
throw new AssertionError("timed out");
if (prods[0].isDone() || prods[0].isCancelled())
throw new AssertionError("completed too early");
done = true;
- if (! (prods[0].get(10L, TimeUnit.SECONDS) instanceof Integer))
+ if (! (prods[0].get(LONG_DELAY_MS, MILLISECONDS) instanceof Integer))
throw new AssertionError("expected Integer");
- if (! (cons[0].get(10L, TimeUnit.SECONDS) instanceof Integer))
+ if (! (cons[0].get(LONG_DELAY_MS, MILLISECONDS) instanceof Integer))
throw new AssertionError("expected Integer");
}
@@ -138,7 +143,7 @@
if (!future.isCancelled())
throw new AssertionError("not cancelled");
try {
- future.get(10L, TimeUnit.SECONDS);
+ future.get(LONG_DELAY_MS, MILLISECONDS);
throw new AssertionError("should throw CancellationException");
} catch (CancellationException success) {}
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java Thu Mar 03 12:49:12 2016 -0800
@@ -26,10 +26,10 @@
* @bug 6384064
* @summary Check proper handling of interrupts
* @author Martin Buchholz
+ * @library /lib/testlibrary/
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
import java.util.List;
@@ -41,8 +41,10 @@
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledThreadPoolExecutor;
+import jdk.testlibrary.Utils;
public class Interrupt {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static void checkInterrupted0(Iterable<Fun> fs, Executor ex) {
for (Fun f : fs) {
@@ -71,7 +73,7 @@
checkInterrupted0(fs, immediateExecutor);
checkInterrupted0(fs, delayedExecutor);
stpe.shutdown();
- check(stpe.awaitTermination(10L, SECONDS));
+ check(stpe.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
}
static void testQueue(final BlockingQueue<Object> q) {
@@ -82,12 +84,12 @@
q.clear();
List<Fun> fs = new ArrayList<Fun>();
fs.add(() -> q.take());
- fs.add(() -> q.poll(60, SECONDS));
+ fs.add(() -> q.poll(LONG_DELAY_MS, MILLISECONDS));
if (deq != null) {
fs.add(() -> deq.takeFirst());
fs.add(() -> deq.takeLast());
- fs.add(() -> deq.pollFirst(7, SECONDS));
- fs.add(() -> deq.pollLast(7, SECONDS));
+ fs.add(() -> deq.pollFirst(LONG_DELAY_MS, MILLISECONDS));
+ fs.add(() -> deq.pollLast(LONG_DELAY_MS, MILLISECONDS));
}
checkInterrupted(fs);
@@ -99,12 +101,12 @@
fs.clear();
fs.add(() -> q.put(1));
- fs.add(() -> q.offer(1, 7, SECONDS));
+ fs.add(() -> q.offer(1, LONG_DELAY_MS, MILLISECONDS));
if (deq != null) {
fs.add(() -> deq.putFirst(1));
fs.add(() -> deq.putLast(1));
- fs.add(() -> deq.offerFirst(1, 7, SECONDS));
- fs.add(() -> deq.offerLast(1, 7, SECONDS));
+ fs.add(() -> deq.offerFirst(1, LONG_DELAY_MS, MILLISECONDS));
+ fs.add(() -> deq.offerLast(1, LONG_DELAY_MS, MILLISECONDS));
}
checkInterrupted(fs);
} catch (Throwable t) {
--- a/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,10 +35,11 @@
* @test
* @bug 4486658
* @summary multiple producers and single consumer using blocking queues
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@@ -51,8 +52,10 @@
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.atomic.AtomicInteger;
+import jdk.testlibrary.Utils;
public class MultipleProducersSingleConsumerLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static ExecutorService pool;
public static void main(String[] args) throws Exception {
@@ -77,7 +80,7 @@
}
pool.shutdown();
- if (! pool.awaitTermination(10L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
pool = null;
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,10 +35,11 @@
* @test
* @bug 4486658
* @summary multiple producers and consumers using blocking queues
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@@ -51,8 +52,10 @@
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.atomic.AtomicInteger;
+import jdk.testlibrary.Utils;
public class ProducerConsumerLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static ExecutorService pool;
public static void main(String[] args) throws Exception {
@@ -77,7 +80,7 @@
run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
}
pool.shutdown();
- if (! pool.awaitTermination(60L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
pool = null;
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,10 +35,11 @@
* @test
* @bug 4486658
* @summary check ordering for blocking queues with 1 producer and multiple consumers
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@@ -50,8 +51,10 @@
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
+import jdk.testlibrary.Utils;
public class SingleProducerMultipleConsumerLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static ExecutorService pool;
public static void main(String[] args) throws Exception {
@@ -75,7 +78,7 @@
run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
}
pool.shutdown();
- if (! pool.awaitTermination(60L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
pool = null;
}
--- a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,15 +34,17 @@
/*
* @test
* @bug 8005696
+ * @summary Basic tests for CompletableFuture
+ * @library /lib/testlibrary/
* @run main Basic
* @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 Basic
- * @summary Basic tests for CompletableFuture
* @author Chris Hegarty
*/
import static java.util.concurrent.CompletableFuture.runAsync;
import static java.util.concurrent.CompletableFuture.supplyAsync;
import static java.util.concurrent.ForkJoinPool.commonPool;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.lang.reflect.Array;
@@ -54,8 +56,10 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
+import jdk.testlibrary.Utils;
public class Basic {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static void checkCompletedNormally(CompletableFuture<?> cf, Object value) {
checkCompletedNormally(cf, value == null ? null : new Object[] { value });
@@ -109,12 +113,13 @@
}
private static void realMain(String[] args) throws Throwable {
- ExecutorService executor = Executors.newFixedThreadPool(2);
+ ExecutorService pool = Executors.newFixedThreadPool(2);
try {
- test(executor);
+ test(pool);
} finally {
- executor.shutdown();
- executor.awaitTermination(30L, SECONDS);
+ pool.shutdown();
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
+ throw new Error();
}
}
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,7 +34,6 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=1600 MapLoops
* @summary Exercise multithreaded maps, by default ConcurrentHashMap.
* Multithreaded hash table test. Each thread does a random walk
* though elements of "key" array. On each iteration, it checks if
@@ -42,9 +41,11 @@
* inserts it, and if present, with probability premove it removes
* it. (pinsert and premove are expressed as percentages to simplify
* parsing from command line.)
+ * @library /lib/testlibrary/
+ * @run main/timeout=1600 MapLoops
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.List;
import java.util.Map;
@@ -53,8 +54,10 @@
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import jdk.testlibrary.Utils;
public class MapLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static int nkeys = 1000; // 10_000
static int pinsert = 60;
static int premove = 2;
@@ -126,7 +129,7 @@
i = k;
}
pool.shutdown();
- if (! pool.awaitTermination(60L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
if (! throwables.isEmpty())
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,11 +34,12 @@
/*
* @test
* @bug 4486658 6785442
+ * @summary Checks that a set of threads can repeatedly get and modify items
+ * @library /lib/testlibrary/
* @run main ConcurrentQueueLoops 8 123456
- * @summary Checks that a set of threads can repeatedly get and modify items
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.ArrayList;
import java.util.Collection;
@@ -57,8 +58,10 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.atomic.AtomicInteger;
+import jdk.testlibrary.Utils;
public class ConcurrentQueueLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
ExecutorService pool;
AtomicInteger totalItems;
boolean print;
@@ -106,16 +109,14 @@
print = false;
System.out.println("Warmup...");
oneRun(1, items, q);
- //Thread.sleep(100);
oneRun(3, items, q);
- Thread.sleep(100);
print = true;
for (int i = 1; i <= maxStages; i += (i+1) >>> 1) {
oneRun(i, items, q);
}
pool.shutdown();
- check(pool.awaitTermination(60L, SECONDS));
+ check(pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
}
class Stage implements Callable<Integer> {
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Thu Mar 03 12:49:12 2016 -0800
@@ -38,10 +38,14 @@
* @run main GCRetention 12345
*/
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.lang.ref.WeakReference;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
@@ -59,6 +63,25 @@
// Suitable for benchmarking. Overridden by args[0] for testing.
int count = 1024 * 1024;
+ /** No guarantees, but effective in practice. */
+ static void forceFullGc() {
+ CountDownLatch finalizeDone = new CountDownLatch(1);
+ WeakReference<?> ref = new WeakReference<Object>(new Object() {
+ protected void finalize() { finalizeDone.countDown(); }});
+ try {
+ for (int i = 0; i < 10; i++) {
+ System.gc();
+ if (finalizeDone.await(1L, SECONDS) && ref.get() == null) {
+ System.runFinalization(); // try to pick up stragglers
+ return;
+ }
+ }
+ } catch (InterruptedException unexpected) {
+ throw new AssertionError("unexpected InterruptedException");
+ }
+ throw new AssertionError("failed to do a \"full\" gc");
+ }
+
final Map<String,String> results = new ConcurrentHashMap<String,String>();
Collection<Queue<Boolean>> queues() {
@@ -117,8 +140,8 @@
long t0 = System.nanoTime();
for (int i = 0; i < count; i++)
check(q.add(Boolean.TRUE));
- System.gc();
- System.gc();
+ forceFullGc();
+ // forceFullGc();
Boolean x;
while ((x = q.poll()) != null)
equal(x, Boolean.TRUE);
--- a/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java Thu Mar 03 12:49:12 2016 -0800
@@ -25,11 +25,11 @@
* @test
* @bug 6253848 6366811
* @summary Basic tests for CyclicBarrier
+ * @library /lib/testlibrary/
* @author Martin Buchholz, David Holmes
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
import java.util.Iterator;
@@ -39,8 +39,10 @@
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
+import jdk.testlibrary.Utils;
public class Basic {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
private static void checkBroken(final CyclicBarrier barrier) {
check(barrier.isBroken());
@@ -77,7 +79,7 @@
private static final CyclicBarrier atTheStartingGate = new CyclicBarrier(3);
private static void toTheStartingGate() {
- try { atTheStartingGate.await(10, SECONDS); pass(); }
+ try { atTheStartingGate.await(LONG_DELAY_MS, MILLISECONDS); pass(); }
catch (Throwable t) {
unexpected(t);
reset(atTheStartingGate);
@@ -314,13 +316,13 @@
Throwable throwable() { return this.throwable; }
boolean interruptBit() { return this.interrupted; }
void realRun() throws Throwable {
- startingGate.await(10, SECONDS);
+ startingGate.await(LONG_DELAY_MS, MILLISECONDS);
try {
- if (timed) barrier.await(10, SECONDS);
+ if (timed) barrier.await(LONG_DELAY_MS, MILLISECONDS);
else barrier.await(); }
catch (Throwable throwable) { this.throwable = throwable; }
- try { doneSignal.await(10, SECONDS); }
+ try { doneSignal.await(LONG_DELAY_MS, MILLISECONDS); }
catch (InterruptedException e) { interrupted = true; }
}
}
@@ -354,7 +356,7 @@
waiter.start();
waiters.add(waiter);
}
- startingGate.await(10, SECONDS);
+ startingGate.await(LONG_DELAY_MS, MILLISECONDS);
while (barrier.getNumberWaiting() < N) Thread.yield();
barrier.await();
doneSignal.countDown();
@@ -383,7 +385,7 @@
waiter.start();
waiters.add(waiter);
}
- startingGate.await(10, SECONDS);
+ startingGate.await(LONG_DELAY_MS, MILLISECONDS);
while (barrier.getNumberWaiting() < N) Thread.yield();
for (int i = 0; i < N/2; i++)
waiters.get(i).interrupt();
--- a/jdk/test/java/util/concurrent/DelayQueue/Stress.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/DelayQueue/Stress.java Thu Mar 03 12:49:12 2016 -0800
@@ -26,6 +26,7 @@
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
/**
* This is not a regression test, but a stress benchmark test for
--- a/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,18 +34,20 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=720 ExchangeLoops
* @summary checks to make sure a pipeline of exchangers passes data.
+ * @library /lib/testlibrary/
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import jdk.testlibrary.Utils;
public class ExchangeLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final ExecutorService pool = Executors.newCachedThreadPool();
static boolean print = false;
@@ -56,14 +58,14 @@
public static void main(String[] args) throws Exception {
int maxStages = 5;
- int iters = 10000;
+ int iters = 2000;
if (args.length > 0)
maxStages = Integer.parseInt(args[0]);
print = false;
System.out.println("Warmup...");
- oneRun(2, 100000);
+ oneRun(2, iters);
print = true;
for (int i = 2; i <= maxStages; i += (i+1) >>> 1) {
@@ -71,7 +73,7 @@
oneRun(i, iters);
}
pool.shutdown();
- if (! pool.awaitTermination(60L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,19 +34,21 @@
/*
* @test
* @bug 4965960
- * @run main/timeout=3600 ExecutorCompletionServiceLoops
- * @summary Exercise ExecutorCompletionServiceLoops
+ * @summary Exercise ExecutorCompletionService
+ * @library /lib/testlibrary/
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import jdk.testlibrary.Utils;
public class ExecutorCompletionServiceLoops {
- static final int POOLSIZE = 100;
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+ static final int POOLSIZE = 10;
static final ExecutorService pool =
Executors.newFixedThreadPool(POOLSIZE);
static final ExecutorCompletionService<Integer> ecs =
@@ -55,23 +57,21 @@
public static void main(String[] args) throws Exception {
int max = 8;
- int base = 10000;
+ int base = 2000;
if (args.length > 0)
max = Integer.parseInt(args[0]);
System.out.println("Warmup...");
oneTest(base);
- Thread.sleep(100);
print = true;
for (int i = 1; i <= max; i += (i+1) >>> 1) {
System.out.print("n: " + i * base);
oneTest(i * base);
- Thread.sleep(100);
}
pool.shutdown();
- if (! pool.awaitTermination(60L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/Executors/AutoShutdown.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/Executors/AutoShutdown.java Thu Mar 03 12:49:12 2016 -0800
@@ -24,26 +24,32 @@
/*
* @test
* @bug 6399443
+ * @summary Check for auto-shutdown and gc of singleThreadExecutors
+ * @library /lib/testlibrary/
* @run main/othervm/timeout=1000 AutoShutdown
- * @summary Check for auto-shutdown and gc of singleThreadExecutors
* @author Martin Buchholz
*/
+import static java.util.concurrent.Executors.defaultThreadFactory;
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-import static java.util.concurrent.Executors.defaultThreadFactory;
-import static java.util.concurrent.Executors.newFixedThreadPool;
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import jdk.testlibrary.Utils;
public class AutoShutdown {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static void await(CountDownLatch latch) throws InterruptedException {
- if (!latch.await(100L, TimeUnit.SECONDS))
+ if (!latch.await(LONG_DELAY_MS, MILLISECONDS))
throw new AssertionError("timed out waiting for latch");
}
--- a/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,13 +34,14 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=2000 CancelledFutureLoops
* @summary Checks for responsiveness of futures to cancellation.
* Runs under the assumption that ITERS computations require more than
* TIMEOUT msecs to complete.
+ * @library /lib/testlibrary/
+ * @run main/timeout=2000 CancelledFutureLoops
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.SplittableRandom;
import java.util.concurrent.BrokenBarrierException;
@@ -51,8 +52,10 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
+import jdk.testlibrary.Utils;
public final class CancelledFutureLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final ExecutorService pool = Executors.newCachedThreadPool();
static final SplittableRandom rnd = new SplittableRandom();
static boolean print = false;
@@ -80,7 +83,7 @@
Thread.sleep(TIMEOUT);
}
pool.shutdown();
- if (! pool.awaitTermination(60L, SECONDS))
+ if (! pool.awaitTermination(6 * LONG_DELAY_MS, MILLISECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/FutureTask/DoneMeansDone.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/DoneMeansDone.java Thu Mar 03 12:49:12 2016 -0800
@@ -36,8 +36,11 @@
* @bug 8073704
* @summary Checks that once isDone() returns true,
* get() never throws InterruptedException or TimeoutException
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
@@ -49,8 +52,11 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import jdk.testlibrary.Utils;
public class DoneMeansDone {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+
public static void main(String[] args) throws Throwable {
final int iters = 1000;
final int nThreads = 2;
@@ -92,7 +98,7 @@
}
done.set(true);
pool.shutdown();
- if (!pool.awaitTermination(10L, TimeUnit.SECONDS))
+ if (!pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new AssertionError();
for (Future<?> future : futures)
future.get();
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,14 +35,21 @@
* @test
* @bug 6725789
* @summary Check for long overflow in task time comparison.
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.DAYS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import jdk.testlibrary.Utils;
public class DelayOverflow {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+
static void waitForNanoTimeTick() {
for (long t0 = System.nanoTime(); t0 == System.nanoTime(); )
;
@@ -52,16 +59,16 @@
Runnable r, int how) {
switch (how) {
case 0:
- pool.schedule(r, 0, TimeUnit.MILLISECONDS);
+ pool.schedule(r, 0, MILLISECONDS);
break;
case 1:
- pool.schedule(Executors.callable(r), 0, TimeUnit.DAYS);
+ pool.schedule(Executors.callable(r), 0, DAYS);
break;
case 2:
- pool.scheduleWithFixedDelay(r, 0, 1000, TimeUnit.NANOSECONDS);
+ pool.scheduleWithFixedDelay(r, 0, 1000, NANOSECONDS);
break;
case 3:
- pool.scheduleAtFixedRate(r, 0, 1000, TimeUnit.MILLISECONDS);
+ pool.scheduleAtFixedRate(r, 0, 1000, MILLISECONDS);
break;
default:
fail(String.valueOf(how));
@@ -72,16 +79,16 @@
Runnable r, int how) {
switch (how) {
case 0:
- pool.schedule(r, Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+ pool.schedule(r, Long.MAX_VALUE, MILLISECONDS);
break;
case 1:
- pool.schedule(Executors.callable(r), Long.MAX_VALUE, TimeUnit.DAYS);
+ pool.schedule(Executors.callable(r), Long.MAX_VALUE, DAYS);
break;
case 2:
- pool.scheduleWithFixedDelay(r, Long.MAX_VALUE, 1000, TimeUnit.NANOSECONDS);
+ pool.scheduleWithFixedDelay(r, Long.MAX_VALUE, 1000, NANOSECONDS);
break;
case 3:
- pool.scheduleAtFixedRate(r, Long.MAX_VALUE, 1000, TimeUnit.MILLISECONDS);
+ pool.scheduleAtFixedRate(r, Long.MAX_VALUE, 1000, MILLISECONDS);
break;
default:
fail(String.valueOf(how));
@@ -114,14 +121,14 @@
proceedLatch.await();
} catch (Throwable t) { unexpected(t); }
}};
- pool.schedule(keepPoolBusy, 0, TimeUnit.SECONDS);
+ pool.schedule(keepPoolBusy, 0, DAYS);
busyLatch.await();
scheduleNow(pool, notifier, nowHow);
waitForNanoTimeTick();
scheduleAtTheEndOfTime(pool, neverRuns, thenHow);
proceedLatch.countDown();
- check(runLatch.await(10L, TimeUnit.SECONDS));
+ check(runLatch.await(LONG_DELAY_MS, MILLISECONDS));
equal(runLatch.getCount(), 0L);
pool.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
@@ -142,10 +149,9 @@
} catch (Throwable t) { unexpected(t); }
}};
pool.scheduleWithFixedDelay(scheduleNowScheduler,
- 0, Long.MAX_VALUE,
- TimeUnit.NANOSECONDS);
+ 0, Long.MAX_VALUE, NANOSECONDS);
- check(runLatch.await(10L, TimeUnit.SECONDS));
+ check(runLatch.await(LONG_DELAY_MS, MILLISECONDS));
equal(runLatch.getCount(), 0L);
pool.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,8 +34,11 @@
/*
* @test
* @summary Ensure that waiting pool threads don't retain refs to tasks.
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.lang.ref.WeakReference;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutionException;
@@ -44,8 +47,11 @@
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import jdk.testlibrary.Utils;
public class GCRetention {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+
/**
* A custom thread pool with a custom RunnableScheduledFuture, for the
* sole purpose of ensuring that the task retains a strong reference to
@@ -116,7 +122,7 @@
Thread.sleep(10);
}
pool.shutdown();
- pool.awaitTermination(10L, TimeUnit.SECONDS);
+ pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS);
if (cleared < size)
throw new Error(String.format
("references to %d/%d tasks retained (\"leaked\")",
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCorePoolSize.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCorePoolSize.java Thu Mar 03 12:49:12 2016 -0800
@@ -26,16 +26,21 @@
* @bug 7091003
* @summary ScheduledExecutorService never executes Runnable
* with corePoolSize of zero
+ * @library /lib/testlibrary/
* @author Chris Hegarty
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import jdk.testlibrary.Utils;
/**
* Verify that tasks can be run even with a core pool size of 0.
*/
public class ZeroCorePoolSize {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
volatile boolean taskRun;
@@ -49,10 +54,10 @@
};
check(pool.getCorePoolSize() == 0);
- pool.schedule(task, 1, TimeUnit.SECONDS);
+ pool.schedule(task, 12L, MILLISECONDS);
pool.shutdown();
- check(pool.awaitTermination(20L, TimeUnit.SECONDS));
+ check(pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
check(pool.getCorePoolSize() == 0);
check(taskRun);
}
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,9 +35,11 @@
* @test
* @bug 8022642 8065320 8129861
* @summary Ensure relative sanity when zero core threads
+ * @library /lib/testlibrary/
*/
import static java.util.concurrent.TimeUnit.HOURS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.lang.reflect.Field;
@@ -45,8 +47,28 @@
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.BooleanSupplier;
+import jdk.testlibrary.Utils;
public class ZeroCoreThreads {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+
+ static long millisElapsedSince(long startTime) {
+ return (System.nanoTime() - startTime) / (1000L * 1000L);
+ }
+
+ static void spinWaitUntil(BooleanSupplier predicate, long timeoutMillis) {
+ long startTime = -1L;
+ while (!predicate.getAsBoolean()) {
+ if (startTime == -1L)
+ startTime = System.nanoTime();
+ else if (millisElapsedSince(startTime) > timeoutMillis)
+ throw new AssertionError(
+ String.format("timed out after %s ms", timeoutMillis));
+ Thread.yield();
+ }
+ }
+
static boolean hasWaiters(ReentrantLock lock, Condition condition) {
lock.lock();
try {
@@ -56,6 +78,11 @@
}
}
+ static void awaitHasWaiters(ReentrantLock lock, Condition condition,
+ long timeoutMillis) {
+ spinWaitUntil(() -> hasWaiters(lock, condition), timeoutMillis);
+ }
+
static <T> T getField(Object x, String fieldName) {
try {
Field field = x.getClass().getDeclaredField(fieldName);
@@ -72,7 +99,7 @@
test(p);
} finally {
p.shutdownNow();
- check(p.awaitTermination(10L, SECONDS));
+ check(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
}
}
@@ -89,13 +116,7 @@
equal(0L, p.getCompletedTaskCount());
p.schedule(dummy, 1L, HOURS);
// Ensure one pool thread actually waits in timed queue poll
- long t0 = System.nanoTime();
- while (!hasWaiters(lock, available)) {
- if (System.nanoTime() - t0 > SECONDS.toNanos(10L))
- throw new AssertionError
- ("timed out waiting for a waiter to show up");
- Thread.yield();
- }
+ awaitHasWaiters(lock, available, LONG_DELAY_MS);
equal(1, p.getPoolSize());
equal(1, p.getLargestPoolSize());
equal(1L, p.getTaskCount());
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java Thu Mar 03 12:49:12 2016 -0800
@@ -25,17 +25,22 @@
* @test
* @bug 6233235 6268386
* @summary Test allowsCoreThreadTimeOut
+ * @library /lib/testlibrary/
* @author Martin Buchholz
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import jdk.testlibrary.Utils;
public class CoreThreadTimeOut {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static class IdentifiableThreadFactory implements ThreadFactory {
static ThreadFactory defaultThreadFactory
@@ -60,8 +65,8 @@
return count;
}
- static long millisElapsedSince(long t0) {
- return (System.nanoTime() - t0) / (1000L * 1000L);
+ static long millisElapsedSince(long startTime) {
+ return (System.nanoTime() - startTime) / (1000L * 1000L);
}
void test(String[] args) throws Throwable {
@@ -89,7 +94,7 @@
equal(countExecutorThreads(), 0);
tpe.shutdown();
check(tpe.allowsCoreThreadTimeOut());
- check(tpe.awaitTermination(10L, TimeUnit.SECONDS));
+ check(tpe.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new Exception("Some tests failed");
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Thu Mar 03 12:49:12 2016 -0800
@@ -25,9 +25,12 @@
* @test
* @bug 6277663
* @summary Test TPE extensibility framework
+ * @library /lib/testlibrary/
* @author Martin Buchholz
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
@@ -37,8 +40,11 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BooleanSupplier;
+import jdk.testlibrary.Utils;
public class Custom {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static volatile int passed = 0, failed = 0;
static void pass() { passed++; }
static void fail() { failed++; Thread.dumpStack(); }
@@ -97,6 +103,22 @@
private static final int threadCount = 10;
+ static long millisElapsedSince(long startTime) {
+ return (System.nanoTime() - startTime) / (1000L * 1000L);
+ }
+
+ static void spinWaitUntil(BooleanSupplier predicate, long timeoutMillis) {
+ long startTime = -1L;
+ while (!predicate.getAsBoolean()) {
+ if (startTime == -1L)
+ startTime = System.nanoTime();
+ else if (millisElapsedSince(startTime) > timeoutMillis)
+ throw new AssertionError(
+ String.format("timed out after %s ms", timeoutMillis));
+ Thread.yield();
+ }
+ }
+
public static void main(String[] args) throws Throwable {
CustomTPE tpe = new CustomTPE();
equal(tpe.getCorePoolSize(), threadCount);
@@ -106,9 +128,8 @@
equal(countExecutorThreads(), threadCount);
equal(CustomTask.births.get(), threadCount);
tpe.shutdown();
- tpe.awaitTermination(120L, TimeUnit.SECONDS);
- Thread.sleep(1000);
- equal(countExecutorThreads(), 0);
+ tpe.awaitTermination(LONG_DELAY_MS, MILLISECONDS);
+ spinWaitUntil(() -> countExecutorThreads() == 0, LONG_DELAY_MS);
CustomSTPE stpe = new CustomSTPE();
for (int i = 0; i < threadCount; i++)
@@ -116,9 +137,8 @@
equal(CustomSTPE.decorations.get(), threadCount);
equal(countExecutorThreads(), threadCount);
stpe.shutdown();
- stpe.awaitTermination(120L, TimeUnit.SECONDS);
- Thread.sleep(1000);
- equal(countExecutorThreads(), 0);
+ stpe.awaitTermination(LONG_DELAY_MS, MILLISECONDS);
+ spinWaitUntil(() -> countExecutorThreads() == 0, LONG_DELAY_MS);
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new Exception("Some tests failed");
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,14 +35,20 @@
/*
* @test
* @summary Should be able to shutdown a pool when worker creation failed.
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import jdk.testlibrary.Utils;
public class FlakyThreadFactory {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+
void test(String[] args) throws Throwable {
test(NullPointerException.class,
new ThreadFactory() {
@@ -89,7 +95,7 @@
check(exceptionClass.isInstance(t));
}
pool.shutdown();
- check(pool.awaitTermination(10L, TimeUnit.SECONDS));
+ check(pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
}
//--------------------- Infrastructure ---------------------------
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java Thu Mar 03 12:49:12 2016 -0800
@@ -25,14 +25,20 @@
* @test
* @bug 6576792
* @summary non-idle worker threads should not be interrupted
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import jdk.testlibrary.Utils;
public class SelfInterrupt {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+
void test(String[] args) throws Throwable {
final int n = 100;
final ThreadPoolExecutor pool =
@@ -58,7 +64,7 @@
} catch (Throwable t) { unexpected(t); }}});
finishLine.await();
pool.shutdown();
- check(pool.awaitTermination(1000L, TimeUnit.SECONDS));
+ check(pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
}
//--------------------- Infrastructure ---------------------------
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java Thu Mar 03 12:49:12 2016 -0800
@@ -36,6 +36,7 @@
* @test
* @summary Only one thread should be created when a thread needs to
* be kept alive to service a delayed task waiting in the queue.
+ * @library /lib/testlibrary/
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -44,8 +45,12 @@
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;
+import jdk.testlibrary.Utils;
public class ThreadRestarts {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+ static final long FAR_FUTURE_MS = 10 * LONG_DELAY_MS;
+
public static void main(String[] args) throws Exception {
test(false);
test(true);
@@ -56,14 +61,15 @@
ScheduledThreadPoolExecutor stpe
= new ScheduledThreadPoolExecutor(10, ctf);
try {
+ // schedule a dummy task in the "far future"
Runnable nop = new Runnable() { public void run() {}};
- stpe.schedule(nop, 10*1000L, MILLISECONDS);
+ stpe.schedule(nop, FAR_FUTURE_MS, MILLISECONDS);
stpe.setKeepAliveTime(1L, MILLISECONDS);
stpe.allowCoreThreadTimeOut(allowTimeout);
- MILLISECONDS.sleep(100L);
+ MILLISECONDS.sleep(12L);
} finally {
stpe.shutdownNow();
- if (!stpe.awaitTermination(60L, SECONDS))
+ if (!stpe.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new AssertionError("timed out");
}
if (ctf.count.get() > 1)
@@ -76,8 +82,9 @@
final AtomicLong count = new AtomicLong(0L);
public Thread newThread(Runnable r) {
+ count.getAndIncrement();
Thread t = new Thread(r);
- count.getAndIncrement();
+ t.setDaemon(true);
return t;
}
}
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java Thu Mar 03 12:49:12 2016 -0800
@@ -25,15 +25,22 @@
* @test
* @bug 6458662
* @summary poolSize might shrink below corePoolSize after timeout
+ * @library /lib/testlibrary/
* @author Martin Buchholz
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import jdk.testlibrary.Utils;
public class TimeOutShrink {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+ static final long KEEPALIVE_MS = 12L;
+
static void checkPoolSizes(ThreadPoolExecutor pool,
int size, int core, int max) {
equal(pool.getPoolSize(), size);
@@ -45,7 +52,8 @@
final int n = 4;
final CyclicBarrier barrier = new CyclicBarrier(2*n+1);
final ThreadPoolExecutor pool
- = new ThreadPoolExecutor(n, 2*n, 1L, TimeUnit.SECONDS,
+ = new ThreadPoolExecutor(n, 2*n,
+ KEEPALIVE_MS, MILLISECONDS,
new SynchronousQueue<Runnable>());
final Runnable r = new Runnable() { public void run() {
try {
@@ -58,12 +66,16 @@
barrier.await();
checkPoolSizes(pool, 2*n, n, 2*n);
barrier.await();
- while (pool.getPoolSize() > n)
- Thread.sleep(100);
- Thread.sleep(100);
+ long nap = KEEPALIVE_MS + (KEEPALIVE_MS >> 2);
+ for (long sleepyTime = 0L; pool.getPoolSize() > n; ) {
+ check((sleepyTime += nap) <= LONG_DELAY_MS);
+ Thread.sleep(nap);
+ }
+ checkPoolSizes(pool, n, n, 2*n);
+ Thread.sleep(nap);
checkPoolSizes(pool, n, n, 2*n);
pool.shutdown();
- check(pool.awaitTermination(60L, TimeUnit.SECONDS));
+ check(pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
}
//--------------------- Infrastructure ---------------------------
--- a/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,9 +35,10 @@
* @test
* @bug 4486658
* @summary basic safety and liveness of ReentrantLocks, and other locks based on them
+ * @library /lib/testlibrary/
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.SplittableRandom;
import java.util.concurrent.CyclicBarrier;
@@ -47,8 +48,10 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import jdk.testlibrary.Utils;
public final class CheckedLockLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static ExecutorService pool;
static final SplittableRandom rnd = new SplittableRandom();
@@ -63,7 +66,7 @@
oneTest(i, iters / i);
}
pool.shutdown();
- if (! pool.awaitTermination(10L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
pool = null;
}
--- a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Thu Mar 03 12:49:12 2016 -0800
@@ -25,9 +25,12 @@
* @test
* @bug 6503247 6574123
* @summary Test resilience to tryAcquire methods that throw
+ * @library /lib/testlibrary/
* @author Martin Buchholz
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
@@ -36,6 +39,7 @@
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
+import jdk.testlibrary.Utils;
/**
* This uses a variant of the standard Mutex demo, except with a
@@ -44,6 +48,7 @@
*/
@SuppressWarnings("serial")
public class FlakyMutex implements Lock {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static class MyError extends Error {}
static class MyException extends Exception {}
static class MyRuntimeException extends RuntimeException {}
@@ -91,7 +96,7 @@
} catch (Throwable t) { unexpected(t); }}});}
barrier.await();
es.shutdown();
- check(es.awaitTermination(30L, TimeUnit.SECONDS));
+ check(es.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
}
private static class FlakySync extends AbstractQueuedLongSynchronizer {
--- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java Thu Mar 03 12:49:12 2016 -0800
@@ -25,9 +25,11 @@
* @test
* @bug 6460501 6236036 6500694 6490770
* @summary Repeated failed timed waits shouldn't leak memory
+ * @library /lib/testlibrary/
* @author Martin Buchholz
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -54,8 +56,11 @@
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import jdk.testlibrary.Utils;
public class TimedAcquireLeak {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
+
static String javahome() {
String jh = System.getProperty("java.home");
return (jh.endsWith("jre")) ? jh.substring(0, jh.length() - 4) : jh;
@@ -191,7 +196,7 @@
final String[] jobCmd = {
java, "-Xmx8m", "-XX:+UsePerfData",
- "-classpath", System.getProperty("test.classes", "."),
+ "-classpath", System.getProperty("test.class.path"),
childClassName, uniqueID
};
final Process p = new ProcessBuilder(jobCmd).start();
@@ -219,7 +224,7 @@
check(Math.abs(n1 - n0) < 10);
check(n1 < 25);
drainers.shutdown();
- if (!drainers.awaitTermination(10L, SECONDS)) {
+ if (!drainers.awaitTermination(LONG_DELAY_MS, MILLISECONDS)) {
drainers.shutdownNow(); // last resort
throw new AssertionError("thread pool did not terminate");
}
--- a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,11 +35,12 @@
* @test
* @bug 8074773
* @summary Stress test looks for lost unparks
+ * @library /lib/testlibrary/
* @modules java.management
- * @run main/timeout=1200 ParkLoops
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.util.SplittableRandom;
@@ -49,13 +50,12 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.LockSupport;
+import jdk.testlibrary.Utils;
public final class ParkLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final int THREADS = 4;
- // static final int ITERS = 2_000_000;
- // static final int TIMEOUT = 3500; // in seconds
- static final int ITERS = 100_000;
- static final int TIMEOUT = 1000; // in seconds
+ static final int ITERS = 30_000;
static class Parker implements Runnable {
static {
@@ -130,13 +130,13 @@
pool.submit(unparker);
}
try {
- if (!done.await(TIMEOUT, SECONDS)) {
+ if (!done.await(LONG_DELAY_MS, MILLISECONDS)) {
dumpAllStacks();
throw new AssertionError("lost unpark");
}
} finally {
pool.shutdown();
- pool.awaitTermination(10L, SECONDS);
+ pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS);
}
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,25 +34,27 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=15000 LockOncePerThreadLoops
* @summary Checks for missed signals by locking and unlocking each of an array of locks once per thread
+ * @library /lib/testlibrary/
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.SplittableRandom;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;
+import jdk.testlibrary.Utils;
public final class LockOncePerThreadLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final ExecutorService pool = Executors.newCachedThreadPool();
static final SplittableRandom rnd = new SplittableRandom();
static boolean print = false;
- static int nlocks = 50000;
- static int nthreads = 100;
- static int replications = 5;
+ static int nlocks = 20_000;
+ static int nthreads = 20;
+ static int replications = 3;
public static void main(String[] args) throws Exception {
if (args.length > 0)
@@ -66,10 +68,9 @@
for (int i = 0; i < replications; ++i) {
System.out.print("Iteration: " + i);
new ReentrantLockLoop().test();
- Thread.sleep(100);
}
pool.shutdown();
- if (! pool.awaitTermination(60L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,23 +34,25 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=4500 SimpleReentrantLockLoops
* @summary multiple threads using a single lock
+ * @library /lib/testlibrary/
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.SplittableRandom;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;
+import jdk.testlibrary.Utils;
public final class SimpleReentrantLockLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final ExecutorService pool = Executors.newCachedThreadPool();
static final SplittableRandom rnd = new SplittableRandom();
static boolean print = false;
- static int iters = 1000000;
+ static int iters = 100_000;
public static void main(String[] args) throws Exception {
int maxThreads = 5;
@@ -66,11 +68,10 @@
while (n-- > 0) {
System.out.print("Threads: " + i);
new ReentrantLockLoop(i).test();
- Thread.sleep(100);
}
}
pool.shutdown();
- if (! pool.awaitTermination(60L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,18 +34,22 @@
/*
* @test
* @bug 4486658 5031862 8140471
- * @run main TimeoutLockLoops
* @summary Checks for responsiveness of locks to timeouts.
+ * @library /lib/testlibrary/
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.util.SplittableRandom;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
+import jdk.testlibrary.Utils;
public final class TimeoutLockLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final ExecutorService pool = Executors.newCachedThreadPool();
static final SplittableRandom rnd = new SplittableRandom();
static boolean print = false;
@@ -63,7 +67,7 @@
new ReentrantLockLoop(i).test();
}
pool.shutdown();
- if (! pool.awaitTermination(60L, TimeUnit.SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java Thu Mar 03 12:49:12 2016 -0800
@@ -25,9 +25,12 @@
* @test
* @bug 6207928 6328220 6378321 6625723
* @summary Recursive lock invariant sanity checks
+ * @library /lib/testlibrary/
* @author Martin Buchholz
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -42,9 +45,11 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import jdk.testlibrary.Utils;
// I am the Cownt, and I lahve to cownt.
public class Count {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
final Random rnd = new Random();
void lock(Lock lock) {
@@ -102,7 +107,7 @@
barrier.await();
} catch (Throwable t) { unexpected(t); }}});}
es.shutdown();
- check(es.awaitTermination(10L, TimeUnit.SECONDS));
+ check(es.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
}
void testReentrantLocks(final boolean fair,
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Thu Mar 03 12:49:12 2016 -0800
@@ -41,17 +41,20 @@
* inserts it, and if present, with probability premove it removes
* it. (pinsert and premove are expressed as percentages to simplify
* parsing from command line.)
+ * @library /lib/testlibrary/
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.Map;
import java.util.SplittableRandom;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import jdk.testlibrary.Utils;
public class MapLoops {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final int NKEYS = 100000;
static int pinsert = 60;
static int premove = 2;
@@ -125,7 +128,7 @@
map.clear();
}
pool.shutdown();
- if (! pool.awaitTermination(10L, SECONDS))
+ if (! pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java Thu Mar 03 12:49:12 2016 -0800
@@ -35,6 +35,7 @@
* @test
* @bug 8005697
* @summary Basic tests for StampedLock
+ * @library /lib/testlibrary/
* @author Chris Hegarty
*/
@@ -49,8 +50,10 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.StampedLock;
+import jdk.testlibrary.Utils;
public class Basic {
+ static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static void checkResult(Locker l, Class<? extends Throwable> c) {
Throwable t = l.thrown();
@@ -268,7 +271,7 @@
case 2: case 5:
return interruptibleReader(sl, -1, SECONDS, gate, view ^= true);
default:
- return interruptibleReader(sl, 30, SECONDS, gate, view ^= true); }}
+ return interruptibleReader(sl, LONG_DELAY_MS, MILLISECONDS, gate, view ^= true); }}
public void remove() {throw new UnsupportedOperationException();}};
}
@@ -286,7 +289,7 @@
case 2: case 5:
return interruptibleWriter(sl, -1, SECONDS, gate, view ^= true);
default:
- return interruptibleWriter(sl, 30, SECONDS, gate, view ^= true); }}
+ return interruptibleWriter(sl, LONG_DELAY_MS, MILLISECONDS, gate, view ^= true); }}
public void remove() {throw new UnsupportedOperationException();}};
}
@@ -454,13 +457,13 @@
// We test interrupting both before and after trying to acquire
boolean view = false;
StampedLock sl = new StampedLock();
- for (long timeout : new long[] { -1L, 30L, -1L, 30L }) {
+ for (long timeout : new long[] { -1L, LONG_DELAY_MS, -1L, LONG_DELAY_MS }) {
long stamp;
Thread.State state;
stamp = sl.writeLock();
try {
- Reader r = interruptibleReader(sl, timeout, SECONDS, null, view);
+ Reader r = interruptibleReader(sl, timeout, MILLISECONDS, null, view);
r.start();
r.interrupt();
r.join();
@@ -471,7 +474,7 @@
stamp = sl.writeLock();
try {
- Reader r = interruptibleReader(sl, timeout, SECONDS, null, view);
+ Reader r = interruptibleReader(sl, timeout, MILLISECONDS, null, view);
r.start();
waitForThreadToBlock(r);
r.interrupt();
@@ -483,7 +486,7 @@
stamp = sl.readLock();
try {
- Writer w = interruptibleWriter(sl, timeout, SECONDS, null, view);
+ Writer w = interruptibleWriter(sl, timeout, MILLISECONDS, null, view);
w.start();
w.interrupt();
w.join();
@@ -494,7 +497,7 @@
stamp = sl.readLock();
try {
- Writer w = interruptibleWriter(sl, timeout, SECONDS, null, view);
+ Writer w = interruptibleWriter(sl, timeout, MILLISECONDS, null, view);
w.start();
waitForThreadToBlock(w);
w.interrupt();
@@ -509,7 +512,7 @@
check(!sl.tryUnlockRead());
check(!sl.tryUnlockWrite());
check(sl.tryOptimisticRead() != 0L);
- if (timeout == 30L)
+ if (timeout == LONG_DELAY_MS)
view = true;
}
} catch (Throwable t) { unexpected(t); }
--- a/jdk/test/java/util/concurrent/tck/Collection8Test.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/tck/Collection8Test.java Thu Mar 03 12:49:12 2016 -0800
@@ -37,6 +37,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@@ -98,26 +99,29 @@
public void testForEachConcurrentStressTest() throws Throwable {
if (!impl.isConcurrent()) return;
final Collection c = impl.emptyCollection();
- final long testDurationMillis = SHORT_DELAY_MS;
+ final long testDurationMillis = timeoutMillis();
final AtomicBoolean done = new AtomicBoolean(false);
final Object elt = impl.makeElement(1);
- ExecutorService pool = Executors.newCachedThreadPool();
- Runnable checkElt = () -> {
- while (!done.get())
- c.stream().forEach((x) -> { assertSame(x, elt); }); };
- Runnable addRemove = () -> {
- while (!done.get()) {
- assertTrue(c.add(elt));
- assertTrue(c.remove(elt));
- }};
- Future<?> f1 = pool.submit(checkElt);
- Future<?> f2 = pool.submit(addRemove);
- Thread.sleep(testDurationMillis);
- done.set(true);
- pool.shutdown();
- assertTrue(pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
- assertNull(f1.get(LONG_DELAY_MS, MILLISECONDS));
- assertNull(f2.get(LONG_DELAY_MS, MILLISECONDS));
+ final Future<?> f1, f2;
+ final ExecutorService pool = Executors.newCachedThreadPool();
+ try (PoolCleaner cleaner = cleaner(pool, done)) {
+ final CountDownLatch threadsStarted = new CountDownLatch(2);
+ Runnable checkElt = () -> {
+ threadsStarted.countDown();
+ while (!done.get())
+ c.stream().forEach((x) -> { assertSame(x, elt); }); };
+ Runnable addRemove = () -> {
+ threadsStarted.countDown();
+ while (!done.get()) {
+ assertTrue(c.add(elt));
+ assertTrue(c.remove(elt));
+ }};
+ f1 = pool.submit(checkElt);
+ f2 = pool.submit(addRemove);
+ Thread.sleep(testDurationMillis);
+ }
+ assertNull(f1.get(0L, MILLISECONDS));
+ assertNull(f2.get(0L, MILLISECONDS));
}
// public void testCollection8DebugFail() { fail(); }
--- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java Thu Mar 03 12:49:12 2016 -0800
@@ -88,6 +88,7 @@
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -210,11 +211,31 @@
private static final int suiteRuns =
Integer.getInteger("jsr166.suiteRuns", 1);
+ private static float systemPropertyValue(String name, float defaultValue) {
+ String floatString = System.getProperty(name);
+ if (floatString == null)
+ return defaultValue;
+ try {
+ return Float.parseFloat(floatString);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException(
+ String.format("Bad float value in system property %s=%s",
+ name, floatString));
+ }
+ }
+
/**
* The scaling factor to apply to standard delays used in tests.
*/
- private static final int delayFactor =
- Integer.getInteger("jsr166.delay.factor", 1);
+ private static final float delayFactor =
+ systemPropertyValue("jsr166.delay.factor", 1.0f);
+
+ /**
+ * The timeout factor as used in the jtreg test harness.
+ * See: http://openjdk.java.net/jtreg/tag-spec.html
+ */
+ private static final float jtregTestTimeoutFactor
+ = systemPropertyValue("test.timeout.factor", 1.0f);
public JSR166TestCase() { super(); }
public JSR166TestCase(String name) { super(name); }
@@ -590,10 +611,12 @@
/**
* Returns the shortest timed delay. This can be scaled up for
- * slow machines using the jsr166.delay.factor system property.
+ * slow machines using the jsr166.delay.factor system property,
+ * or via jtreg's -timeoutFactor: flag.
+ * http://openjdk.java.net/jtreg/command-help.html
*/
protected long getShortDelay() {
- return 50 * delayFactor;
+ return (long) (50 * delayFactor * jtregTestTimeoutFactor);
}
/**
@@ -906,6 +929,14 @@
}};
}
+ PoolCleaner cleaner(ExecutorService pool, AtomicBoolean flag) {
+ return new PoolCleanerWithReleaser(pool, releaser(flag));
+ }
+
+ Runnable releaser(final AtomicBoolean flag) {
+ return new Runnable() { public void run() { flag.set(true); }};
+ }
+
/**
* Waits out termination of a thread pool or fails doing so.
*/
@@ -1462,16 +1493,20 @@
return new LatchAwaiter(latch);
}
- public void await(CountDownLatch latch) {
+ public void await(CountDownLatch latch, long timeoutMillis) {
try {
- if (!latch.await(LONG_DELAY_MS, MILLISECONDS))
+ if (!latch.await(timeoutMillis, MILLISECONDS))
fail("timed out waiting for CountDownLatch for "
- + (LONG_DELAY_MS/1000) + " sec");
+ + (timeoutMillis/1000) + " sec");
} catch (Throwable fail) {
threadUnexpectedException(fail);
}
}
+ public void await(CountDownLatch latch) {
+ await(latch, LONG_DELAY_MS);
+ }
+
public void await(Semaphore semaphore) {
try {
if (!semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS))
--- a/jdk/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -32,6 +32,7 @@
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
@@ -55,7 +56,9 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -226,52 +229,75 @@
}
/**
- * scheduleAtFixedRate executes series of tasks at given rate
+ * scheduleAtFixedRate executes series of tasks at given rate.
+ * Eventually, it must hold that:
+ * cycles - 1 <= elapsedMillis/delay < cycles
*/
public void testFixedRateSequence() throws InterruptedException {
final CustomExecutor p = new CustomExecutor(1);
try (PoolCleaner cleaner = cleaner(p)) {
for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
- long startTime = System.nanoTime();
- int cycles = 10;
+ final long startTime = System.nanoTime();
+ final int cycles = 8;
final CountDownLatch done = new CountDownLatch(cycles);
- Runnable task = new CheckedRunnable() {
+ final Runnable task = new CheckedRunnable() {
public void realRun() { done.countDown(); }};
- ScheduledFuture h =
+ final ScheduledFuture periodicTask =
p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
- await(done);
- h.cancel(true);
- double normalizedTime =
- (double) millisElapsedSince(startTime) / delay;
- if (normalizedTime >= cycles - 1 &&
- normalizedTime <= cycles)
+ final int totalDelayMillis = (cycles - 1) * delay;
+ await(done, totalDelayMillis + LONG_DELAY_MS);
+ periodicTask.cancel(true);
+ final long elapsedMillis = millisElapsedSince(startTime);
+ assertTrue(elapsedMillis >= totalDelayMillis);
+ if (elapsedMillis <= cycles * delay)
return;
+ // else retry with longer delay
}
fail("unexpected execution rate");
}
}
/**
- * scheduleWithFixedDelay executes series of tasks with given period
+ * scheduleWithFixedDelay executes series of tasks with given period.
+ * Eventually, it must hold that each task starts at least delay and at
+ * most 2 * delay after the termination of the previous task.
*/
public void testFixedDelaySequence() throws InterruptedException {
final CustomExecutor p = new CustomExecutor(1);
try (PoolCleaner cleaner = cleaner(p)) {
for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
- long startTime = System.nanoTime();
- int cycles = 10;
+ final long startTime = System.nanoTime();
+ final AtomicLong previous = new AtomicLong(startTime);
+ final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
+ final int cycles = 8;
final CountDownLatch done = new CountDownLatch(cycles);
- Runnable task = new CheckedRunnable() {
- public void realRun() { done.countDown(); }};
- ScheduledFuture h =
+ final int d = delay;
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ long now = System.nanoTime();
+ long elapsedMillis
+ = NANOSECONDS.toMillis(now - previous.get());
+ if (done.getCount() == cycles) { // first execution
+ if (elapsedMillis >= d)
+ tryLongerDelay.set(true);
+ } else {
+ assertTrue(elapsedMillis >= d);
+ if (elapsedMillis >= 2 * d)
+ tryLongerDelay.set(true);
+ }
+ previous.set(now);
+ done.countDown();
+ }};
+ final ScheduledFuture periodicTask =
p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
- await(done);
- h.cancel(true);
- double normalizedTime =
- (double) millisElapsedSince(startTime) / delay;
- if (normalizedTime >= cycles - 1 &&
- normalizedTime <= cycles)
+ final int totalDelayMillis = (cycles - 1) * delay;
+ await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
+ periodicTask.cancel(true);
+ final long elapsedMillis = millisElapsedSince(startTime);
+ assertTrue(elapsedMillis >= totalDelayMillis);
+ if (!tryLongerDelay.get())
return;
+ // else retry with longer delay
}
fail("unexpected execution rate");
}
--- a/jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -34,6 +34,7 @@
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
@@ -52,7 +53,9 @@
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -170,52 +173,75 @@
}
/**
- * scheduleAtFixedRate executes series of tasks at given rate
+ * scheduleAtFixedRate executes series of tasks at given rate.
+ * Eventually, it must hold that:
+ * cycles - 1 <= elapsedMillis/delay < cycles
*/
public void testFixedRateSequence() throws InterruptedException {
final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
try (PoolCleaner cleaner = cleaner(p)) {
for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
- long startTime = System.nanoTime();
- int cycles = 10;
+ final long startTime = System.nanoTime();
+ final int cycles = 8;
final CountDownLatch done = new CountDownLatch(cycles);
- Runnable task = new CheckedRunnable() {
+ final Runnable task = new CheckedRunnable() {
public void realRun() { done.countDown(); }};
- ScheduledFuture h =
+ final ScheduledFuture periodicTask =
p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
- await(done);
- h.cancel(true);
- double normalizedTime =
- (double) millisElapsedSince(startTime) / delay;
- if (normalizedTime >= cycles - 1 &&
- normalizedTime <= cycles)
+ final int totalDelayMillis = (cycles - 1) * delay;
+ await(done, totalDelayMillis + LONG_DELAY_MS);
+ periodicTask.cancel(true);
+ final long elapsedMillis = millisElapsedSince(startTime);
+ assertTrue(elapsedMillis >= totalDelayMillis);
+ if (elapsedMillis <= cycles * delay)
return;
+ // else retry with longer delay
}
fail("unexpected execution rate");
}
}
/**
- * scheduleWithFixedDelay executes series of tasks with given period
+ * scheduleWithFixedDelay executes series of tasks with given period.
+ * Eventually, it must hold that each task starts at least delay and at
+ * most 2 * delay after the termination of the previous task.
*/
public void testFixedDelaySequence() throws InterruptedException {
final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
try (PoolCleaner cleaner = cleaner(p)) {
for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
- long startTime = System.nanoTime();
- int cycles = 10;
+ final long startTime = System.nanoTime();
+ final AtomicLong previous = new AtomicLong(startTime);
+ final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
+ final int cycles = 8;
final CountDownLatch done = new CountDownLatch(cycles);
- Runnable task = new CheckedRunnable() {
- public void realRun() { done.countDown(); }};
- ScheduledFuture h =
+ final int d = delay;
+ final Runnable task = new CheckedRunnable() {
+ public void realRun() {
+ long now = System.nanoTime();
+ long elapsedMillis
+ = NANOSECONDS.toMillis(now - previous.get());
+ if (done.getCount() == cycles) { // first execution
+ if (elapsedMillis >= d)
+ tryLongerDelay.set(true);
+ } else {
+ assertTrue(elapsedMillis >= d);
+ if (elapsedMillis >= 2 * d)
+ tryLongerDelay.set(true);
+ }
+ previous.set(now);
+ done.countDown();
+ }};
+ final ScheduledFuture periodicTask =
p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
- await(done);
- h.cancel(true);
- double normalizedTime =
- (double) millisElapsedSince(startTime) / delay;
- if (normalizedTime >= cycles - 1 &&
- normalizedTime <= cycles)
+ final int totalDelayMillis = (cycles - 1) * delay;
+ await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
+ periodicTask.cancel(true);
+ final long elapsedMillis = millisElapsedSince(startTime);
+ assertTrue(elapsedMillis >= totalDelayMillis);
+ if (!tryLongerDelay.get())
return;
+ // else retry with longer delay
}
fail("unexpected execution rate");
}
--- a/jdk/test/java/util/concurrent/tck/ThreadTest.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/concurrent/tck/ThreadTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -77,7 +77,7 @@
*/
public void testGetAndSetDefaultUncaughtExceptionHandler() {
assertEquals(null, Thread.getDefaultUncaughtExceptionHandler());
- // failure due to securityException is OK.
+ // failure due to SecurityException is OK.
// Would be nice to explicitly test both ways, but cannot yet.
Thread.UncaughtExceptionHandler defaultHandler
= Thread.getDefaultUncaughtExceptionHandler();
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarAPI.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/jar/JarFile/MultiReleaseJarAPI.java Thu Mar 03 12:49:12 2016 -0800
@@ -39,9 +39,9 @@
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import jdk.Version;
import static java.util.jar.JarFile.Release;
-import static sun.misc.Version.jdkMajorVersion; // fixme JEP 223 Version
import org.testng.Assert;
import org.testng.annotations.AfterClass;
@@ -50,6 +50,9 @@
public class MultiReleaseJarAPI {
+
+ static final int MAJOR_VERSION = Version.current().major();
+
String userdir = System.getProperty("user.dir",".");
File unversioned = new File(userdir, "unversioned.jar");
File multirelease = new File(userdir, "multi-release.jar");
@@ -106,7 +109,7 @@
}
// assure that we have a Release object corresponding to the actual runtime version
- String version = "VERSION_" + jdkMajorVersion();
+ String version = "VERSION_" + MAJOR_VERSION;
boolean runtimeVersionExists = false;
for (Release value : values) {
if (version.equals(value.name())) runtimeVersionExists = true;
@@ -123,7 +126,7 @@
if (name.equals("BASE")) {
prefix = "";
} else if (name.equals("RUNTIME")) {
- prefix = "META-INF/versions/" + jdkMajorVersion() + "/";
+ prefix = "META-INF/versions/" + MAJOR_VERSION + "/";
} else {
prefix = "META-INF/versions/" + name.substring(8) + "/";
}
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarIterators.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/jar/JarFile/MultiReleaseJarIterators.java Thu Mar 03 12:49:12 2016 -0800
@@ -42,9 +42,9 @@
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.zip.ZipFile;
+import jdk.Version;
import static java.util.jar.JarFile.Release;
-import static sun.misc.Version.jdkMajorVersion; // fixme JEP 223 Version
import org.testng.Assert;
import org.testng.annotations.AfterClass;
@@ -53,6 +53,9 @@
public class MultiReleaseJarIterators {
+
+ static final int MAJOR_VERSION = Version.current().major();
+
String userdir = System.getProperty("user.dir", ".");
File unversioned = new File(userdir, "unversioned.jar");
File multirelease = new File(userdir, "multi-release.jar");
@@ -121,7 +124,7 @@
try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
Map<String,JarEntry> expectedEntries;
- switch (jdkMajorVersion()) {
+ switch (MAJOR_VERSION) {
case 9:
expectedEntries = v9Entries;
break;
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarProperties.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/jar/JarFile/MultiReleaseJarProperties.java Thu Mar 03 12:49:12 2016 -0800
@@ -54,8 +54,7 @@
import java.nio.file.Files;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-
-import static sun.misc.Version.jdkMajorVersion; // fixme JEP 223 Version
+import jdk.Version;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
@@ -63,6 +62,9 @@
import org.testng.annotations.Test;
public class MultiReleaseJarProperties {
+
+ static final int MAJOR_VERSION = Version.current().major();
+
final static int ROOTVERSION = 8; // magic number from knowledge of internals
final static String userdir = System.getProperty("user.dir", ".");
final static File multirelease = new File(userdir, "multi-release.jar");
@@ -77,14 +79,14 @@
creator.compileEntries();
creator.buildMultiReleaseJar();
- rtVersion = Integer.getInteger("jdk.util.jar.version", jdkMajorVersion());
+ rtVersion = Integer.getInteger("jdk.util.jar.version", MAJOR_VERSION);
String mrprop = System.getProperty("jdk.util.jar.enableMultiRelease", "");
if (mrprop.equals("false")) {
rtVersion = ROOTVERSION;
} else if (rtVersion < ROOTVERSION) {
rtVersion = ROOTVERSION;
- } else if (rtVersion > jdkMajorVersion()) {
- rtVersion = jdkMajorVersion();
+ } else if (rtVersion > MAJOR_VERSION) {
+ rtVersion = MAJOR_VERSION;
}
force = mrprop.equals("force");
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarSecurity.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/jar/JarFile/MultiReleaseJarSecurity.java Thu Mar 03 12:49:12 2016 -0800
@@ -40,6 +40,7 @@
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipFile;
+import jdk.Version;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
@@ -47,6 +48,9 @@
import org.testng.annotations.Test;
public class MultiReleaseJarSecurity {
+
+ static final int MAJOR_VERSION = Version.current().major();
+
String userdir = System.getProperty("user.dir",".");
File multirelease = new File(userdir, "multi-release.jar");
File signedmultirelease = new File(userdir, "signed-multi-release.jar");
@@ -68,9 +72,8 @@
@Test
public void testCertsAndSigners() throws IOException {
try (JarFile jf = new JarFile(signedmultirelease, true, ZipFile.OPEN_READ, JarFile.Release.RUNTIME)) {
- int version = sun.misc.Version.jdkMajorVersion(); // fixme JEP 223 Version
CertsAndSigners vcas = new CertsAndSigners(jf, jf.getJarEntry("version/Version.class"));
- CertsAndSigners rcas = new CertsAndSigners(jf, jf.getJarEntry("META-INF/versions/" + version + "/version/Version.class"));
+ CertsAndSigners rcas = new CertsAndSigners(jf, jf.getJarEntry("META-INF/versions/" + MAJOR_VERSION + "/version/Version.class"));
Assert.assertTrue(Arrays.equals(rcas.getCertificates(), vcas.getCertificates()));
Assert.assertTrue(Arrays.equals(rcas.getCodeSigners(), vcas.getCodeSigners()));
}
--- a/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/DoubleStreamTestDataProvider.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/DoubleStreamTestDataProvider.java Thu Mar 03 12:49:12 2016 -0800
@@ -126,6 +126,9 @@
() -> Spliterators.spliterator(isl.iterator(), doubles.length, 0)));
spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
() -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
+ spliterators.add(splitDescr("DoubleStream.iterate(0,x->x<l;x->x+1):" + name,
+ () -> DoubleStream.iterate(0.0, x -> x < doubles.length, x -> x + 1.0)
+ .spliterator()));
// Need more!
}
spliteratorTestData = spliterators.toArray(new Object[0][]);
--- a/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/IntStreamTestDataProvider.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/IntStreamTestDataProvider.java Thu Mar 03 12:49:12 2016 -0800
@@ -136,6 +136,8 @@
() -> IntStream.range(0, ints.length).spliterator()));
spliterators.add(splitDescr("IntStream.intRangeClosed(0,l):" + name,
() -> IntStream.rangeClosed(0, ints.length).spliterator()));
+ spliterators.add(splitDescr("IntStream.iterate(0,x->x<l,x->x+1): " + name,
+ () -> IntStream.iterate(0, x -> x < ints.length, x -> x + 1).spliterator()));
// Need more!
}
spliteratorTestData = spliterators.toArray(new Object[0][]);
--- a/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LongStreamTestDataProvider.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LongStreamTestDataProvider.java Thu Mar 03 12:49:12 2016 -0800
@@ -136,6 +136,9 @@
() -> LongStream.range(0, longs.length).spliterator()));
spliterators.add(splitDescr("LongStream.longRangeClosed(0,l):" + name,
() -> LongStream.rangeClosed(0, longs.length).spliterator()));
+ spliterators.add(splitDescr("LongStream.iterate(0,x->x<l;x->x+1):" + name,
+ () -> LongStream.iterate(0L, x -> x < longs.length, x -> x + 1L)
+ .spliterator()));
// Need more!
}
spliteratorTestData = spliterators.toArray(new Object[0][]);
--- a/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/StreamTestDataProvider.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/StreamTestDataProvider.java Thu Mar 03 12:49:12 2016 -0800
@@ -171,6 +171,8 @@
() -> Spliterators.spliterator(Arrays.asList(ints).iterator(), ints.length, 0)));
spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator()):" + name,
() -> Spliterators.spliteratorUnknownSize(Arrays.asList(ints).iterator(), 0)));
+ spliterators.add(splitDescr("Stream.iterate(0,x->x<l,x->x+1): " + name,
+ () -> Stream.iterate(0, x -> x < ints.length, x -> x + 1).spliterator()));
// @@@ Add map and collection spliterators when spliterator() is exposed on Collection or Iterable
}
spliteratorTestData = spliterators.toArray(new Object[0][]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IterateTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8072727
+ */
+
+package org.openjdk.tests.java.util.stream;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.TestData;
+import java.util.stream.TestData.Factory;
+
+import static java.util.stream.ThowableHelper.checkNPE;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class IterateTest extends OpTestCase {
+
+ @DataProvider(name = "IterateStreamsData")
+ public static Object[][] makeIterateStreamsTestData() {
+ Object[][] data = {
+ {List.of(),
+ Factory.ofSupplier("ref.empty", () -> Stream.iterate(1, x -> x < 0, x -> x * 2))},
+ {List.of(1),
+ Factory.ofSupplier("ref.one", () -> Stream.iterate(1, x -> x < 2, x -> x * 2))},
+ {List.of(1, 2, 4, 8, 16, 32, 64, 128, 256, 512),
+ Factory.ofSupplier("ref.ten", () -> Stream.iterate(1, x -> x < 1000, x -> x * 2))},
+ {List.of(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0),
+ Factory.ofSupplier("ref.nullCheck", () -> Stream.iterate(10, Objects::nonNull, x -> x > 0 ? x - 1 : null))},
+ {List.of(),
+ Factory.ofIntSupplier("int.empty", () -> IntStream.iterate(1, x -> x < 0, x -> x + 1))},
+ {List.of(1),
+ Factory.ofIntSupplier("int.one", () -> IntStream.iterate(1, x -> x < 2, x -> x + 1))},
+ {List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
+ Factory.ofIntSupplier("int.ten", () -> IntStream.iterate(1, x -> x <= 10, x -> x + 1))},
+ {List.of(5, 4, 3, 2, 1),
+ Factory.ofIntSupplier("int.divZero", () -> IntStream.iterate(5, x -> x != 0, x -> x - 1/x/2 - 1))},
+ {List.of(),
+ Factory.ofLongSupplier("long.empty", () -> LongStream.iterate(1L, x -> x < 0, x -> x + 1))},
+ {List.of(1L),
+ Factory.ofLongSupplier("long.one", () -> LongStream.iterate(1L, x -> x < 2, x -> x + 1))},
+ {List.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L),
+ Factory.ofLongSupplier("long.ten", () -> LongStream.iterate(1L, x -> x <= 10, x -> x + 1))},
+ {List.of(),
+ Factory.ofDoubleSupplier("double.empty", () -> DoubleStream.iterate(1.0, x -> x < 0, x -> x + 1))},
+ {List.of(1.0),
+ Factory.ofDoubleSupplier("double.one", () -> DoubleStream.iterate(1.0, x -> x < 2, x -> x + 1))},
+ {List.of(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0),
+ Factory.ofDoubleSupplier("double.ten", () -> DoubleStream.iterate(1.0, x -> x <= 10, x -> x + 1))}
+ };
+ return data;
+ }
+
+ @Test(dataProvider = "IterateStreamsData")
+ public <T> void testIterate(List<T> expected, TestData<T, ?> data) {
+ withData(data).stream(s -> s).expectedResult(expected).exercise();
+ }
+
+ @Test
+ public void testNPE() {
+ checkNPE(() -> Stream.iterate("", null, x -> x + "a"));
+ checkNPE(() -> Stream.iterate("", String::isEmpty, null));
+ checkNPE(() -> IntStream.iterate(0, null, x -> x + 1));
+ checkNPE(() -> IntStream.iterate(0, x -> x < 10, null));
+ checkNPE(() -> LongStream.iterate(0, null, x -> x + 1));
+ checkNPE(() -> LongStream.iterate(0, x -> x < 10, null));
+ checkNPE(() -> DoubleStream.iterate(0, null, x -> x + 1));
+ checkNPE(() -> DoubleStream.iterate(0, x -> x < 10, null));
+ }
+}
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -24,7 +24,7 @@
/*
* @test
* @summary close handlers and closing streams
- * @bug 8044047
+ * @bug 8044047 8147505
*/
package org.openjdk.tests.java.util.stream;
@@ -37,6 +37,7 @@
import static java.util.stream.LambdaTestHelpers.countTo;
import static java.util.stream.ThowableHelper.checkNPE;
+import static java.util.stream.ThowableHelper.checkISE;
@Test(groups = { "serialization-hostile" })
public class StreamCloseTest extends OpTestCase {
@@ -170,4 +171,21 @@
for (int i=0; i<n-1; i++)
assertTrue(e.getSuppressed()[i].getMessage().equals(String.valueOf(i + 2)));
}
+
+ public void testConsumed() {
+ try(Stream<Integer> s = countTo(100).stream()) {
+ s.forEach(i -> {});
+ // Adding onClose handler when stream is consumed is illegal
+ // handler must not be registered
+ checkISE(() -> s.onClose(() -> fail("1")));
+ }
+
+ // close() must be idempotent:
+ // second close() invoked at the end of try-with-resources must have no effect
+ try(Stream<Integer> s = countTo(100).stream()) {
+ s.close();
+ // Adding onClose handler when stream is closed is also illegal
+ checkISE(() -> s.onClose(() -> fail("3")));
+ }
+ }
}
--- a/jdk/test/javax/management/mxbean/MXBeanLoadingTest1.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/javax/management/mxbean/MXBeanLoadingTest1.java Thu Mar 03 12:49:12 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -33,7 +33,6 @@
import java.lang.ref.WeakReference;
import java.net.URL;
-import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Map;
import javax.management.Attribute;
@@ -70,16 +69,16 @@
+ " some little extra check of Descriptors, MBean*Info.");
ClassLoader myClassLoader = MXBeanLoadingTest1.class.getClassLoader();
+ if(myClassLoader == null)
+ throw new RuntimeException("Test Failed : Null Classloader for test");
+ URL url = myClassLoader.getResource(
+ MXBeanLoadingTest1.class.getCanonicalName()
+ .replace(".", "/") + ".class");
+ String clsLoadPath = url.toURI().toString().
+ replaceAll(MXBeanLoadingTest1.class.getSimpleName()
+ + ".class", "");
- if (!(myClassLoader instanceof URLClassLoader)) {
- String message = "(ERROR) Test's class loader is not " +
- "a URLClassLoader";
- System.out.println(message);
- throw new RuntimeException(message);
- }
-
- URLClassLoader myURLClassLoader = (URLClassLoader) myClassLoader;
- URL[] urls = myURLClassLoader.getURLs();
+ URL[] urls = new URL[]{new URL(clsLoadPath)};
PrivateMLet mlet = new PrivateMLet(urls, null, false);
Class<?> shadowClass = mlet.loadClass(TestMXBean.class.getName());
--- a/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java Thu Mar 03 12:25:57 2016 -0800
+++ b/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java Thu Mar 03 12:49:12 2016 -0800
@@ -44,7 +44,7 @@
import org.testng.annotations.*;
public class MultiReleaseJarTest {
- final private int MAJOR_VERSION= Version.current().major();
+ final private int MAJOR_VERSION = Version.current().major();
final private String userdir = System.getProperty("user.dir",".");
final private Map<String,String> stringEnv = new HashMap<>();
--- a/jdk/test/sun/misc/Version/Version.java Thu Mar 03 12:25:57 2016 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2010, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 6994413 8134365
- * @summary Check the JDK and JVM version returned by sun.misc.Version
- * matches the versions defined in the system properties.
- * Should use the API described in JDK-8136651 when available
- * @modules java.base/sun.misc
- * @compile -XDignore.symbol.file Version.java
- * @run main Version
- */
-
-import static sun.misc.Version.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class Version {
-
- public static void main(String[] args) throws Exception {
- VersionInfo jdk = newVersionInfo(System.getProperty("java.runtime.version"));
- VersionInfo v1 = new VersionInfo(jdkMajorVersion(),
- jdkMinorVersion(),
- jdkSecurityVersion(),
- jdkPatchVersion(),
- jdkBuildNumber());
- System.out.println("JDK version = " + jdk + " " + v1);
- if (!jdk.equals(v1)) {
- throw new RuntimeException("Unmatched version: " + jdk + " vs " + v1);
- }
- VersionInfo jvm = newVersionInfo(System.getProperty("java.vm.version"));
- VersionInfo v2 = new VersionInfo(jvmMajorVersion(),
- jvmMinorVersion(),
- jvmSecurityVersion(),
- jvmPatchVersion(),
- jvmBuildNumber());
- System.out.println("JVM version = " + jvm + " " + v2);
- if (!jvm.equals(v2)) {
- throw new RuntimeException("Unmatched version: " + jvm + " vs " + v2);
- }
- }
-
- static class VersionInfo {
- final int major;
- final int minor;
- final int security;
- final int patch;
- final int build;
- VersionInfo(int major, int minor, int security,
- int patch, int build) {
- this.major = major;
- this.minor = minor;
- this.security = security;
- this.patch = patch;
- this.build = build;
- }
-
- VersionInfo(int[] fields) {
- this.major = fields[0];
- this.minor = fields[1];
- this.security = fields[2];
- this.patch = fields[3];
- this.build = fields[4];
- }
-
- public boolean equals(VersionInfo v) {
- return (this.major == v.major && this.minor == v.minor &&
- this.security == v.security && this.patch == v.patch &&
- this.build == v.build);
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- // Do not include trailing zeros
- if (patch > 0) {
- sb.insert(0, "." + patch);
- }
- if (security > 0 || sb.length() > 0) {
- sb.insert(0, "." + security);
- }
- if (minor > 0 || sb.length() > 0) {
- sb.insert(0, "." + minor);
- }
- sb.insert(0, major);
-
- if (build >= 0)
- sb.append("+" + build);
-
- return sb.toString();
- }
- }
-
- private static VersionInfo newVersionInfo(String version) throws Exception {
- // Version string fromat as defined by JEP-223
- String jep223Pattern =
- "^([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?(\\.([0-9]+))?" + // $VNUM
- "(-([a-zA-Z]+))?(\\.([a-zA-Z]+))?" + // $PRE
- "(\\+([0-9]+))?" + // Build Number
- "(([-a-zA-Z0-9.]+))?$"; // $OPT
-
- // Pattern group index for: Major, Minor, Security, Patch, Build
- int[] groups = {1, 3, 5, 7, 13};
- // Default values for Major, Minor, Security, Patch, Build
- int[] versionFields = {0, 0, 0, 0, 0};
-
- Pattern pattern = Pattern.compile(jep223Pattern);
- Matcher matcher = pattern.matcher(version);
- if (matcher.matches()) {
- for (int i = 0; i < versionFields.length; i++) {
- String field = matcher.group(groups[i]);
- versionFields[i] = (field != null) ? Integer.parseInt(field) : 0;
- }
- }
-
- VersionInfo vi = new VersionInfo(versionFields);
- System.out.printf("newVersionInfo: input=%s output=%s\n", version, vi);
- return vi;
- }
-}