diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk
index 84923075122..453a4b0c00c 100644
--- a/make/test/JtregNativeHotspot.gmk
+++ b/make/test/JtregNativeHotspot.gmk
@@ -109,6 +109,13 @@ NSK_GC_LOCK_REF_INCLUDES := \
-I$(VM_TESTBASE_DIR)/nsk/share/native \
-I$(VM_TESTBASE_DIR)/nsk/share/jni
+NSK_STRACE_INCLUDES := \
+ -I$(VM_TESTBASE_DIR)/nsk/share/native \
+ -I$(VM_TESTBASE_DIR)/nsk/share/jni
+
+NSK_STRESS_JNI_INCLUDES := \
+ -I$(VM_TESTBASE_DIR)/nsk/stress/jni
+
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libProcessUtils := $(VM_SHARE_INCLUDES)
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libThreadController := $(NSK_MONITORING_INCLUDES)
@@ -150,6 +157,20 @@ BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libJNILocalRefLocker := $(NSK_GC_LOCK_REF_I
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libJNIRefLocker := $(NSK_GC_LOCK_REF_INCLUDES)
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libJNIWeakGlobalRefLocker := $(NSK_GC_LOCK_REF_INCLUDES)
+
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace003 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace004 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace005 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace006 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace008 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace009 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace011 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace012 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace014 := $(NSK_STRACE_INCLUDES)
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstrace015 := $(NSK_STRACE_INCLUDES)
+
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libgcl001 := $(NSK_STRESS_JNI_INCLUDES)
+
################################################################################
# Platform specific setup
diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups
index 8c41cc3bdea..a881f879bc4 100644
--- a/test/hotspot/jtreg/TEST.groups
+++ b/test/hotspot/jtreg/TEST.groups
@@ -1157,6 +1157,9 @@ vmTestbase_nsk_jdi_quick = \
vmTestbase/nsk/jdi/StackFrame/getArgumentValues/getArgumentValues002/getArgumentValues002.java \
vmTestbase/nsk/jdi/StackFrame/getArgumentValues/getArgumentValues003/getArgumentValues003.java
+vmTestbase_nsk_stress = \
+ vmTestbase/nsk/stress
+
vmTestbase_vm_g1classunloading = \
vmTestbase/gc/g1/unloading/tests
@@ -1264,4 +1267,3 @@ vmTestbase_vm_heapdump_quick = \
vmTestbase/heapdump/OnOOMToPath/TestDescription.java \
vmTestbase/heapdump/JMapHeapCore/TestDescription.java \
vmTestbase/heapdump/JMapMetaspace/TestDescription.java
-
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/TEST.properties
new file mode 100644
index 00000000000..8b51b2a9115
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/TEST.properties
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except001.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except001.java
new file mode 100644
index 00000000000..066123c4eb0
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except001.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except001.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if OutOfMemoryError exception is correctly enwrapped into
+ * InvocationTargetException when thrown inside a method invoked via
+ * reflection.
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new Object() instances. Instances of the "empty"
+ * type Object are the smallest objects, so they apparently should occupy
+ * most fine-grained fragments in the heap. Thus, there apparently should
+ * not remain any free space to incarnate new Throwable instance, and VM
+ * possibly could crash while trying to throw new OutOfMemoryError and
+ * enwrap it into new InvocationTargetException instance.
+ * By the way, the test checks time elapsed to allocate memory. Both
+ * classic VM and HotSpot seem to fall into poor performance of memory
+ * allocation when heap is almost over. E.g.: HotSpot 1.3-betaH may spend
+ * more than 1 minute to allocate next Object in this case (tested on
+ * Pentium-II, 350MHz, 128Mb RAM). To avoid this problem, the test enforce
+ * OutOfMemoryError if more then 5 minutes is spent to allocate "last bytes"
+ * of memory.
+ * COMMENTS
+ * HotSpot releases 1.0-fcsE (both Win32 and Sparc), and 1.3-betaH (Win32)
+ * fail on this test due to poor performance of memory allocation.
+ * #4248801 (P3/S5) slow memory allocation when heap is almost exhausted
+ * Despite this bug is treated fixed in HotSpot 1.0.1, it still does suffer
+ * slow memory allocation when running on PC having 64Mb or less of RAM.
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace may fail under JDK 1.2 for Win32 even so.
+ * HotSpot 2.0-devA (Win32) crashes due to the known HotSpot bug:
+ * #4239828 (P1/S4) 1.3c1: VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except001
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * This checks if OutOfMemoryError exception is correctly
+ * enwrapped into InvocationTargetException when thrown inside
+ * a method invoked via reflection.
+ *
+ *
The test tries to occupy all of memory available in the heap by
+ * allocating lots of new Object() instances. Instances of the
+ * ``empty'' type Object are the smallest objects, so they
+ * apparently should occupy most fine-grained fragments in the heap.
+ * Thus, there apparently should not remain any free space to incarnate new
+ * Throwable instance, and VM possibly could crash while trying
+ * to throw new OutOfMemoryError and enwrap it into new
+ * InvocationTargetException instance.
+ *
+ *
By the way, the test checks time elapsed to allocate memory.
+ * Both classic VM and HotSpot seem to fall into poor performance of memory
+ * allocation when heap is almost over. E.g.: HotSpot 1.3-betaH may spend
+ * more than 1 minute to allocate next Object in this case
+ * (tested on Pentium-II, 350MHz, 128Mb RAM). To workaround this problem,
+ * the test enforces OutOfMemoryError if more then 5 minutes
+ * is spent to allocate ``last bytes'' of the memory.
+ */
+public class except001 {
+ /**
+ * This field allows or supresses printing with display()
+ * method.
+ *
+ * @see #display(Object)
+ * @see #complain(Object)
+ * @see #out
+ */
+ private static boolean MODE_VERBOSE = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+
+ /**
+ * Print execution trace if MODE_VERBOSE is true
+ * (optional).
+ *
+ * @see #MODE_VERBOSE
+ * @see #complain(Object)
+ * @see #out
+ */
+ private static void display(Object message) {
+ if (MODE_VERBOSE)
+ out.println(message.toString());
+ out.flush();
+ }
+
+ /**
+ * Print error message.
+ *
+ * @see #display(Object)
+ * @see #out
+ */
+ private static void complain(Object message) {
+ out.println("# " + message);
+ out.flush();
+ }
+
+ /**
+ * The log-stream assigned at runtime by the method
+ * run(args,out).
+ *
+ * @see #display(Object)
+ * @see #complain(Object)
+ * @see #run(String[], PrintStream)
+ */
+ private static PrintStream out;
+
+ /**
+ * Try to allocate lots of instances of the type Object.
+ * Such instances are most fine-grained, and thus they should occupy
+ * smallest fragments of free memory in the heap.
+ *
+ *
By the way, break the test, if JVM has spent more than
+ * 5 minutes to allocate latest portions of memory.
+ */
+ public static void raiseOutOfMemory() throws OutOfMemoryError {
+ try {
+ // Repository for objects, which should be allocated:
+ int index = 0;
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+
+ for (; index < pool.length; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ display(
+ "pool[" + index +
+ "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 300) {
+ complain(
+ "Memory allocation became slow: so heap seems exhausted.");
+ throw new OutOfMemoryError();
+ }
+ }
+ }
+
+ // This method should never return:
+ throw new Error("TEST_BUG: failed to provoke OutOfMemoryError");
+ } finally {
+ // Make sure there will be enough memory for next object allocation
+ pool = null;
+ }
+ }
+
+ /**
+ * Invoke the method raiseOutOfMemory() with reflection,
+ * and check if the exception it throws is just
+ * OutOfMemoryError enwrapped into
+ * InvocationTargetException instance.
+ *
+ *
Before the test begins, this.out filed is assigned
+ * to the parameter out. Parameter args[]
+ * is ignored.
+ *
+ * @see #raiseOutOfMemory()
+ */
+ public static int run(String args[], PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so.");
+
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ MODE_VERBOSE = true;
+ }
+
+ except001.out = out;
+ Class testClass = except001.class;
+ try {
+ Method testMethod = testClass.getMethod("raiseOutOfMemory", new Class [0]);
+ Object junk = testMethod.invoke(null, new Object [0]);
+
+ } catch (InvocationTargetException ite) {
+ Throwable targetException = ite.getTargetException();
+ if (targetException instanceof OutOfMemoryError) {
+ display("OutOfMemoryError thrown as expected.");
+ display("Test passed.");
+ return 0;
+ }
+ complain("Unexpected InvocationTargetException: " + targetException);
+ complain("Test failed.");
+ return 2;
+
+ } catch (Exception exception) {
+ complain("Unexpected exception: " + exception);
+ complain("Test failed.");
+ return 2;
+ }
+ //
+ complain("The test has finished unexpectedly.");
+ complain("Test failed.");
+ return 2;
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exception outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(95);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except002.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except002.java
new file mode 100644
index 00000000000..c8aca536883
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except002.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except002.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except002
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ *
+ *
The test tries to occupy all of memory available in the heap by
+ * allocating lots of new Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ *
Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ *
There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ *
+ *
Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except002 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ public static volatile Object pool[] = null;
+ /**
+ * Temporary log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will return the");
+ out.println("# exit status 96 instead of 97 to indicate the problem.");
+
+ // Prepare some items, which will be used by the test:
+ Object trash = null;
+
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+ int index = 0;
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+
+ // Do not release any byte once allocated:
+ pool[index++] = oome;
+ }
+
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Check ClassNotFoundException (positive):
+ try {
+ trash = Class.forName("nsk.stress.except.except002.except002$Abra$Cadabra"); // correct - should pass
+// trash = Class.forName("nsk.stress.except.except002.except002.Abra.Cadabra"); // incorrect - should fail
+ if (TRACE_ON)
+ log[messages++] = "Success: ClassNotFoundException (positive)";
+ } catch (ClassNotFoundException cnfe) {
+ log[messages++] = "Failure: ClassNotFoundException (positive)";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: ClassNotFoundException (positive)";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exception outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+ /**
+ * This class should be used to check ClassNotFoundException
+ * and IllegalAccessException.
+ */
+ private static class Abra {
+ /**
+ * Will try to incorrectly find this class as Cadabra
+ * instead of Abra$Cadabra.
+ */
+ public static class Cadabra {
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except003.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except003.java
new file mode 100644
index 00000000000..6486857123a
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except003.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except003.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except003
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ *
+ *
The test tries to occupy all of memory available in the heap by
+ * allocating lots of new Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ *
Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ *
There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ *
+ *
Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except003 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * Temporary log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will return the");
+ out.println("# exit status 96 instead of 97 to indicate the problem.");
+
+ // Prepare some items, which will be used by the test:
+ Object trash = null;
+
+ // Allocate repository for a lots of tiny objects:
+ pool = null;
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+ int index = 0;
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+
+ // Do not release any byte once allocated:
+ pool[index++] = oome;
+ }
+
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Check ClassNotFoundException (negative):
+ try {
+// trash = Class.forName("nsk.stress.except.except003.except003$Abra$Cadabra"); // correct - should pass
+ trash = Class.forName("nsk.stress.except.except003.except003.Abra.Cadabra"); // incorrect - should fail
+ log[messages++] = "Failure: ClassNotFoundException (negative)";
+ exitCode = 2;
+ } catch (ClassNotFoundException cnfe) {
+ if (TRACE_ON)
+ log[messages++] = "Success: ClassNotFoundException (negative)";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: ClassNotFoundException (negative)";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exception outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(95);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+ /**
+ * This class should be used to check ClassNotFoundException
+ * and IllegalAccessException.
+ */
+ private static class Abra {
+ /**
+ * Will try to incorrectly find this class as Cadabra
+ * instead of Abra$Cadabra.
+ */
+ public static class Cadabra {
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except004.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except004.java
new file mode 100644
index 00000000000..4753236d27d
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except004.java
@@ -0,0 +1,553 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except004.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M -XX:-UseGCOverheadLimit nsk.stress.except.except004
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ *
+ *
The test tries to occupy all of memory available in the heap by
+ * allocating lots of new Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ *
Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ *
There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ *
+ *
Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except004 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * Temporary
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new
+ * Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except005 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+
+ /**
+ * Temporary
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new
+ * Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except006 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * Temporary
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new
+ * Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except007 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * Temporary
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new
+ * Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except008 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * Temporary
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new
+ * Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except009 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * Temporary
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new
+ * Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except010 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * Temporary
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new
+ * Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except011 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * Temporary
+ * The test tries to occupy all of memory available in the heap by
+ * allocating lots of new
+ * Note, that memory occupation is terminated if memory allocation slows
+ * down crucially. This is a workaround intended to avoid the HotSpot bug:
+ *
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ *
+ * Also note, that the test needs a lot of memory to start up, so it should
+ * not run under older JDK 1.1.x release due to its poor heap utilization.
+ */
+public class except012 {
+ /**
+ * Either allow or supress printing of execution trace.
+ */
+ private static boolean TRACE_ON = false;
+ /**
+ * Either allow or supress printing of warning messages.
+ */
+ private static final boolean WARN_ON = true;
+
+ /**
+ * Temporary
+ * Information transfer is synchronized in this test. Client passes
+ * a large data parcel to server, and server reads that parcel and checks
+ * if it is same as expected (byte-to-byte equality). Then server passes
+ * (some other) parcel to client, and client reads and verifies those bytes.
+ * This ping-pong game is repeated 2000 times; and after that both sockets
+ * check if there are no extra bytes accudentally passed through their
+ * connection.
+ *
+ * Parcels lengths and contents are chosen randomly, and average parcel
+ * length is 125 bytes. So totally, each of the 2 sockets passes ~250Kb of
+ * data to its partner, and thus ~500Kb of data are transfered by this test.
+ */
+public class network001 {
+ /**
+ * Number of parcels to be sent/recieve.
+ */
+ private static final int DATA_PARCELS = 2000;
+
+ /**
+ * Maximal length of data parcel to be sent/recieved
+ * (now it equals to 250 bytes).
+ */
+ private static final int MAX_PARCEL = 250;
+
+ /**
+ * Either actually display optional reports or not.
+ */
+ static private final boolean DEBUG_MODE = false;
+
+ /**
+ * Errors and optional reports log. Usually
+ * Command-line parameters provided with
+ * Information transfer is synchronized in this test. Client VM passes
+ * a large data parcel to server VM, and server reads that parcel and checks
+ * if it is same as expected (byte-to-byte equality). Then server passes
+ * (some other) parcel to client, and client reads and verifies those data.
+ * This ping-pong game is repeated 2000 times; and after that both VMs check
+ * if there are no extra bytes accudentally passed through their connection.
+ *
+ * Parcels lengths and contents are chosen randomly, and average parcel
+ * length is 125 bytes. So totally, each of the 2 VMs passes ~250Kb of data
+ * to its partner, and thus ~500Kb of data are transfered by this test.
+ */
+public class network002 {
+ /**
+ * Timeout for TCP/IP sockets (currently set to 1 min).
+ */
+ private static int SO_TIMEOUT;
+
+ /**
+ * Number of parcels to be sent/recieved.
+ */
+ private static final int DATA_PARCELS = 2000;
+
+ /**
+ * Maximal length of data parcel to be sent/recieved.
+ */
+ private static final int MAX_PARCEL = 250;
+
+ /**
+ * Either actually display optional reports or not.
+ */
+ static private final boolean DEBUG_MODE = false;
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Re-calls to the method
+ * There should be 1 or 2 command-line parameters:
+ *
+ * Usually,
+ * If optional parameter is ommited, the test invokes the method
+ *
+ * In this test, 128 client/server connections are established. Once a
+ * connection is established, client passes a large data parcel to server,
+ * and server reads that parcel and checks if it is same as expected
+ * (byte-to-byte equality is desired). Then server passes (some other) parcel
+ * to the client, and client reads and verifies those bytes. This ping-pong
+ * game is repeated 128 times; and after that each pair of sockets checks if
+ * there are no extra bytes accudentally passed through their connection.
+ *
+ * Parcels lengths and contents are chosen randomly, and average parcel
+ * length is 128 bytes. So totally, each pair of sockets passes ~16Kb of
+ * data to each other, and thus ~32Kb of data are transfered by each sockets
+ * pair. Totally, ~4Mb of data are transfered by all client/server pairs.
+ */
+public class network003 {
+ /**
+ * Do actually display optional reports?
+ */
+ static private final boolean DEBUG_MODE = false;
+
+ /**
+ * Errors and optional reports log. Usually
+ * Command-line parameters provided with
+ * In this test, 128 client/server connections are established. Once a
+ * connection is established, client passes a large data parcel to server,
+ * and server reads that parcel and checks if it is same as expected
+ * (byte-to-byte equality is desired). Then server passes (some other) parcel
+ * to the client, and client reads and verifies those bytes. This ping-pong
+ * game is repeated 128 times; and after that each pair of sockets checks if
+ * there are no extra bytes accudentally passed through their connection.
+ *
+ * Parcels lengths and contents are chosen randomly, and average
+ * parcel length is 128 bytes. So totally, each pair of sockets passes ~16Kb of
+ * data to each other, and thus ~32Kb of data are transfered by each sockets
+ * pair. Totally, ~4Mb of data are transfered by all client/server pairs.
+ */
+public class network004 {
+ /**
+ * Timeout for TCP/IP sockets (currently set to 1 min).
+ */
+ private static int SO_TIMEOUT;// = 2*60*1000;
+
+ /**
+ * Maximal number of connections this test should open simultaneously.
+ */
+ private final static int MAX_CONNECTIONS = 128;
+
+ /**
+ * Check few more connections to make sure that MAX_CONNECTIONS are safe.
+ */
+ private final static int CONNECTIONS_RESERVE = 10;
+
+ /**
+ * Number of parcels to be sent/recieved.
+ */
+ private final static int DATA_PARCELS = 128;
+
+ /**
+ * Maximal length of data parcel to be sent/recieved
+ * (it equals to 256 bytes now).
+ */
+ private final static int MAX_PARCEL = 1 << 8;
+
+ /**
+ * Either actually display optional reports or not.
+ */
+ static private final boolean DEBUG_MODE = false;
+
+ /**
+ * How many IP sockets can we open simultaneously?
+ * Check if
+ * There should be 1 or 2 command-line parameters:
+ *
+ * Usually,
+ * If optional parameter is ommited, the test invokes the method
+ *
+ * In this test, 128 client/server connections are established. Once a
+ * connection is established, client passes a large data parcel to server,
+ * and server reads that parcel and checks if it is same as expected
+ * (byte-to-byte equality is desired). Then server passes (some other) parcel
+ * to the client, and client reads and verifies those bytes. This ping-pong
+ * game is repeated 128 times; and after that each pair of sockets checks if
+ * there are no extra bytes accudentally passed through their connection.
+ *
+ * Parcels lengths and contents are chosen randomly, and average parcel
+ * length is 128 bytes. So totally, each pair of sockets passes ~16Kb of
+ * data to each other, and thus ~32Kb of data are transfered by each sockets
+ * pair. Totally, ~4Mb of data are transfered by all client/server pairs.
+ */
+public class network005 {
+ /**
+ * Do actually display optional reports?
+ */
+ static private final boolean DEBUG_MODE = false;
+
+ /**
+ * Errors and optional reports log. Usually
+ * Command-line parameters provided with
+ * In this test, 128 client/server connections are established. Once a
+ * connection is established, client passes a data parcel to server, and server
+ * reads that parcel and checks if it is same as expected (byte-to-byte equality
+ * is desired). Then server passes (some other) parcel to the client, and client
+ * reads and verifies those bytes. This ping-pong game is repeated 128 times; and
+ * after that each pair of sockets checks if there are no extra bytes accudentally
+ * passed through their connection.
+ *
+ * Parcels lengths and contents are chosen randomly, and average parcel length
+ * is 128 bytes. So totally, each pair of sockets passes ~16Kb of data to each other,
+ * and thus ~32Kb of data are transfered by each sockets pair. Totally, ~4Mb of data
+ * are transfered by all client/server pairs.
+ */
+public class network006 {
+ /**
+ * Timeout for TCP/IP sockets (currently set to 1 min).
+ */
+ private static int SO_TIMEOUT;// = 2*60*1000;
+
+ /**
+ * Maximal number of connections this test should open simultaneously.
+ */
+ private final static int MAX_CONNECTIONS = 128;
+
+ /**
+ * Check few more connections to make sure that MAX_CONNECTIONS are safe.
+ */
+ private final static int CONNECTIONS_RESERVE = 10;
+
+ /**
+ * The test used to fail with connection reset by peer set to 50.
+ * (and once in a three if it was set to 10).
+ * So now we set it to MAX_CONNECTIONS (128).
+ */
+ private final static int BACKLOG_QUEUE_LENGTH = MAX_CONNECTIONS;
+
+ /**
+ * Number of parcels to be sent/recieved.
+ */
+ private final static int DATA_PARCELS = 128;
+
+ /**
+ * Maximal length of data parcel to be sent/recieved
+ * (it equals to 256 bytes now).
+ */
+ private final static int MAX_PARCEL = 1 << 8;
+
+ /**
+ * Either actually display optional reports or not.
+ */
+ static private final boolean DEBUG_MODE = false;
+
+ /**
+ * How many IP sockets can we open simultaneously?
+ * Check if
+ * There should be 2 or 3 command-line parameters:
+ *
+ * Usually,
+ * If optional parameter is ommited, the test invokes the method
+ *
+ * That product A.A is calculated twice: in
+ * a single thread, and in N separate threads, where NxN
+ * is the size of square matrix A. When executing in N threads,
+ * each thread calculate distinct row of the resulting matrix. The test checks
+ * if the resulting product A.A is the same when
+ * calculated in single thread and in N threads.
+ *
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs
+ * installed on the platform executing the test is taken into account for
+ * performance testing). Note, that HotSpot may fail to adjust itself for
+ * better performance in single-thread calculation.
+ *
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * That product A.A is calculated twice: in
+ * a single thread, and in N separate threads, where NxN
+ * is the size of square matrix A. When executing in N threads,
+ * each thread calculate distinct row of the resulting matrix. The test checks
+ * if the resulting product A.A is the same when
+ * calculated in single thread and in N threads.
+ *
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs
+ * installed on the platform executing the test is taken into account for
+ * performance testing). Note, that HotSpot may fail to adjust itself for
+ * better performance in single-thread calculation.
+ *
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * That product A.A is calculated twice: in
+ * a single thread, and in N separate threads, where NxN
+ * is the size of square matrix A. When executing in N threads,
+ * each thread calculate distinct row of the resulting matrix. The test checks
+ * if the resulting product A.A is the same when
+ * calculated in single thread and in N threads.
+ *
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs
+ * installed on the platform executing the test is taken into account for
+ * performance testing). Note, that HotSpot may fail to adjust itself for
+ * better performance in single-thread calculation.
+ *
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * That product A.A is calculated twice: in
+ * a single thread, and in N separate threads, where NxN
+ * is the size of square matrix A. When executing in N threads,
+ * each thread calculate distinct row of the resulting matrix. The test checks
+ * if the resulting product A.A is the same when
+ * calculated in single thread and in N threads.
+ *
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs
+ * installed on the platform executing the test is taken into account for
+ * performance testing). Note, that HotSpot may fail to adjust itself for
+ * better performance in single-thread calculation.
+ *
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * Calculation of the product
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower
+ * than the 3rd iteration. The calculations algorithm is encoded
+ * as compact ``canonical'' 3-levels cycle like:
+ *
+ * In this test,
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * Calculation of the product
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower
+ * than the 3rd iteration. The calculations algorithm is encoded
+ * as compact ``canonical'' 3-levels cycle like:
+ *
+ * In this test,
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * Calculation of the product
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower
+ * than the 3rd iteration. The calculations algorithm is encoded
+ * as compact ``canonical'' 3-levels cycle like:
+ *
+ * In this test,
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * Calculation of the product
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower
+ * than the 3rd iteration. The calculations algorithm is encoded
+ * as compact ``canonical'' 3-levels cycle like:
+ *
+ * In this test,
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * Calculation of the product
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower
+ * than the 2nd iteration. The calculations algorithm is encoded
+ * as compact ``canonical'' 3-levels cycle like:
+ *
+ * In this test,
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * The product
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than
+ * In this test,
+ * See the bug-report:
+ *
+ * Command-line parameters are:
+ *
+ * Here:
+ *
+ * The test creates These checking are performed
+ * The test creates These checking are performed
+ * The test creates These checking are performed
+ * The test creates These checking are performed
+ * The test creates These checking are performed The test creates These checking are performed
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the
+ * It is expected that these methods return the same stack traces. Each stack frame
+ * for both stack traces must be corresponded to invocation of one of the methods
+ * defined by the log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode;
+ try {
+ exitCode = run(out);
+ } finally { // ensure we have free memory for exception processing
+ pool = null;
+ System.gc();
+ }
+ if (TRACE_ON)
+ out.println("Test completed.");
+
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could cause OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will return the");
+ out.println("# exit status 96 instead of 97 to indicate the problem.");
+
+ // run all tests normally to ensure all needed classes are loaded and
+ // initialized before the heap is exhausted - else we may trigger OOME
+ // in unexpected places.
+ try {
+ if (TRACE_ON)
+ out.println("Running without heap exhaustion");
+ runTests(out, false);
+ } catch (Throwable unexpected) {
+ out.println("Test pre-initialisation failed: " + unexpected);
+ return 2;
+ }
+
+ if (TRACE_ON)
+ out.println("Running with heap exhaustion");
+
+ return runTests(out, true);
+ }
+
+ private static int runTests(PrintStream out, boolean exhaustHeap) {
+ // reset message index
+ messages = 0;
+
+ // Prepare some items, which will be used by the test:
+ Object stringArray[] = new String[1];
+ Object integerValue = new Integer(0);
+ Object doubleValue = new Double(0);
+ Object trash = null;
+ Field abraPrivateField;
+ Field abraIntegerField;
+ Field abraBooleanField;
+ try {
+ abraPrivateField = Abra.class.getDeclaredField("DONT_TOUCH_ME");
+ abraIntegerField = Abra.class.getDeclaredField("MAIN_CYR_NUMBER");
+ abraBooleanField = Abra.class.getDeclaredField("NOT_AN_INTEGER");
+ } catch (NoSuchFieldException nsfe) {
+ out.println("Test initialisation failed: field not found in class Abra");
+ return 2;
+ }
+
+ Abra abra = new Abra("via public constructor");
+ Abra.Cadabra cadabra = new Abra.Cadabra();
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+
+ int poolSize = 0;
+ int index = 0;
+
+ if (exhaustHeap) {
+ pool = null;
+ // Allocate repository for lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1) {
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ poolSize = pool.length;
+ index = 0;
+
+ // Sum up time spent, when it was hard for JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ // Do not release any byte once allocated:
+ pool[index++] = oome;
+ }
+
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+ } else {
+ // pool gets used for array index tests
+ pool = new Object[3];
+ poolSize = pool.length;
+ }
+
+ // Check ArithmeticException:
+ try {
+ int x, y, z;
+ x = y = 0;
+ z = x / y;
+ log[messages++] = "Failure: ArithmeticException";
+ exitCode = 2; // FAILED
+ } catch (ArithmeticException ae) {
+ if (TRACE_ON)
+ log[messages++] = "Success: ArithmeticException";
+ if (exhaustHeap)
+ pool[index++] = ae;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: ArithmeticException";
+ skipped++;
+ }
+
+ // Check ArrayIndexOutOfBoundsException:
+ try {
+ pool[poolSize] = pool[0];
+ log[messages++] = "Failure: ArrayIndexOutOfBoundsException";
+ exitCode = 2; // FAILED
+ } catch (ArrayIndexOutOfBoundsException aioobe) {
+ if (TRACE_ON)
+ log[messages++] = "Success: ArrayIndexOutOfBoundsException";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: ArrayIndexOutOfBoundsException";
+ skipped++;
+ }
+
+ // Check ArrayStoreException:
+ try {
+ stringArray[0] = integerValue;
+ log[messages++] = "Failure: ArrayStoreException";
+ exitCode = 2; // FAILED
+ } catch (ArrayStoreException ase) {
+ if (TRACE_ON)
+ log[messages++] = "Success: ArrayStoreException";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: ArrayStoreException";
+ skipped++;
+ }
+
+ // Check ClassCastException:
+ try {
+ trash = (Double) integerValue;
+ log[messages++] = "Failure: ClassCastException";
+ exitCode = 2; // FAILED
+ } catch (ClassCastException cce) {
+ if (TRACE_ON)
+ log[messages++] = "Success: ClassCastException";
+ if (exhaustHeap)
+ pool[index++] = cce;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: ClassCastException";
+ skipped++;
+ }
+
+ // Check CloneNotSupportedException:
+ try {
+ trash = abra.clone(); // illegal - should fail
+// trash = cadabra.clone(); // legal - should pass
+ log[messages++] = "Failure: CloneNotSupportedException";
+ exitCode = 2; // FAILED
+ } catch (CloneNotSupportedException cnse) {
+ if (TRACE_ON)
+ log[messages++] = "Success: CloneNotSupportedException";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: CloneNotSupportedException";
+ skipped++;
+ }
+
+ // Check IllegalAccessException (positive):
+ try {
+ int junkIt = abraIntegerField.getInt(null); // legal - should pass
+// int junkIt = abraPrivateField.getInt(null); // illegal - should fail
+ if (TRACE_ON)
+ log[messages++] = "Success: IllegalAccessException (positive)";
+ } catch (IllegalAccessException iae) {
+ log[messages++] = "Failure: IllegalAccessException (positive)";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: IllegalAccessException (positive)";
+ skipped++;
+ }
+
+ // Check IllegalAccessException (negative):
+ try {
+// int junkIt = abraIntegerField.getInt(null); // legal - should pass
+ int junkIt = abraPrivateField.getInt(null); // illegal - should fail
+ log[messages++] = "Failure: IllegalAccessException (negative)";
+ exitCode = 2; // FAILED
+ } catch (IllegalAccessException iae) {
+ if (TRACE_ON)
+ log[messages++] = "Success: IllegalAccessException (negative)";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: IllegalAccessException (negative)";
+ skipped++;
+ }
+
+ // Check IllegalArgumentException (positive):
+ try {
+ int junkIt = abraIntegerField.getInt(null); // legal - should pass
+// int junkIt = abraBooleanField.getInt(null); // illegal - should fail
+ if (TRACE_ON)
+ log[messages++] = "Success: IllegalArgumentException (positive)";
+ } catch (IllegalAccessException iae) {
+ log[messages++] =
+ "Failure: IllegalArgumentException (positive) incorrectly thrown IllegalAccessException";
+ exitCode = 2;
+ } catch (IllegalArgumentException iae) {
+ log[messages++] = "Failure: IllegalArgumentException (positive)";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: IllegalArgumentException (positive)";
+ skipped++;
+ }
+
+ // Check IllegalArgumentException (negative):
+ try {
+// int junkIt = abraIntegerField.getInt(null); // legal - should pass
+ int junkIt = abraBooleanField.getInt(null); // illegal - should fail
+ log[messages++] = "Failure: IllegalArgumentException (negative)";
+ exitCode = 2; // FAILED
+ } catch (IllegalAccessException iae) {
+ log[messages++] =
+ "Failure: IllegalArgumentException (negative) incorrectly thrown IllegalAccessException";
+ exitCode = 2;
+ } catch (IllegalArgumentException iae) {
+ if (TRACE_ON)
+ log[messages++] = "Success: IllegalArgumentException (negative)";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: IllegalArgumentException (negative)";
+ skipped++;
+ }
+
+ // Check IllegalMonitorStateException (positive):
+ try {
+ synchronized (cadabra) {
+ cadabra.notifyAll(); // legal - should pass
+ }
+// cadabra.notifyAll(); // illegal - should fail
+ if (TRACE_ON)
+ log[messages++] = "Success: IllegalMonitorStateException (positive)";
+ } catch (IllegalMonitorStateException imse) {
+ log[messages++] = "Failure: IllegalMonitorStateException (positive)";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: IllegalMonitorStateException (positive)";
+ skipped++;
+ }
+
+ // Check IllegalMonitorStateException (negative):
+ try {
+// synchronized (cadabra) {
+// cadabra.notifyAll(); // legal - should pass
+// }
+ cadabra.notifyAll(); // illegal - should fail
+ log[messages++] = "Failure: IllegalMonitorStateException (negative)";
+ exitCode = 2;
+ } catch (IllegalMonitorStateException imse) {
+ if (TRACE_ON)
+ log[messages++] = "Success: IllegalMonitorStateException (negative)";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: IllegalMonitorStateException (negative)";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exception outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ else if (e instanceof Error)
+ throw (Error) e;
+ else
+ throw new Error("Unexpected checked exception", e);
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+ /**
+ * This class should be used to check CloneNotSupportedException,
+ * IllegalAccessException, and IllegalArgumentException.
+ * The class extends except004 in order that its (protected)
+ * method clone() be available from except004.
+ */
+ private static class Abra extends except004 {
+ /**
+ * Will try to incorrectly find this class as Cadabra
+ * instead of Abra$Cadabra.
+ */
+ public static class Cadabra implements Cloneable {
+ }
+
+ /**
+ * Will try to incorrectly access to this field from outside this class.
+ */
+ private static final int DONT_TOUCH_ME = 666;
+ /**
+ * Will try to incorrectly access to this field from outside this class.
+ */
+ public static final int MAIN_CYR_NUMBER = 47;
+ /**
+ * Will try to get this field like int zero.
+ */
+ public static final boolean NOT_AN_INTEGER = false;
+
+ /**
+ * Will try to correctly instantiate Abra.Cadabra,
+ * not Abra.
+ */
+ private Abra() {
+ }
+
+ /**
+ * Yet another constructor, which is public.
+ */
+ public Abra(String nothingSpecial) {
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except005.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except005.java
new file mode 100644
index 00000000000..0bdf60d76e2
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except005.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except005.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except005
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ * log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * pool to store tiny objects to fill up the Heap
+ */
+ private static volatile Object pool[] = null;
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# Test have been updated!");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will try to return");
+ out.println("# the exit status 96 instead of 97 to indicate the problem.");
+ out.println("# However, the test may fail or even crash on some platforms");
+ out.println("# suffering the bug 4239841 or 4245060.");
+
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+ int index = 0;
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON) {
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ }
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ }
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Check InstantiationException (positive):
+ try {
+// Object junkIt = Abra_Cadabra.class.newInstance(); // illegal - should fail
+ Object junkIt = Abra.Cadabra.class.newInstance(); // legal - should pass
+ if (TRACE_ON)
+ log[messages++] = "Success: InstantiationException (positive)";
+ } catch (IllegalAccessException iae) {
+ log[messages++] =
+ "Failure: InstantiationException (positive) incorrectly thrown IllegalAccessException";
+ pool[index++] = iae;
+ exitCode = 2;
+ } catch (InstantiationException ie) {
+ log[messages++] = "Failure: InstantiationException (positive)";
+ pool[index++] = ie;
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: InstantiationException (positive)";
+ pool[index++] = oome;
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some OOME, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+ /**
+ * This class should be used to check CloneNotSupportedException,
+ * IllegalAccessException, and IllegalArgumentException.
+ * The class extends except005 in order that its (protected)
+ * method clone() be available from except005.
+ */
+ private static class Abra {
+ /**
+ * Will correctly instantiate Abra.Cadabra object.
+ */
+ public static class Cadabra {
+ }
+
+ /**
+ * Will try to correctly instantiate Abra.Cadabra,
+ * not Abra.
+ */
+ private Abra() {
+ }
+
+ }
+
+ /**
+ * Will try to incorrectly instantiate and object of this class.
+ */
+ private interface Abra_Cadabra {
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except006.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except006.java
new file mode 100644
index 00000000000..e66089268da
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except006.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except006.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except006
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ * log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will try to return");
+ out.println("# the exit status 96 instead of 97 to indicate the problem.");
+ out.println("# However, the test may fail or even crash on some platforms");
+ out.println("# suffering the bug 4239841 or 4245060.");
+
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+ int index = 0;
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+ Object junkIt;
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ }
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+
+ // Check InstantiationException (negative):
+ try {
+ junkIt = Abra_Cadabra.class.newInstance(); // illegal - should fail
+// Object junkIt = Abra.Cadabra.class.newInstance(); // legal - should pass
+ log[messages++] = "Failure: InstantiationException (negative)";
+ exitCode = 2;
+ } catch (IllegalAccessException iae) {
+ log[messages++] =
+ "Failure: InstantiationException (negative) incorrectly thrown IllegalAccessException";
+ exitCode = 2;
+ } catch (InstantiationException ie) {
+ if (TRACE_ON)
+ log[messages++] = "Success: InstantiationException (negative)";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: InstantiationException (negative)";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exception outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+ /**
+ * This class should be used to check CloneNotSupportedException,
+ * IllegalAccessException, and IllegalArgumentException.
+ * The class extends except006 in order that its (protected)
+ * method clone() be available from except006.
+ */
+ private static class Abra {
+ /**
+ * Will correctly instantiate Abra.Cadabra object.
+ */
+ public static class Cadabra {
+ }
+
+ /**
+ * Will try to correctly instantiate Abra.Cadabra,
+ * not Abra.
+ */
+ private Abra() {
+ }
+
+ }
+
+ /**
+ * Will try to incorrectly instantiate and object of this class.
+ */
+ private interface Abra_Cadabra {
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except007.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except007.java
new file mode 100644
index 00000000000..9265a24d36c
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except007.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except007.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except007
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ * log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will try to return");
+ out.println("# the exit status 96 instead of 97 to indicate the problem.");
+ out.println("# However, the test may fail or even crash on some platforms");
+ out.println("# suffering the bug 4239841 or 4245060.");
+
+ // Prepare some items, which will be used by the test:
+ Thread rabbit = new Rabbit();
+
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+
+ int index = 0;
+ pool[index++] = new Object();
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ }
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+
+ // Check InterruptedException:
+ try {
+ synchronized (rabbit) {
+ rabbit.start();
+ rabbit.wait();
+ }
+ rabbit.interrupt();
+ while (rabbit.isAlive())
+ rabbit.join();
+ Throwable exception = ((Rabbit) rabbit).exception;
+ if (exception == null) {
+ log[messages++] = "Failure: InterruptedException not thrown";
+ exitCode = 2;
+ } else {
+ if (exception instanceof InterruptedException) {
+ if (TRACE_ON)
+ log[messages++] =
+ "Success: InterruptedException thrown as expected";
+ } else if (exception instanceof OutOfMemoryError) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: InterruptedException";
+ skipped++;
+ } else {
+ log[messages++] =
+ "Failure: InterruptedException: unexpected exception thrown";
+ exitCode = 2;
+ }
+ pool[index++] = exception;
+ }
+ } catch (InterruptedException ie) {
+ log[messages++] = "Failure: InterruptedException thrown unexpectedly";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: InterruptedException";
+ skipped++;
+ }
+
+ // Check NegativeArraySizeException:
+ try {
+ int negative = -1;
+ byte array[] = new byte[negative];
+ log[messages++] = "Failure: NegativeArraySizeException not thrown as expected";
+ exitCode = 2;
+ } catch (NegativeArraySizeException ie) {
+ if (TRACE_ON)
+ log[messages++] = "Success: NegativeArraySizeException thrown as expected";
+ pool[index++] = ie;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: NegativeArraySizeException";
+ skipped++;
+ }
+
+ // Check NullPointerException:
+ try {
+ Double none = null;
+ double oops = none.doubleValue();
+ log[messages++] = "Failure: NullPointerException not thrown as expected";
+ exitCode = 2;
+ } catch (NullPointerException npe) {
+ if (TRACE_ON)
+ log[messages++] = "Success: NullPointerException thrown as expected";
+ pool[index++] = npe;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: NullPointerException";
+ skipped++;
+ }
+
+ // Check NumberFormatException:
+ try {
+ double oops = Double.parseDouble("3.14159D00"); // FORTRAN-like
+ log[messages++] = "Failure: NumberFormatException not thrown as expected";
+ exitCode = 2;
+ } catch (NumberFormatException nfe) {
+ if (TRACE_ON)
+ log[messages++] = "Success: NumberFormatException thrown as expected";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] = "Skipped: NumberFormatException";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Will shoot a rabbit when it waits -- in order to provoke
+ * InterruptedException.
+ */
+ private static class Rabbit extends Thread {
+ Throwable exception = null;
+
+ public void run() {
+ try {
+ synchronized (this) {
+ this.notify();
+ this.wait();
+ }
+ } catch (InterruptedException ie) {
+ exception = ie;
+ } catch (OutOfMemoryError oome) {
+ exception = oome;
+ }
+ }
+
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exception outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except008.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except008.java
new file mode 100644
index 00000000000..6266d255b0d
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except008.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except008.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M -XX:-UseGCOverheadLimit nsk.stress.except.except008
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ * log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will try to return");
+ out.println("# the exit status 96 instead of 97 to indicate the problem.");
+ out.println("# However, the test may fail or even crash on some platforms");
+ out.println("# suffering the bug 4239841 or 4245060.");
+
+ // Prepare some items, which will be used by the test:
+ Zoo zoo = new Zoo(); // load the class Zoo
+ Class noArgs[] = new Class[0];
+
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+
+ int index = 0;
+ pool[index++] = new Object();
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ }
+
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Check NoSuchFieldException (positive):
+ try {
+ Field valid = Zoo.class.getField("PUBLIC_FIELD"); // should pass
+// Field wrong = Zoo.class.getField("PRIVATE_FIELD"); // should fail
+ if (TRACE_ON)
+ log[messages++] = "Success: NoSuchFieldException not thrown as expected";
+ } catch (NoSuchFieldException nsfe) {
+ pool[index++] = nsfe;
+ log[messages++] = "Failure: NoSuchFieldException thrown unexpectedly";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: NoSuchFieldException positive check - OutOfMemoryError thrown";
+ skipped++;
+ }
+
+ // Check NoSuchFieldException (negative):
+ try {
+// Field valid = Zoo.class.getField("PUBLIC_FIELD"); // should pass
+ Field wrong = Zoo.class.getField("PRIVATE_FIELD"); // should fail
+ log[messages++] = "Failure: NoSuchFieldException incorrectly not thrown";
+ exitCode = 2;
+ } catch (NoSuchFieldException nsfe) {
+ if (TRACE_ON)
+ log[messages++] = "Success: NoSuchFieldException thrown as expected";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "NoSuchFieldException negative check - OutOfMemoryError thrown";
+ skipped++;
+ }
+
+ // Check NoSuchMethodException (positive):
+ try {
+ Method valid = Zoo.class.getMethod("PUBLIC_METHOD", noArgs); // should pass
+// Method wrong = Zoo.class.getMethod("PRIVATE_METHOD",noArgs); // should fail
+ if (TRACE_ON)
+ log[messages++] = "Success: NoSuchFieldException not thrown as expected";
+ } catch (NoSuchMethodException nsme) {
+ pool[index++] = nsme;
+ log[messages++] = "Failure: NoSuchMethodException thrown unexpectedly";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: NoSuchMethodException positive check - OutOfMemoryError thrown";
+ pool[index++] = oome;
+ skipped++;
+ }
+
+ // Check NoSuchMethodException (negative):
+ try {
+// Method valid = Zoo.class.getMethod("PUBLIC_METHOD",noArgs); // should pass
+ Method wrong = Zoo.class.getMethod("PRIVATE_METHOD", noArgs); // should fail
+ log[messages++] = "Failure: NoSuchMethodException incorrectly not thrown";
+ exitCode = 2;
+ } catch (NoSuchMethodException nsme) {
+ pool[index++] = nsme;
+ if (TRACE_ON)
+ log[messages++] = "Success: NoSuchFieldException thrown as expected";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: NoSuchMethodException negative check - OutOfMemoryError thrown";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Several items used to check reflections.
+ */
+ private static class Zoo {
+ public String PUBLIC_FIELD = "Accessible via reflection";
+ private String PRIVATE_FIELD = "Inaccessible via reflection";
+
+ public String PUBLIC_METHOD() {
+ return "Accessible via reflection";
+ }
+
+ private String PRIVATE_METHOD() {
+ return "Inaccessible via reflection";
+ }
+
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exception outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except009.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except009.java
new file mode 100644
index 00000000000..d3cfb02162d
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except009.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except009.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except009
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ * log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will try to return");
+ out.println("# the exit status 96 instead of 97 to indicate the problem.");
+ out.println("# However, the test may fail or even crash on some platforms");
+ out.println("# suffering the bug 4239841 or 4245060.");
+
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+ String s = "qwerty";
+ char c;
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+
+ int index = 0;
+ pool[index++] = new Object();
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ }
+
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Check StringIndexOutOfBoundsException:
+ try {
+ c = s.charAt(6); // should fail
+ log[messages++] = "Failure: StringIndexOutOfBoundsException incorrectly not thrown";
+ exitCode = 2;
+ } catch (StringIndexOutOfBoundsException sioobe) {
+ pool[index++] = sioobe;
+ if (TRACE_ON)
+ log[messages++] = "Success: StringIndexOutOfBoundsException thrown as expected";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: StringIndexOutOfBoundsException: thrown OutOfMemoryError";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exceprions outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except010.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except010.java
new file mode 100644
index 00000000000..b120d3acd59
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except010.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except010.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except010
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ * log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will try to return");
+ out.println("# the exit status 96 instead of 97 to indicate the problem.");
+ out.println("# However, the test may fail or even crash on some platforms");
+ out.println("# suffering the bug 4239841 or 4245060.");
+
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+
+ int index = 0;
+ pool[index++] = new Object();
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ }
+
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Check StackOverflowError:
+ try {
+ goIntoInfiniteRecursion();
+ log[messages++] = "Failure: StackOverflowError failed to throw";
+ exitCode = 2;
+ } catch (StackOverflowError soe) {
+ pool[index++] = soe;
+ if (TRACE_ON)
+ log[messages++] = "Success: StackOverflowError thrown as expected";
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: StackOverflowError: thrown OutOfMemoryError";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ private static void goIntoInfiniteRecursion() {
+ goIntoInfiniteRecursion();
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some exceptions outside the code, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc();
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011.java
new file mode 100644
index 00000000000..bbcf78cfd79
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except011.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except011
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ * log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+
+ private static final String className = "nsk.stress.except.except011.except011oops";
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will try to return");
+ out.println("# the exit status 96 instead of 97 to indicate the problem.");
+ out.println("# However, the test may fail or even crash on some platforms");
+ out.println("# suffering the bug 4239841 or 4245060.");
+
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+ Class oops;
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+
+ int index = 0;
+ pool[index++] = new Object();
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ }
+
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Check ExceptionInInitializerError:
+ try {
+ oops = Class.forName(className);
+ log[messages++] = "Failure: ExceptionInInitializerError failed to throw";
+ exitCode = 2;
+ } catch (ExceptionInInitializerError eiie) {
+ String message = eiie.getException().getMessage();
+ if (!message.equals("except011oops")) {
+ log[messages++] =
+ "Failure: ExceptionInInitializerError: unexpected target exception";
+ exitCode = 2;
+ } else if (TRACE_ON)
+ log[messages++] = "Success: ExceptionInInitializerError thrown as expected";
+ } catch (ClassNotFoundException cnfe) {
+ log[messages++] = "Failure: ExceptionInInitializerError: target class not found";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: ExceptionInInitializerError: thrown OutOfMemoryError";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some OOME, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ log = null;
+ System.gc(); // Empty memory to be able to write to the output
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // No code in the handler can provoke correct exceptions.
+ } else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011oops.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011oops.java
new file mode 100644
index 00000000000..46c9324404b
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011oops.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package nsk.stress.except;
+
+/**
+ * This class throws exception while static initialization.
+ * The test should load this class via reflection in order
+ * to hold the exception until runtime.
+ *
+ * @see nsk.stress.except.except011
+ */
+public class except011oops {
+ static boolean truth = true;
+
+ static {
+ if (truth)
+ throw new RuntimeException("except011oops");
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except012.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except012.java
new file mode 100644
index 00000000000..e773259e279
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except012.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/except/except012.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * The test tries to occupy all of memory available in the heap by allocating
+ * lots of new Object() instances. Instances of the type Object are the smallest
+ * objects, so they apparently should occupy most fine-grained fragments in the
+ * heap and leave no free space for new Throwable instance. After that, the test
+ * provokes various exceptions (e.g.: by executing integer division by 0 and so
+ * on), and checks if appropriate exceptions are thrown.
+ * COMMENTS
+ * The test needs a lot of memory to start up, so it should not run under older
+ * JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
+ * skipped when testing classic VM, because OutOfMemoryError is correctly thrown
+ * instead of target exception.
+ * When the test is being self-initiating (i.e.: eating heap), memory occupation
+ * is terminated if memory allocation slows down crucially. This is a workaround
+ * intended to avoid the HotSpot bug:
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ * There is also a workaround involved to avoid the following bugs known
+ * for HotSpot and for classic VM:
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)
+ * #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)
+ * However, printing of the test's error messages, warnings, and of execution
+ * trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
+ * problem, exit status 96 is returned instead of 97.
+ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
+ * #4245057 (P2/S3) VM crashes when heap is exhausted
+ *
+ * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except012
+ */
+
+package nsk.stress.except;
+
+import java.io.PrintStream;
+import java.util.Random;
+
+/**
+ * This checks if various exceptions are thrown (and caught) correctly
+ * when there apparently are no free space in the heap to allocate new
+ * Throwable instance.
+ * Object() instances. Instances of the
+ * type Object are the smallest objects, so they apparently should
+ * occupy most fine-grained fragments in the heap and leave no free space for
+ * new Throwable instance. After that, the test provokes various
+ * exceptions (e.g.: by executing integer division by 0 and so on), and checks
+ * if appropriate exceptions are thrown.
+ *
+ * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
+ *
+ * #4239841 (P1/S5) 1.1: poor garbage collector performance
+ *
+ * #4245060 (P4/S5) poor garbage collector performance
+ *
However, printing of the test's error messages, warnings, and of
+ * execution trace may fail even so. If the test fails due to poor GC
+ * performance, exit status 96 is returned instead of 97.
+ * log for error messages, warnings and/or execution trace.
+ *
+ * @see #messages
+ */
+ private static String log[] = new String[1000]; // up to 1000 messages
+ /**
+ * How many messages were submitted to the log.
+ *
+ * @see #log
+ */
+ private static int messages = 0;
+ /*
+ * Storage for a lot of tiny objects
+ * "static volatile" keywords are for preventing heap optimization
+ */
+ private static volatile Object pool[] = null;
+
+ /**
+ * Re-call to the method run(out) (ignore args[]),
+ * and print the test summary - either test passed of failed.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0) {
+ if (args[0].toLowerCase().startsWith("-v"))
+ TRACE_ON = true;
+ }
+
+ int exitCode = run(out);
+ pool = null;
+ System.gc();
+ // Print the log[] and the test summary:
+ try {
+ for (int i = 0; i < messages; i++)
+ out.println(log[i]);
+ if (exitCode == 0) {
+ if (TRACE_ON)
+ out.println("Test passed.");
+ } else
+ out.println("Test failed.");
+ } catch (OutOfMemoryError oome) {
+ // Poor performance of garbage collector:
+ exitCode = 1;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * Allocate as much Object instances as possible to bring JVM
+ * into stress, and then check if exceptions are correctly thrown accordingly
+ * to various situations like integer division by 0, etc.
+ */
+ private static int run(PrintStream out) {
+ out.println("# While printing this message, JVM seems to initiate the output");
+ out.println("# stream, so that it will not need more memory to print later,");
+ out.println("# when the heap would fail to provide more memory.");
+ out.println("# ");
+ out.println("# Note, that the test maintains especial static log[] field in");
+ out.println("# order to avoid printing when the heap seems exhausted.");
+ out.println("# Nevertheless, printing could arise OutOfMemoryError even");
+ out.println("# after all the memory allocated by the test is released.");
+ out.println("# ");
+ out.println("# That problem is caused by the known JDK/HotSpot bugs:");
+ out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");
+ out.println("# 4245060 (P4/S5) poor garbage collector performance");
+ out.println("# ");
+ out.println("# This message is just intended to work-around that problem.");
+ out.println("# If printing should fail even so, the test will try to return");
+ out.println("# the exit status 96 instead of 97 to indicate the problem.");
+ out.println("# However, the test may fail or even crash on some platforms");
+ out.println("# suffering the bug 4239841 or 4245060.");
+
+ // Allocate items necessary for the test:
+ CrazyClassLoader crazyClassLoader = new CrazyClassLoader();
+ MustDie threadToDie = new MustDie();
+
+ // Sum up exit code:
+ int exitCode = 0; // apparently PASSED
+ int skipped = 0; // some checks may correctly suffer OutOfMemoryError
+ // Allocate repository for a lots of tiny objects:
+ for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
+ try {
+ pool = new Object[size];
+ } catch (OutOfMemoryError oome) {
+ }
+ if (pool == null)
+ throw new Error("HS bug: cannot allocate new Object[1]");
+ int poolSize = pool.length;
+
+ int index = 0;
+ pool[index++] = new Object();
+
+ // Sum up time spent, when it was hard to JVM to allocate next object
+ // (i.e.: when JVM has spent more than 1 second to allocate new object):
+ double totalDelay = 0;
+ long timeMark = System.currentTimeMillis();
+ try {
+ for (; index < poolSize; index++) {
+ //-------------------------
+ pool[index] = new Object();
+ long nextTimeMark = System.currentTimeMillis();
+ long elapsed = nextTimeMark - timeMark;
+ timeMark = nextTimeMark;
+ //----------------------
+ if (elapsed > 1000) {
+ double seconds = elapsed / 1000.0;
+ if (TRACE_ON)
+ out.println(
+ "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
+ totalDelay += seconds;
+ if (totalDelay > 60) {
+ if (TRACE_ON)
+ out.println(
+ "Memory allocation became slow; so, heap seems exhausted.");
+ break;
+ }
+ }
+ }
+ } catch (OutOfMemoryError oome) {
+ if (TRACE_ON)
+ log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
+ }
+
+ if (index > poolSize - 1000) {
+ if (WARN_ON)
+ log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
+ }
+
+ // Check ClassFormatError:
+ try {
+ Class oops = crazyClassLoader.loadClass("name doesn't matter");
+ log[messages++] = "Failure: ClassFormatError failed to throw";
+ exitCode = 2;
+ } catch (ClassFormatError cfe) {
+ if (TRACE_ON)
+ log[messages++] = "Success: ClassFormatError thrown as expected";
+ } catch (ClassNotFoundException cnfe) {
+ log[messages++] =
+ "Failure: ClassFormatError: unexpectedly thrown ClassNotFoundException";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: ClassFormatError: thrown OutOfMemoryError";
+ skipped++;
+ }
+
+ // Check ThreadDeath:
+ try {
+ threadToDie.start();
+ while (threadToDie.isAlive())
+ threadToDie.join();
+ Throwable exception = threadToDie.exception;
+ if (exception == null) {
+ log[messages++] = "Failure: ThreadDeath failed to throw";
+ exitCode = 2;
+ } else if (exception instanceof OutOfMemoryError) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: ThreadDeath: thrown OutOfMemoryError instead";
+ } else if (!(exception instanceof ThreadDeath)) {
+ log[messages++] =
+ "Failure: ThreadDeath: unexpected exception thrown";
+ exitCode = 2;
+ } else if (TRACE_ON)
+ log[messages++] = "Success: ThreadDeath thrown as expected";
+ } catch (InterruptedException ie) {
+ pool[index++] = ie;
+ log[messages++] =
+ "Failure: ThreadDeath: thrown InterruptedException instead";
+ exitCode = 2;
+ } catch (OutOfMemoryError oome) {
+ if (WARN_ON)
+ log[messages++] =
+ "Skipped: ThreadDeath: thrown OutOfMemoryError";
+ skipped++;
+ }
+
+ return exitCode;
+ }
+
+ /**
+ * This class loader provokes ClassFormatError.
+ */
+ private static class CrazyClassLoader extends ClassLoader {
+ public Class loadClass(String name) throws ClassNotFoundException {
+ Class crazyClass = defineClass(null, crazyBytecode, 0, crazyBytecode.length);
+ return crazyClass; // return is unreacable, due to ClassFormatError
+ }
+
+ private static byte crazyBytecode[];
+
+ static {
+ crazyBytecode = new byte[1000];
+ Random random = new Random(0);
+ for (int i = 0; i < crazyBytecode.length; i++)
+ crazyBytecode[i] = (byte) random.nextInt(256);
+ }
+
+ }
+
+ /**
+ * This thread should die in order to check ThreadDeath error.
+ */
+ private static class MustDie extends Thread {
+ Throwable exception = null;
+
+ public void run() {
+ try {
+ stop();
+ } catch (Throwable throwable) {
+ exception = throwable;
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ }
+ }
+
+ }
+
+ /**
+ * Re-call to run(args,out), and return JCK-like exit status.
+ * (The stream out is assigned to System.out here.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ // Last try. If there is some OOME, test should end correctly
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ try {
+ pool = null;
+ System.gc(); // Empty memory to be able to write to the output
+ if (e instanceof OutOfMemoryError) {
+ try {
+ System.out.println("OOME : Test Skipped");
+ System.exit(0);
+ } catch (Throwable ignore) {
+ } // any of the test exceptions are handled in test.#
+ // No code in the handler can provoke correct exceptions.
+ } else if (e instanceof ThreadDeath) {
+ } //ignore since it thrown as expected
+ else {
+ e.printStackTrace();
+ throw (RuntimeException) e;
+ }
+ } catch (OutOfMemoryError oome) {
+ }
+ }
+ });
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/GarbageGenerator.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/GarbageGenerator.java
new file mode 100644
index 00000000000..654fc0edbbb
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/GarbageGenerator.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package nsk.stress.jni;
+
+class GarbageGenerator extends Thread {
+ class Garbage {
+ Garbage() {
+ this(1024);
+ }
+
+ Garbage(int m) {
+ memory = new byte[m];
+ }
+
+ void setNext(Garbage n) {
+ next = n;
+ }
+
+ Garbage getNext() {
+ return next;
+ }
+
+ protected void finalize() {
+ }
+
+ private Garbage next;
+ private byte[] memory;
+ }
+
+ class GarbageRing {
+ GarbageRing() {
+ attachment = new Garbage(0);
+ }
+
+ void add(int size) {
+ Garbage head = attachment.getNext();
+ Garbage g = new Garbage(size);
+ if (head != null) {
+ Garbage oldNext = head.getNext();
+ if (oldNext != null) {
+ g.setNext(oldNext);
+ head.setNext(g);
+ attachment.setNext(g);
+ } else {
+ g.setNext(head);
+ head.setNext(g);
+ }
+ } else
+ attachment.setNext(g);
+ }
+
+ void discard() {
+ attachment.setNext(null);
+ }
+
+ private byte[] memory;
+ private Garbage attachment;
+ }
+
+ public void run() {
+ GarbageRing gr = new GarbageRing();
+ int g = 0;
+ while (!done) {
+ for (g = 0; g < ringSize; g++) {
+ gr.add(allocSize);
+ yield();
+ }
+ gr.discard();
+ try {
+ sleep(interval);
+ } catch (InterruptedException e) {
+ }
+ }
+ if (DEBUG) System.out.println("GarbageRing::run(): done");
+ }
+
+ public void setAllocSize(int i) {
+ allocSize = i;
+ }
+
+ public int getAllocSize() {
+ return allocSize;
+ }
+
+ public void setInterval(int i) {
+ interval = i;
+ }
+
+ public int getInterval() {
+ return interval;
+ }
+
+ public void halt() {
+ done = true;
+ }
+
+ private int allocSize = 10000;
+ private int ringSize = 50;
+ private int interval = 1000;
+ private boolean done = false;
+ final private static boolean DEBUG = false;
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/Interrupter.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/Interrupter.java
new file mode 100644
index 00000000000..a1a8520e142
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/Interrupter.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package nsk.stress.jni;
+
+class Interrupter extends Thread {
+ public Interrupter(
+ Thread[] alloc,
+ Synchronizer[] s
+ ) {
+ targets = alloc;
+ sync = s;
+ if (DEBUG) System.out.println("Interrupter created.");
+ }
+
+ public void run() {
+ while (!done) {
+ synchronized (sync[2]) {
+ targets[turn].interrupt();
+ }
+ turn = (turn + 1) % targets.length;
+ try {
+ sleep(interval);
+ } catch (InterruptedException e) {
+ }
+ }
+ if (DEBUG) System.out.println("Interrupter::run(): done");
+ }
+
+ public void setInterval(int i) {
+ interval = i;
+ }
+
+ public int getInterval() {
+ return interval;
+ }
+
+ public void halt() {
+ done = true;
+ }
+
+ Thread[] targets;
+ Synchronizer[] sync;
+ private int turn = 0;
+ private int interval = 1000;
+ private boolean done = false;
+ final private static boolean DEBUG = false;
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/Synchronizer.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/Synchronizer.java
new file mode 100644
index 00000000000..5946dc7b6f7
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/Synchronizer.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package nsk.stress.jni;
+
+class Synchronizer {
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/TEST.properties
new file mode 100644
index 00000000000..8b51b2a9115
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/TEST.properties
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/gcl001.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/gcl001.java
new file mode 100644
index 00000000000..f7b1d935890
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/gcl001.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/jni/gclocker/gcl001.
+ * VM testbase keywords: [stress, quick, feature_283, nonconcurrent, exclude]
+ * VM testbase comments: JDK-8199562
+ * VM testbase readme:
+ * DESCRIPTION
+ * Check compatibility of GC Locker improvements with JNI CS
+ * Two types of concurrent threads are present:
+ * A) Create N 'JNI CS' threads. Each of them will:
+ * 1. Create primitive array and string with random data
+ * 2. Pass it to native method
+ * 3. Sort/Hash data in JNI CS mixing string and array critical sections
+ * 4. Check isCopy == false
+ * 5. Return from native
+ * 6. Check data to be processed correctly
+ * B) Create M ' Garbage producer/memory allocation' threads. Each of them will:
+ * 1. Allocate memory blocks and make them garbage.
+ * 2. Check for OOM errors.
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @ignore JDK-8199562
+ * @run main/othervm/native/timeout=480
+ * -XX:-UseGCOverheadLimit
+ * nsk.stress.jni.gclocker.gcl001
+ * -stressThreadsFactor 8
+ */
+
+package nsk.stress.jni.gclocker;
+
+import nsk.share.gc.GC;
+import nsk.share.gc.ThreadedGCTest;
+import nsk.share.gc.gp.array.BooleanArrayProducer;
+import nsk.share.gc.gp.array.ByteArrayProducer;
+import nsk.share.gc.gp.array.CharArrayProducer;
+import nsk.share.gc.gp.array.DoubleArrayProducer;
+import nsk.share.gc.gp.array.FloatArrayProducer;
+import nsk.share.gc.gp.array.IntArrayProducer;
+import nsk.share.gc.gp.array.LongArrayProducer;
+import nsk.share.gc.gp.array.ShortArrayProducer;
+import nsk.share.test.ExecutionController;
+import nsk.share.test.LocalRandom;
+
+import java.util.Random;
+
+public class gcl001 extends ThreadedGCTest {
+
+ static {
+ System.loadLibrary("gcl001");
+ }
+
+ int maxBlockSize;
+
+ public static void main(String[] args) {
+ GC.runTest(new gcl001(), args);
+ }
+
+ @Override
+ public void run() {
+ // each thread have only one block at the time
+ // so we should occupy less then 60% of heap with live objects
+ long maxSize = runParams.getTestMemory() / runParams.getNumberOfThreads();
+ if (maxSize > Integer.MAX_VALUE - 1) {
+ maxSize = Integer.MAX_VALUE - 1;
+ }
+ maxBlockSize = (int) maxSize;
+ log.info("Maximium block size = " + maxBlockSize);
+ super.run();
+ }
+
+ @Override
+ protected Runnable createRunnable(int i) {
+ if (i < runParams.getNumberOfThreads() / 2) {
+ return CreateJNIWorker(i, maxBlockSize);
+ } else {
+ return new GarbageProducer(maxBlockSize);
+ }
+ }
+
+ public Runnable CreateJNIWorker(int number, int size) {
+ JNIAbstractWorker worker = null;
+ switch (number % 8) {
+ case 0:
+ worker = new JNIBooleanWorker(size);
+ break;
+ case 1:
+ worker = new JNIByteWorker(size);
+ break;
+ case 2:
+ worker = new JNICharWorker(size);
+ break;
+ case 3:
+ worker = new JNIShortWorker(size);
+ break;
+ case 4:
+ worker = new JNIIntWorker(size);
+ break;
+ case 5:
+ worker = new JNILongWorker(size);
+ break;
+ case 6:
+ worker = new JNIFloatWorker(size);
+ break;
+ case 7:
+ worker = new JNIDoubleWorker(size);
+ break;
+ }
+ return worker;
+ }
+
+ int random(int maxSize) {
+ int res = LocalRandom.nextInt(maxSize);
+ return res > 128 ? res : 128;
+ }
+
+ public static Object tmp;
+
+ class GarbageProducer implements Runnable {
+
+ private int maxSize;
+ ExecutionController stresser;
+ ByteArrayProducer bp;
+
+ GarbageProducer(int size) {
+ this.maxSize = size;
+ bp = new ByteArrayProducer();
+ }
+
+ public void run() {
+ if (stresser == null) {
+ stresser = getExecutionController();
+ }
+
+ while (stresser.continueExecution()) {
+ try {
+ byte[] arr = bp.create(random(maxSize));
+ tmp = arr;
+ } catch (OutOfMemoryError oome) {
+ // Do nothing.
+ }
+ }
+ }
+ }
+
+ abstract class JNIAbstractWorker extends JNIWorker implements Runnable {
+
+ ExecutionController stresser;
+ private int maxSize;
+
+ public JNIAbstractWorker(int maxSize) {
+ this.maxSize = maxSize;
+ }
+
+ public void check(boolean condition, String message) {
+ if (!condition) {
+ throw new Error(message);
+ }
+ }
+
+ abstract void doit(int size);
+
+ public void run() {
+ // create array with random elements
+ // store min and max element for further check
+ // create new string
+ // call JNI methods
+ // check min/max as sort result
+ // check string hash
+
+ if (stresser == null) {
+ stresser = getExecutionController();
+ }
+ while (stresser.continueExecution()) {
+ // let make at least several values for long/float
+ try {
+ doit(random(maxSize));
+ } catch (OutOfMemoryError oome) {
+ // Do nothing.
+ }
+ }
+ }
+ }
+
+ // BYTE
+ class JNIBooleanWorker extends JNIAbstractWorker {
+
+ BooleanArrayProducer gp = new BooleanArrayProducer();
+
+ public JNIBooleanWorker(int size) {
+ super(size);
+ }
+
+ void doit(int size) {
+
+ boolean[] array = gp.create(size);
+ // just to be sure that we have true & false
+ array[0] = true;
+ array[array.length - 1] = false;
+ String str = "unsupported";
+ int nativeHash = NativeCall(array, str);
+ int javaHash = 0;
+ for (int i = 0; i < str.length(); ++i) {
+ javaHash += (int) str.charAt(i);
+ }
+ check(array[0] == false && array[array.length - 1] == true
+ && javaHash == nativeHash, "Data validation failure");
+
+ }
+ }
+
+ class JNIByteWorker extends JNIAbstractWorker {
+
+ ByteArrayProducer gp = new ByteArrayProducer();
+
+ public JNIByteWorker(int size) {
+ super(size);
+ }
+
+ void doit(int size) {
+
+ byte[] array = gp.create(size);
+ byte min = Byte.MAX_VALUE, max = Byte.MIN_VALUE;
+ for (int i = 0; i < array.length; ++i) {
+ if (array[i] > max) {
+ max = array[i];
+ }
+
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+ String str = "Min: " + min + " Max: " + max;
+ int nativeHash = NativeCall(array, str);
+ int javaHash = 0;
+ for (int i = 0; i < str.length(); ++i) {
+ javaHash += (int) str.charAt(i);
+ }
+
+ check(array[0] == min && array[array.length - 1] == max
+ && javaHash == nativeHash, "Data validation failure");
+
+ }
+ }
+
+ // CHAR
+ class JNICharWorker extends JNIAbstractWorker {
+
+ CharArrayProducer gp = new CharArrayProducer();
+
+ public JNICharWorker(int size) {
+ super(size);
+ }
+
+ void doit(int size) {
+ char[] array = gp.create(size);
+ Random rand = new Random();
+ char min = 0xffff, max = 0;
+ for (int i = 0; i < array.length; ++i) {
+ array[i] = (char) rand.nextInt();
+ if (array[i] > max) {
+ max = array[i];
+ }
+
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+ String str = "Min: " + min + " Max: " + max;
+ int nativeHash = NativeCall(array, str);
+ int javaHash = 0;
+ for (int i = 0; i < str.length(); ++i) {
+ javaHash += (int) str.charAt(i);
+ }
+
+ check(array[0] == min && array[array.length - 1] == max
+ && javaHash == nativeHash, "Data validation failure");
+
+ }
+ }
+
+ // SHORT
+ class JNIShortWorker extends JNIAbstractWorker {
+
+ ShortArrayProducer gp = new ShortArrayProducer();
+
+ public JNIShortWorker(int size) {
+ super(size);
+ }
+
+ void doit(int size) {
+
+ short[] array = gp.create(size);
+ short min = Short.MAX_VALUE, max = Short.MIN_VALUE;
+ for (int i = 0; i < array.length; ++i) {
+ if (array[i] > max) {
+ max = array[i];
+ }
+
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+ String str = "Min: " + min + " Max: " + max;
+ int nativeHash = NativeCall(array, str);
+ int javaHash = 0;
+ for (int i = 0; i < str.length(); ++i) {
+ javaHash += (int) str.charAt(i);
+ }
+
+ check(array[0] == min && array[array.length - 1] == max
+ && javaHash == nativeHash, "Data validation failure");
+ }
+ }
+
+ // INT
+ class JNIIntWorker extends JNIAbstractWorker {
+
+ IntArrayProducer gp = new IntArrayProducer();
+
+ public JNIIntWorker(int size) {
+ super(size);
+ }
+
+ void doit(int size) {
+ int[] array = gp.create(size);
+ int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
+ for (int i = 0; i < array.length; ++i) {
+ if (array[i] > max) {
+ max = array[i];
+ }
+
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+ String str = "Min: " + min + " Max: " + max;
+ int nativeHash = NativeCall(array, str);
+ int javaHash = 0;
+ for (int i = 0; i < str.length(); ++i) {
+ javaHash += (int) str.charAt(i);
+ }
+
+ check(array[0] == min && array[array.length - 1] == max
+ && javaHash == nativeHash, "Data validation failure");
+
+ }
+ }
+
+ // LONG
+ class JNILongWorker extends JNIAbstractWorker {
+
+ LongArrayProducer gp = new LongArrayProducer();
+
+ public JNILongWorker(int size) {
+ super(size);
+ }
+
+ void doit(int size) {
+
+ long[] array = gp.create(size);
+ long min = Long.MAX_VALUE, max = Long.MIN_VALUE;
+ for (int i = 0; i < array.length; ++i) {
+ if (array[i] > max) {
+ max = array[i];
+ }
+
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+ String str = "Min: " + min + " Max: " + max;
+ int nativeHash = NativeCall(array, str);
+ int javaHash = 0;
+ for (int i = 0; i < str.length(); ++i) {
+ javaHash += (int) str.charAt(i);
+ }
+
+ check(array[0] == min && array[array.length - 1] == max
+ && javaHash == nativeHash, "Data validation failure");
+
+ }
+ }
+
+ // FLOAT
+ class JNIFloatWorker extends JNIAbstractWorker {
+
+ FloatArrayProducer gp = new FloatArrayProducer();
+
+ public JNIFloatWorker(int size) {
+ super(size);
+ }
+
+ void doit(int size) {
+
+ float[] array = gp.create(size);
+ float min = Float.MAX_VALUE, max = Float.MIN_VALUE;
+ for (int i = 0; i < array.length; ++i) {
+ if (array[i] > max) {
+ max = array[i];
+ }
+
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+ String str = "Min: " + min + " Max: " + max;
+ int nativeHash = NativeCall(array, str);
+ int javaHash = 0;
+ for (int i = 0; i < str.length(); ++i) {
+ javaHash += (int) str.charAt(i);
+ }
+
+ check(array[0] == min && array[array.length - 1] == max
+ && javaHash == nativeHash, "Data validation failure");
+ }
+ }
+
+ // DOUBLE
+ class JNIDoubleWorker extends JNIAbstractWorker {
+
+ DoubleArrayProducer gp = new DoubleArrayProducer();
+
+ public JNIDoubleWorker(int size) {
+ super(size);
+ }
+
+ void doit(int size) {
+
+ double[] array = gp.create(size);
+ Random rand = new Random();
+ double min = Double.MAX_VALUE, max = Double.MIN_VALUE;
+ for (int i = 0; i < array.length; ++i) {
+ if (array[i] > max) {
+ max = array[i];
+ }
+
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+ String str = "Min: " + min + " Max: " + max;
+ int nativeHash = NativeCall(array, str);
+ int javaHash = 0;
+ for (int i = 0; i < str.length(); ++i) {
+ javaHash += (int) str.charAt(i);
+ }
+
+ check(array[0] == min && array[array.length - 1] == max
+ && javaHash == nativeHash, "Data validation failure");
+ }
+ }
+}
+
+class JNIWorker {
+
+ protected native int NativeCall(boolean[] array, String str);
+
+ protected native int NativeCall(byte[] array, String str);
+
+ protected native int NativeCall(char[] array, String str);
+
+ protected native int NativeCall(short[] array, String str);
+
+ protected native int NativeCall(int[] array, String str);
+
+ protected native int NativeCall(long[] array, String str);
+
+ protected native int NativeCall(float[] array, String str);
+
+ protected native int NativeCall(double[] array, String str);
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/libgcl001.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/libgcl001.c
new file mode 100644
index 00000000000..9d37866b4e6
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/gclocker/libgcl001.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#include System.out.
+ */
+ static private PrintStream out = System.out;
+
+ /**
+ * Print error message: both client and server may print
+ * concurently.
+ */
+ static private synchronized void println(Object message) {
+ out.println(message.toString());
+ }
+
+ /**
+ * Display optional report: comment ca va.
+ */
+ static private void display(Object report) {
+ if (DEBUG_MODE)
+ println(report.toString());
+ }
+
+ /**
+ * Server thread intended to reply to data parcels sent by Client thread.
+ */
+ static private class Server extends Thread {
+ /**
+ * This server thread listens the single socket.
+ */
+ private ServerSocket serverSocket;
+
+ /**
+ * Address and port of this server socket.
+ */
+ public String toString() {
+ return serverSocket.toString();
+ }
+
+ /**
+ * Did the thread failed? If yes, what is the failure's reason.
+ */
+ Exception exception = null;
+
+ /**
+ * Which port does this socket is listening.
+ */
+ int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ /**
+ * Find some free port at the given address
+ * and attach new server to hear that port.
+ */
+ Server(InetAddress address) throws IOException {
+ int someFreePort = 0;
+ int backlog = 50; // default for new ServerSocket(port)
+ serverSocket = new ServerSocket(someFreePort, backlog, address);
+ }
+
+ /**
+ * Accept connection, read the string "abra", and respond "cadabra".
+ */
+ public void run() {
+ try {
+ Socket socket = serverSocket.accept();
+ display("Server socket: " + socket);
+
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(0);
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ println("Server thread got unexpected parcel:");
+ println("sample=" + sample);
+ println("etalon=" + etalon);
+ throw new TestFailure(
+ "server has read unexpected parcel");
+ }
+
+ etalon.send(ostream);
+ ostream.flush();
+ }
+
+ int datum = istream.read(); // wait for client close()
+ if (datum >= 0)
+ throw new TestFailure(
+ "server has read ambigous byte: " + datum);
+
+ ostream.close(); // implies: socket.close();
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ }
+
+ /**
+ * Client thread intended to send data parcels to Server thread and
+ * to recieve the server's replies.
+ */
+ static private class Client extends Thread {
+ /**
+ * This thread uses the single client socket.
+ */
+ private Socket socket;
+
+ /**
+ * Address and port of this socket.
+ */
+ public String toString() {
+ return socket.toString();
+ }
+
+ /**
+ * Did the thread failed? If yes, what is the failure's reason.
+ */
+ Exception exception = null;
+
+ /**
+ * Connect client socket on the given address
+ * and port.
+ */
+ Client(InetAddress address, int port) throws IOException {
+ socket = new Socket(address, port);
+ }
+
+ /**
+ * Accept connection, read the string "abra", and respond "cadabra".
+ */
+ public void run() {
+ try {
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(0);
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+ etalon.send(ostream);
+ ostream.flush();
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ println("Client thread got unexpected parcel:");
+ println("sample=" + sample);
+ println("etalon=" + etalon);
+ throw new TestFailure(
+ "parcel context is unexpected to client");
+ }
+ }
+
+ if (istream.available() > 0) {
+ int datum = istream.read();
+ throw new TestFailure(
+ "client has read ambigous byte: " + datum);
+ }
+ ostream.close(); // implies: socket.close()
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ }
+
+ /**
+ * A data parcel to sent/recieved between Client and Server threads.
+ * When data parcel is sent, first 4 bytes transfered encode the size
+ * of the parcel (i.e.: number of data bytes in the parcel's contents).
+ * Then the parcel's contents bytes are transered.
+ */
+ static class Parcel {
+ private byte[] parcel;
+
+ /**
+ * Display all bytes as integer values from 0 to 255;
+ * or return ``null'' if this Parcel is not
+ * yet initialized.
+ */
+ public String toString() {
+ if (parcel == null)
+ return "null";
+ String s = "{";
+ for (int i = 0; i < parcel.length; i++)
+ s += (i > 0 ? ", " : "") + ((int) parcel[i] & 0xFF);
+ return s + "}";
+ }
+
+ /**
+ * Generate new parcel[] array using the given
+ * random numbers generator. Client and Server
+ * threads should use identical random generators,
+ * so that those threads could generate equal data parcels and
+ * check the parcel just transfered.
+ */
+ public Parcel(Random random) {
+ int size = random.nextInt(MAX_PARCEL) + 1;
+ parcel = new byte[size];
+ for (int i = 0; i < size; i++)
+ parcel[i] = (byte) random.nextInt(256);
+ }
+
+ /**
+ * Read exactly size bytes from the istream
+ * if possible, or throw TestFailure if unexpected end of
+ * istream occurs.
+ */
+ private static byte[] readBytes(int size, InputStream istream)
+ throws IOException {
+
+ byte data[] = new byte[size];
+ for (int i = 0; i < size; i++) {
+ int datum = istream.read();
+ if (datum < 0)
+ throw new TestFailure(
+ "unexpected EOF: have read: " + i + " bytes of " + size);
+ data[i] = (byte) datum;
+ }
+ return data;
+ }
+
+ /**
+ * Read 4 bytes from istream and threat them to encode
+ * size of data parcel following these 4 bytes.
+ */
+ private static int getSize(InputStream istream) throws IOException {
+ byte data[] = readBytes(4, istream);
+ int data0 = (int) data[0] & 0xFF;
+ int data1 = (int) data[1] & 0xFF;
+ int data2 = (int) data[2] & 0xFF;
+ int data3 = (int) data[3] & 0xFF;
+ int sizeWord = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
+ int size = sizeWord + 1;
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+ return size;
+ }
+
+ /**
+ * Send 4 bytes encoding actual size of the parcel just to be transfered.
+ */
+ private static void putSize(OutputStream ostream, int size)
+ throws IOException {
+
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+
+ int sizeWord = size - 1;
+ byte data[] = new byte[4];
+ data[0] = (byte) sizeWord;
+ data[1] = (byte) (sizeWord >> 8);
+ data[2] = (byte) (sizeWord >> 16);
+ data[3] = (byte) (sizeWord >> 24);
+ ostream.write(data);
+ }
+
+ /**
+ * Recieve data parcel.
+ */
+ public Parcel(InputStream istream) throws IOException {
+ int size = getSize(istream);
+ parcel = readBytes(size, istream);
+ }
+
+ /**
+ * Send this data parcel.
+ */
+ public void send(OutputStream ostream) throws IOException {
+ int size = parcel.length;
+ putSize(ostream, size);
+ ostream.write(parcel);
+ }
+
+ /**
+ * Check byte-to-byte equality between this and the
+ * other parcels.
+ */
+ public boolean equals(Parcel other) {
+ if (this.parcel.length != other.parcel.length)
+ return false;
+ int size = parcel.length;
+ for (int i = 0; i < size; i++)
+ if (this.parcel[i] != other.parcel[i])
+ return false;
+ return true;
+ }
+
+ }
+
+ /**
+ * Server or Client thread may throw this exception to report the test
+ * failure.
+ */
+ static class TestFailure extends RuntimeException {
+ /**
+ * Report particular purpose of the test failure.
+ */
+ public TestFailure(String purpose) {
+ super(purpose);
+ }
+
+ }
+
+ /**
+ * Attach client and server sockets to the local host, and check if
+ * huge amount of data could be correctly transfered between these
+ * sockets.
+ * args[] may
+ * prompt the local host IP address or domain name. Execute:
+ *
+ * java network001 [IP-address | host_name |
+ * localhost ]
+ *
where parameters are:
+ *
+ * IP-address - local hots's address, or 127.0.0.1
+ *
+ * host_name - local host's domain name, or the
+ * keyword ``localhost''
+ *
+ * localhost - placeholder for the IP-address 127.0.0.1
+ *
By default, the test uses the Internet address available via
+ * the method InetAddress.getLocalHost()
+ */
+ public static int run(String args[], PrintStream out) {
+ network001.out = out;
+
+ //
+ // Get IP address of the local machine.
+ //
+
+ InetAddress address = null;
+ try {
+ switch (args.length) {
+ case 0:
+ address = InetAddress.getLocalHost();
+ break;
+ case 1:
+ String hostName = args[0];
+ address = InetAddress.getByName(args[0]);
+ break;
+ default:
+ println("Use:");
+ println(" java network001");
+ println("or:");
+ println(" java network001 ${IP_ADDRESS}");
+ println("or:");
+ println(" java network001 ${HOST_NAME}");
+ println("or:");
+ println(" java network001 localhost");
+ return 2; // FAILED
+ }
+ } catch (UnknownHostException exception) {
+ println(exception);
+ return 2; // FAILED
+ }
+ display("Host: " + address);
+
+ //
+ // Incarnate the server & the client sockets.
+ //
+
+ Server server = null;
+ try {
+ server = new Server(address);
+ } catch (IOException io) {
+ println("Failed to create server: " + io);
+ return 2;
+ }
+ display("Server: " + server);
+
+ int port = server.getPort();
+
+ Client client = null;
+ try {
+ client = new Client(address, port);
+ } catch (IOException io) {
+ out.println("Failed to create client: " + io);
+ return 2;
+ }
+ display("Client socket: " + client);
+
+ //
+ // Execute the server and client threads.
+ //
+
+ Exception exception = null;
+ try {
+ server.start();
+ client.start();
+ while (client.isAlive() || server.isAlive())
+ if (client.exception == null && server.exception == null)
+ Thread.yield();
+ else
+ break;
+ } catch (TestFailure failure) {
+ exception = failure;
+ }
+
+ // Failure diagnostics, if needed.
+
+ Exception problem[] = new Exception[3];
+ problem[0] = exception;
+ problem[1] = server.exception;
+ problem[2] = client.exception;
+
+ int exitCode = 0;
+
+ for (int i = 0; i < 3; i++)
+ if (problem[i] != null) {
+ out.println("#### OOPS ! ####");
+ problem[i].printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0) {
+ out.println("#### OOPS ! ####");
+ out.println("# Test failed.");
+ return 2; // FAILED
+ }
+ display("Test passed.");
+ return 0; // PASSED
+ }
+
+ /**
+ * Re-calls to the method run(args[],out) actually
+ * performing the test; and stop with exit code 95 if the test
+ * has passed, or with code 97 if the test has failed.
+ * (This is JCK-like exit codes convention.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit code.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network002.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network002.java
new file mode 100644
index 00000000000..fdbaca17f16
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network002.java
@@ -0,0 +1,697 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/network/network002.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test transfers huge amount of data between 2 Java virtual machines
+ * using the TCP/IP protocol, and checks if those data are transfered correctly.
+ * Both client and server VMs run on the same local computer and attach TCP/IP
+ * sockets to the local host, or to the loopback domain "localhost" (having IP
+ * address 127.0.0.1).
+ * Information transfer is synchronized in this test. Client VM passes
+ * a large data parcel to server VM, and server reads that parcel and checks
+ * if it is same as expected (byte-to-byte equality). Then server passes
+ * (some other) parcel to client, and client reads and verifies those data.
+ * This ping-pong game is repeated 2000 times; and after that both VMs check
+ * if there are no extra bytes accudentally passed through their connection.
+ * Parcels lengths and contents are chosen randomly, and average parcel
+ * length is 125 bytes. So totally, each of the 2 VMs passes ~250Kb of data
+ * to its partner, and thus ~500Kb of data are transfered by this test.
+ * COMMENTS
+ * HotSpot 1.3beta-H fails to start this test due to the hotspot bug:
+ * #4245704 (P1/S1) Fails to launch with: jre/bin/net.dll ...
+ * Test was fixed:
+ * added WAITTIME parameter defined timeout for TCP/IP sockets in minutes
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.stress.network.network002
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.stress.network.network002
+ * "${test.jdk}/bin/java ${test.vm.opts} ${test.java.opts}" 5
+ */
+
+package nsk.stress.network;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Random;
+
+/**
+ * This test transfers huge amount of data between 2 Java virtual machines
+ * using the TCP/IP protocol, and checks if those data are transfered correctly.
+ * Both client and server VMs run on the same local computer and attach TCP/IP
+ * sockets to the local host, or to the loopback domain ``localhost''
+ * (having IP address 127.0.0.1).
+ * run(args[],out) actually
+ * performing the test. After run(args[],out) stops,
+ * follow JDK-like convention for exit codes. I.e.: stop with
+ * exit status 95 if the test has passed, or with status 97 if
+ * the test has failed.
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+ /**
+ * Incarnate new network002 instance reporting to the given
+ * out stream, and invoke the method run(args)
+ * for that instance to perform the test.
+ */
+ public static int run(String args[], PrintStream out) {
+ network002 test = new network002(out);
+ int exitCode = test.run(args);
+ return exitCode;
+ }
+
+ /**
+ * Parse command-line parameters stored into args[] array,
+ * then perform the test. I.e.: start the server thread at the same VM
+ * this method runs, then start the other client VM, and verify data
+ * transfer through TCP/IP connection between those different virtual
+ * machines.
+ *
+ * java network002 java_command waittime
+ * [IP-address | host_name | localhost ]
+ *
where parameters are:
+ *
+ * java_command - how to start java,
+ * e.g.: ``c:\jdk1.3\bin\java -classic''
+ *
+ * waittime - timeout for TCP/IP sockets in minutes
+ *
+ * IP-address - local hots's address, or 127.0.0.1
+ *
+ * host_name - local host's domain name, or the
+ * keyword ``localhost''
+ *
+ * localhost - placeholder for the IP-address 127.0.0.1
+ * java_command should point to the same
+ * Java machine just executing this test. However, every compatible Java 2
+ * implementation is appropriate.
+ * InetAddress.getLocalHost() to get the domain name and
+ * IP-address of the local computer.
+ */
+ private int run(String args[]) {
+ //
+ // Get the Internet address of the local machine.
+ //
+ InetAddress address = null;
+ try {
+ switch (args.length) {
+ case 2:
+ address = InetAddress.getLocalHost();
+ break;
+ case 3:
+ address = InetAddress.getByName(args[2]);
+ break;
+ default:
+ complain("Illegal arguments number; execute:");
+ complain(" java network002 $JAVA_COMMAND " +
+ "[$IP_ADDRESS | $HOST_NAME | localhost]");
+ return 2; // FAILED
+ }
+ } catch (UnknownHostException exception) {
+ complain(exception.toString());
+ return 2; // FAILED
+ }
+ display("Host: " + address);
+
+ //
+ // Start the server thread on the same VM this method just runs.
+ //
+ Server server = null;
+ try {
+ server = new Server(address);
+ server.start();
+ } catch (Exception exception) {
+ complain("Failed to start server: " + exception);
+ return 2;
+ }
+ display("Server: " + server);
+
+ //
+ // Start the client process on different VM.
+ //
+ String IPAddress = server.getIPAddress(); // e.g.: 127.0.0.1
+ int port = server.getPort();
+ String command = args[0] + " " + network002.class.getName() + "$Client " + IPAddress + " " + port;
+ try {
+ SO_TIMEOUT = Integer.parseInt(args[1]) * 60 * 1000;
+ } catch (NumberFormatException e) {
+ complain("Wrong timeout argument: " + e);
+ return 2;
+ }
+
+ Runtime runtime = Runtime.getRuntime();
+
+ Process client = null;
+ IORedirector redirectOut = null;
+ IORedirector redirectErr = null;
+
+ try {
+ client = runtime.exec(command);
+
+ InputStream clientOut = client.getInputStream();
+ InputStream clientErr = client.getErrorStream();
+ redirectOut = new IORedirector(clientOut, DEBUG_MODE ? out : null);
+ redirectErr = new IORedirector(clientErr, out);
+ redirectOut.start();
+ redirectErr.start();
+
+ } catch (Exception exception) {
+ complain("Failed to start client: " + exception);
+ return 2;
+ }
+
+ //
+ // Wait until the server and client both stop.
+ //
+ try {
+ client.waitFor();
+ if (redirectOut.isAlive())
+ redirectOut.join();
+ if (redirectErr.isAlive())
+ redirectErr.join();
+
+ // If client has crashed, also terminate the server (to avoid hangup).
+ int clientStatus = client.exitValue();
+ if (clientStatus != 95) {
+ complain("");
+ complain("Client VM has crashed: exit status=" + clientStatus);
+ if (server.isAlive())
+ complain("Server also should be terminated.");
+ complain("Test failed.");
+ return 2; // failure
+ }
+
+ // Client has finished OK; wait for the server.
+ if (server.isAlive())
+ server.join();
+
+ } catch (Exception exception) {
+ complain("Test interrupted: " + exception);
+ complain("Test failed.");
+ return 2; // FAILURE
+ }
+
+ //
+ // Complain failure, if occured.
+ //
+
+ if (server.exception != null) {
+ complain("Server exception: " + server.exception);
+ complain("Test failed.");
+ return 2; // failure
+ }
+
+ display("Test passed.");
+ return 0; // Ok
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * The test should report to the given out stream.
+ */
+ private network002(PrintStream out) {
+ this.out = out;
+ }
+
+ /**
+ * Log stream for error messages and/or (optional) execution trace.
+ */
+ private PrintStream out;
+
+ /**
+ * Print error message.
+ */
+ private void complain(Object message) {
+ out.println("# " + message);
+ out.flush();
+ }
+
+ /**
+ * Display optional report: comment ca va?
+ */
+ private void display(Object report) {
+ if (DEBUG_MODE)
+ out.println(report.toString());
+ out.flush();
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Server thread should reply to data parcels sent by Client VM.
+ */
+ private class Server extends Thread {
+ /**
+ * The socket to listen for a client.
+ */
+ private ServerSocket serverSocket;
+
+ /**
+ * Display the server socket.
+ */
+ public String toString() {
+ return serverSocket.toString();
+ }
+
+ /**
+ * Server's IP-address in the form ``x.y.u.z'',
+ * or ``127.0.0.1'' for loopback connection.
+ */
+ public String getIPAddress() {
+ return serverSocket.getInetAddress().getHostAddress();
+ }
+
+ /**
+ * Which port is this socket listening?
+ */
+ int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ /**
+ * Find some free port at the given address
+ * and attach new server to hear that port.
+ */
+ public Server(InetAddress address) throws IOException {
+ int someFreePort = 0;
+ int backlog = 50; // default for new ServerSocket(port)
+ serverSocket = new ServerSocket(someFreePort, backlog, address);
+ }
+
+ /**
+ * Exception just arisen while the server was working,
+ * or null if it was OK with the server.
+ */
+ Exception exception = null;
+
+ /**
+ * Accept connection, then reply to client's parcels.
+ */
+ public void run() {
+ try {
+ Socket socket = serverSocket.accept();
+ socket.setSoTimeout(SO_TIMEOUT);
+
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(0);
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ display("Server: i=" + i);
+ Parcel etalon = new Parcel(random);
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ complain("Server got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "the parcel just read seems wrong for server");
+ }
+
+ etalon.send(ostream);
+ ostream.flush();
+ }
+
+ int datum = istream.read(); // wait for client close()
+ if (datum >= 0)
+ throw new TestFailure(
+ "server has read ambigous byte: " + datum);
+
+ ostream.close(); // implies: socket.close();
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Client VM should send data parcels to Server VM and
+ * recieve and verify the server's replies.
+ */
+ private static class Client {
+ /**
+ * Print error message.
+ */
+ private static void complain(Object message) {
+ System.err.println("# " + message);
+ System.err.flush();
+ }
+
+ /**
+ * Display execution trace.
+ */
+ private static void display(Object message) {
+ System.out.println(message.toString());
+ System.out.flush();
+ }
+
+ /**
+ * Exit with JCK-like status.
+ */
+ private static void exit(int exitCode) {
+ System.exit(exitCode + 95);
+ }
+
+ /**
+ * Atack server with huge data parcels, and check if it replies correctly.
+ * The command-line parameters prescribe the server's IP-address and port:
+ *
+ * java network002$Client IP-address port
+ *
where:
+ *
+ * IP-address - local host's address,
+ * or 127.0.0.1
+ *
+ * port - some port assigned by server
+ */
+ public static void main(String args[]) {
+ if (args.length != 2) {
+ complain("Illegal number of client paramenets, try:");
+ complain(" java network002$Client IP-address port");
+ exit(2); // FAILED
+ }
+
+ try {
+ InetAddress address = InetAddress.getByName(args[0]);
+ int port = Integer.parseInt(args[1]);
+
+ Socket socket = new Socket(address, port);
+ socket.setSoTimeout(SO_TIMEOUT);
+ display("Client: " + socket);
+
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(0);
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ display("Client: i=" + i);
+ Parcel etalon = new Parcel(random);
+ etalon.send(ostream);
+ ostream.flush();
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ complain("Client got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "parcel context is unexpected to client");
+ }
+ }
+
+ if (istream.available() > 0) {
+ int datum = istream.read();
+ throw new TestFailure(
+ "client has read ambigous byte: " + datum);
+ }
+ ostream.close(); // implies: socket.close()
+
+ } catch (Exception exception) {
+ complain("Client exception: " + exception);
+ exit(2); // FAILED
+ }
+ exit(0); // PASSED, at least at the client side.
+ }
+
+ }
+
+ /**
+ * Two of such threads should redirect out and err
+ * streams of client VM.
+ */
+ private static class IORedirector extends Thread {
+ /**
+ * Source stream.
+ */
+ InputStream in;
+ /**
+ * Destination stream.
+ */
+ OutputStream out;
+
+ /**
+ * Redirect in to out.
+ */
+ public IORedirector(InputStream in, OutputStream out) {
+ this.in = in;
+ this.out = out;
+ }
+
+ /**
+ * Read input stream until the EOF, and write everithing to output stream.
+ * If output stream is assigned to null, do not print anything,
+ * but read the input stream anywhere.
+ */
+ public void run() {
+ try {
+ for (; ; ) {
+ int symbol = in.read();
+ if (symbol < 0)
+ break; // EOF
+ if (out != null)
+ out.write(symbol);
+ }
+
+ if (out != null)
+ out.flush();
+
+ } catch (Exception exception) {
+ throw new TestFailure("IORedirector exception: " + exception);
+ }
+ }
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * A data parcel to be sent/recieved between Client VM and Server thread.
+ * When data parcel is sent, first 4 bytes are transfered which encode the
+ * int number equal to size of the parcel minus 1. I.e.: if
+ * number of data bytes in the parcel's contents is N, then
+ * the first 4 bytes encode the number N-1. After that, the
+ * parcel's contents bytes are transered.
+ */
+ static class Parcel {
+ private byte[] parcel;
+
+ /**
+ * Display all bytes as integer values from 0 to 255;
+ * or return ``null'' if this Parcel is not
+ * yet initialized.
+ */
+ public String toString() {
+ if (parcel == null)
+ return "null";
+ String s = "{";
+ for (int i = 0; i < parcel.length; i++)
+ s += (i > 0 ? ", " : "") + ((int) parcel[i] & 0xFF);
+ return s + "}";
+ }
+
+ /**
+ * Generate new parcel[] array using the given
+ * random numbers generator. Client and Server
+ * threads should use identical random generators,
+ * so that those threads could generate equal data parcels and
+ * check the parcel just transfered.
+ */
+ public Parcel(Random random) {
+ int size = random.nextInt(MAX_PARCEL) + 1;
+ parcel = new byte[size];
+ for (int i = 0; i < size; i++)
+ parcel[i] = (byte) random.nextInt(256);
+ }
+
+ /**
+ * Read exactly size bytes from the istream
+ * if possible, or throw TestFailure if unexpected end of
+ * istream occurs.
+ */
+ private static byte[] readBytes(int size, InputStream istream)
+ throws IOException {
+
+ byte data[] = new byte[size];
+ for (int i = 0; i < size; i++) {
+ int datum = istream.read();
+ if (datum < 0)
+ throw new TestFailure(
+ "unexpected EOF: have read: " + i + " bytes of " + size);
+ data[i] = (byte) datum;
+ }
+ return data;
+ }
+
+ /**
+ * Read 4 bytes from istream and threat them to encode
+ * size of data parcel following these 4 bytes.
+ */
+ private static int getSize(InputStream istream) throws IOException {
+ byte data[] = readBytes(4, istream);
+ int data0 = (int) data[0] & 0xFF;
+ int data1 = (int) data[1] & 0xFF;
+ int data2 = (int) data[2] & 0xFF;
+ int data3 = (int) data[3] & 0xFF;
+ int sizeWord = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
+ int size = sizeWord + 1;
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+ return size;
+ }
+
+ /**
+ * Send 4 bytes encoding actual size of the parcel just to be transfered.
+ */
+ private static void putSize(OutputStream ostream, int size)
+ throws IOException {
+
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+
+ int sizeWord = size - 1;
+ byte data[] = new byte[4];
+ data[0] = (byte) sizeWord;
+ data[1] = (byte) (sizeWord >> 8);
+ data[2] = (byte) (sizeWord >> 16);
+ data[3] = (byte) (sizeWord >> 24);
+ ostream.write(data);
+ }
+
+ /**
+ * Recieve data parcel.
+ */
+ public Parcel(InputStream istream) throws IOException {
+ int size = getSize(istream);
+ parcel = readBytes(size, istream);
+ }
+
+ /**
+ * Send this data parcel.
+ */
+ public void send(OutputStream ostream) throws IOException {
+ int size = parcel.length;
+ putSize(ostream, size);
+ ostream.write(parcel);
+ }
+
+ /**
+ * Check byte-to-byte equality between this and the
+ * other parcels.
+ */
+ public boolean equals(Parcel other) {
+ if (this.parcel.length != other.parcel.length)
+ return false;
+ int size = parcel.length;
+ for (int i = 0; i < size; i++)
+ if (this.parcel[i] != other.parcel[i])
+ return false;
+ return true;
+ }
+
+ }
+
+ /**
+ * Server or Client may throw this exception to report the test failure.
+ */
+ static class TestFailure extends RuntimeException {
+ /**
+ * Report particular purpose of the test failure.
+ */
+ public TestFailure(String purpose) {
+ super(purpose);
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network003.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network003.java
new file mode 100644
index 00000000000..b3e44838ef2
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network003.java
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/network/network003.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test transfers huge amount of data between one server and multiple
+ * clients communicating via TCP/IP sockets, and checks if those data are
+ * transfered correctly. All TCP/IP sockets are attached to local host
+ * (by its domain name), or to the ``localhost'' loopback (having the IP
+ * address 127.0.0.1).
+ * In this test, 128 client/server connections are established. Once a
+ * connection is established, client passes a large data parcel to server,
+ * and server reads that parcel and checks if it is same as expected
+ * (byte-to-byte equality is desired). Then server passes (some other) parcel
+ * to the client, and client reads and verifies those bytes. This ping-pong
+ * game is repeated 128 times; and after that each pair of sockets checks if
+ * there are no extra bytes accudentally passed through their connection.
+ * Parcels lengths and contents are chosen randomly, and average parcel
+ * length is 128 bytes. So totally, each pair of sockets passes ~16Kb of
+ * data to each other, and thus ~32Kb of data are transfered by each sockets
+ * pair. Totally, ~4Mb of data are transfered by all client/server pairs.
+ * COMMENTS
+ * The production Solaris_JDK_1.3-b12 Server VM crashes under this test:
+ * #
+ * # HotSpot Virtual Machine Error, Unexpected Signal 10
+ * # Please report this error at
+ * # http://java.sun.com/cgi-bin/bugreport.cgi
+ * #
+ * # Error ID: 4F533F534F4C415249530E43505007D9 01
+ * #
+ * # Problematic Thread: prio=5 tid=0x214418 nid=0x103 runnable
+ * #
+ * (ErrorID == "os_solaris.cpp, 2009")
+ *
+ * @run main/othervm nsk.stress.network.network003
+ */
+
+package nsk.stress.network;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Random;
+
+/**
+ * This test transfers huge amount of data between one server and multiple
+ * clients communicating via TCP/IP sockets, and checks if those data are
+ * transfered correctly. All TCP/IP sockets are attached to local host
+ * (by its domain name), or to the ``localhost'' loopback (having the IP
+ * address 127.0.0.1).
+ * System.out.
+ */
+ static private PrintStream out = System.out;
+
+ /**
+ * Print error message: all clients and servers may print concurently.
+ */
+ static private synchronized void println(Object message) {
+ out.println(message.toString());
+ }
+
+ /**
+ * Display optional report: comment ca va.
+ */
+ static private void display(Object report) {
+ if (DEBUG_MODE)
+ println(report.toString());
+ }
+
+ /**
+ * Maximal number of connections this test should open simultaneously.
+ */
+ private final static int MAX_CONNECTIONS = 128;
+
+ /**
+ * Check few more connections to make sure that MAX_CONNECTIONS are safe.
+ */
+ private final static int CONNECTIONS_RESERVE = 10;
+
+ /**
+ * Number of client/server connections to establish.
+ */
+ private static final int CONNECTIONS = detectOSLimitation();
+
+ /**
+ * Number of parcels to be sent/recieved.
+ */
+ private static final int DATA_PARCELS = 128;
+
+ /**
+ * Maximal length of data parcel to be sent/recieved
+ * (it equals to 256 bytes now).
+ */
+ private static final int MAX_PARCEL = 1 << 8;
+
+ /**
+ * How many IP sockets can we open simultaneously?
+ * Check if MAX_CONNECTIONS connections
+ * can be open simultaneously.
+ */
+ private static int detectOSLimitation() {
+ final int CONNECTIONS_TO_TRY = MAX_CONNECTIONS + CONNECTIONS_RESERVE;
+ ServerSocket ssoc[] = new ServerSocket[CONNECTIONS_TO_TRY];
+ display("--- Trying to open " + CONNECTIONS_TO_TRY + " connections:");
+ int i;
+ for (i = 0; i < CONNECTIONS_TO_TRY; i++)
+ try {
+ ssoc[i] = new ServerSocket(0);
+ display("--- Open: ssoc[" + i + "] = " + ssoc[i]);
+ } catch (IOException ioe) {
+ display("--- OOPS! -- failed to open connection #" + i);
+ break;
+ }
+ display("--- Could open " +
+ (i < CONNECTIONS_TO_TRY ? "only " : "") + i + " connections.");
+ display("--- Closing them:");
+ for (int j = 0; j < i; j++)
+ try {
+ ssoc[j].close();
+ } catch (IOException ioe) {
+ throw new Error("FATAL error while loading the test: " + ioe);
+ }
+ display("--- OK.");
+ int safeConnections = i - CONNECTIONS_RESERVE;
+ if (safeConnections < 1)
+ safeConnections = 1;
+ if (safeConnections < MAX_CONNECTIONS) {
+ println("# ------------------------- CAUTION: -------------------");
+ println("# While checking the OS limitations, the test found that");
+ println("# only " + i + " TCP/IP socket connections could be safely open");
+ println("# simultaneously. However, possibility to open at least");
+ println("# " + MAX_CONNECTIONS + "+" + CONNECTIONS_RESERVE
+ + " connections were expected.");
+ println("# ");
+ println("# So, the test will check only " + safeConnections + " connection"
+ + (safeConnections == 1 ? "" : "s") + " which seem");
+ println("# safe to be open simultaneously.");
+ println("# ------------------------------------------------------");
+ }
+ return safeConnections;
+ }
+
+ /**
+ * Server thread intended to reply to data parcels sent by Client thread.
+ */
+ static private class Server extends Thread {
+ /**
+ * This server thread listens the single socket.
+ */
+ private ServerSocket serverSocket;
+
+ /**
+ * Address and port of this server socket.
+ */
+ public String toString() {
+ return serverSocket.toString();
+ }
+
+ /**
+ * Did the thread failed? If yes, what is the failure's reason.
+ */
+ Exception exception = null;
+
+ /**
+ * What is the port number this socket is listening for?
+ */
+ int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ /**
+ * Find some free port at the given address
+ * and attach new server to hear that port.
+ */
+ Server(InetAddress address) throws IOException {
+ int someFreePort = 0;
+ int backlog = 50; // default for new ServerSocket(port)
+ serverSocket = new ServerSocket(someFreePort, backlog, address);
+ }
+
+ /**
+ * Accept connection, then read/respond DATA_PARCELS parcels
+ * of random data. Set initial seed for pseudo-random numbers generator
+ * to the value of the local port number.
+ *
+ * @see #DATA_PARCELS
+ * @see #getPort()
+ */
+ public void run() {
+ try {
+ Socket socket = serverSocket.accept();
+ display("Server socket: " + socket);
+
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(getPort());
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ println("Server thread for port #"
+ + getPort() + " got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "server has read unexpected parcel");
+ }
+
+ etalon.send(ostream);
+ ostream.flush();
+ }
+
+ int datum = istream.read(); // wait for client close()
+ if (datum >= 0)
+ throw new TestFailure(
+ "server has read ambigous byte: " + datum);
+
+ ostream.close(); // implies: socket.close();
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ }
+
+ /**
+ * Client thread intended to send data parcels to Server thread and
+ * to recieve the server's replies.
+ */
+ static private class Client extends Thread {
+ /**
+ * This thread uses the single client socket.
+ */
+ private Socket socket;
+
+ /**
+ * Address and port of this socket.
+ */
+ public String toString() {
+ return socket.toString();
+ }
+
+ /**
+ * Did the thread failed? If yes, what is the failure's reason.
+ */
+ Exception exception = null;
+
+ /**
+ * Connect client socket on the given address
+ * and port.
+ */
+ Client(InetAddress address, int port) throws IOException {
+ socket = new Socket(address, port);
+ }
+
+ /**
+ * What is the port number this socket is listening for?
+ */
+ int getPort() {
+ return socket.getPort();
+ }
+
+
+ /**
+ * Establish connection, then read/respond DATA_PARCELS parcels
+ * of random data. Set initial seed for pseudo-random numbers generator
+ * to the value of the local port number.
+ *
+ * @see #DATA_PARCELS
+ * @see #getPort()
+ */
+ public void run() {
+ try {
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(getPort());
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+ etalon.send(ostream);
+ ostream.flush();
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ println("Client thread for port #"
+ + getPort() + " got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "parcel context is unexpected to client");
+ }
+ }
+
+ if (istream.available() > 0) {
+ int datum = istream.read();
+ throw new TestFailure(
+ "client has read ambigous byte: " + datum);
+ }
+ ostream.close(); // implies: socket.close()
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ }
+
+ /**
+ * A data parcel to sent/recieved between Client and Server threads.
+ * When data parcel is sent, first 4 bytes transfered encode the size
+ * of the parcel (i.e.: number of data bytes in the parcel's contents).
+ * Then the parcel's contents bytes are transered.
+ */
+ static class Parcel {
+ private byte[] parcel;
+
+ /**
+ * Display all bytes as integer values from 0 to 255;
+ * or return ``null'' if this Parcel is not
+ * yet initialized.
+ */
+ public String toString() {
+ if (parcel == null)
+ return "null";
+ String s = "{";
+ for (int i = 0; i < parcel.length; i++)
+ s += (i > 0 ? ", " : "") + ((int) parcel[i] & 0xFF);
+ return s + "}";
+ }
+
+ /**
+ * Generate new parcel[] array using the given
+ * random numbers generator. Client and Server
+ * threads should use identical random generators,
+ * so that those threads could generate equal data parcels and
+ * check the parcel just transfered.
+ */
+ public Parcel(Random random) {
+ int size = random.nextInt(MAX_PARCEL) + 1;
+ parcel = new byte[size];
+ for (int i = 0; i < size; i++)
+ parcel[i] = (byte) random.nextInt(256);
+ }
+
+ /**
+ * Read exactly size bytes from the istream
+ * if possible, or throw TestFailure if unexpected end of
+ * istream occurs.
+ */
+ private static byte[] readBytes(int size, InputStream istream)
+ throws IOException {
+
+ byte data[] = new byte[size];
+ for (int i = 0; i < size; i++) {
+ int datum = istream.read();
+ if (datum < 0)
+ throw new TestFailure(
+ "unexpected EOF: have read: " + i + " bytes of " + size);
+ data[i] = (byte) datum;
+ }
+ return data;
+ }
+
+ /**
+ * Read 4 bytes from istream and threat them to encode
+ * size of data parcel following these 4 bytes.
+ */
+ private static int getSize(InputStream istream) throws IOException {
+ byte data[] = readBytes(4, istream);
+ int data0 = (int) data[0] & 0xFF;
+ int data1 = (int) data[1] & 0xFF;
+ int data2 = (int) data[2] & 0xFF;
+ int data3 = (int) data[3] & 0xFF;
+ int sizeWord = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
+ int size = sizeWord + 1;
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+ return size;
+ }
+
+ /**
+ * Send 4 bytes encoding actual size of the parcel just to be transfered.
+ */
+ private static void putSize(OutputStream ostream, int size)
+ throws IOException {
+
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+
+ int sizeWord = size - 1;
+ byte data[] = new byte[4];
+ data[0] = (byte) sizeWord;
+ data[1] = (byte) (sizeWord >> 8);
+ data[2] = (byte) (sizeWord >> 16);
+ data[3] = (byte) (sizeWord >> 24);
+ ostream.write(data);
+ }
+
+ /**
+ * Recieve data parcel.
+ */
+ public Parcel(InputStream istream) throws IOException {
+ int size = getSize(istream);
+ parcel = readBytes(size, istream);
+ }
+
+ /**
+ * Send this data parcel.
+ */
+ public void send(OutputStream ostream) throws IOException {
+ int size = parcel.length;
+ putSize(ostream, size);
+ ostream.write(parcel);
+ }
+
+ /**
+ * Check byte-to-byte equality between this and the
+ * other parcels.
+ */
+ public boolean equals(Parcel other) {
+ if (this.parcel.length != other.parcel.length)
+ return false;
+ int size = parcel.length;
+ for (int i = 0; i < size; i++)
+ if (this.parcel[i] != other.parcel[i])
+ return false;
+ return true;
+ }
+
+ }
+
+ /**
+ * Server or Client thread may throw this exception to report the test
+ * failure.
+ */
+ static class TestFailure extends RuntimeException {
+ /**
+ * Report particular purpose of the test failure.
+ */
+ public TestFailure(String purpose) {
+ super(purpose);
+ }
+
+ }
+
+ /**
+ * Attach client and server sockets to the local host, and check if
+ * huge amount of data could be correctly transfered between these
+ * sockets.
+ * args[] may
+ * prompt the local host IP address or domain name. Execute:
+ *
+ * java network003 [IP-address | host_name |
+ * localhost ]
+ *
where parameters are:
+ *
+ * IP-address - local hots's address, or 127.0.0.1
+ *
+ * host_name - local host's domain name, or the
+ * keyword ``localhost''
+ *
+ * localhost - placeholder for the IP-address 127.0.0.1
+ *
By default, the test uses the Internet address available via
+ * the method InetAddress.getLocalHost()
+ */
+ public static int run(String args[], PrintStream out) {
+ network003.out = out;
+
+ //
+ // Get IP address of the local machine.
+ //
+
+ InetAddress address = null;
+ try {
+ switch (args.length) {
+ case 0:
+ address = InetAddress.getLocalHost();
+ break;
+ case 1:
+ String hostName = args[0];
+ address = InetAddress.getByName(args[0]);
+ break;
+ default:
+ println("Use:");
+ println(" java network003");
+ println("or:");
+ println(" java network003 ${IP_ADDRESS}");
+ println("or:");
+ println(" java network003 ${HOST_NAME}");
+ println("or:");
+ println(" java network003 localhost");
+ return 2; // FAILED
+ }
+ } catch (UnknownHostException exception) {
+ println(exception);
+ return 2; // FAILED
+ }
+ display("Host: " + address);
+
+ //
+ // Incarnate the server & the client sockets.
+ //
+
+ Server server[] = new Server[CONNECTIONS];
+ Client client[] = new Client[CONNECTIONS];
+
+ for (int i = 0; i < CONNECTIONS; i++) {
+ try {
+ server[i] = new Server(address);
+ } catch (IOException io) {
+ println("Failed to create server #" + i + ": " + io);
+ return 2;
+ }
+ display("Server #" + i + ": " + server[i]);
+ }
+
+ for (int i = 0; i < CONNECTIONS; i++) {
+ int port = server[i].getPort();
+ try {
+ client[i] = new Client(address, port);
+ } catch (IOException io) {
+ out.println("Failed to create client #" + i + ": " + io);
+ return 2;
+ }
+ display("Client socket #" + i + ": " + client[i]);
+ }
+
+ //
+ // Execute the server and client threads.
+ //
+
+ Exception exception = null;
+ try {
+ for (int i = 0; i < CONNECTIONS; i++)
+ server[i].start();
+ for (int i = 0; i < CONNECTIONS; i++)
+ client[i].start();
+ boolean someIsAlive = true;
+ while (someIsAlive) {
+ boolean aliveFound = false;
+ boolean someBroken = false;
+ for (int i = 0; i < CONNECTIONS; i++)
+ if (client[i].isAlive() || server[i].isAlive()) {
+ if ((client[i].exception != null) ||
+ (server[i].exception != null))
+ someBroken = true;
+ aliveFound = true;
+ Thread.yield();
+ }
+ someIsAlive = aliveFound;
+ if (someBroken)
+ break;
+ }
+ } catch (TestFailure failure) {
+ exception = failure;
+ }
+
+ // Failure diagnostics, if needed.
+
+ Exception problem[] = new Exception[2 * CONNECTIONS + 1];
+ problem[0] = exception;
+ for (int i = 0; i < CONNECTIONS; i++) {
+ problem[2 * i + 1] = server[i].exception;
+ problem[2 * i + 2] = client[i].exception;
+ }
+
+ int exitCode = 0;
+
+ for (int i = 0; i < 2 * CONNECTIONS + 1; i++)
+ if (problem[i] != null) {
+ out.println("#### OOPS ! ####");
+ problem[i].printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0) {
+ out.println("#### OOPS ! ####");
+ out.println("# Test failed.");
+ return 2; // FAILED
+ }
+ display("Test passed.");
+ return 0; // PASSED
+ }
+
+ /**
+ * Re-calls to the method run(args[],out) actually
+ * performing the test; and stop with exit code 95 if the test
+ * has passed, or with code 97 if the test has failed.
+ * (This is JCK-like exit codes convention.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit code.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network004.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network004.java
new file mode 100644
index 00000000000..340bb49e8b3
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network004.java
@@ -0,0 +1,878 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/network/network004.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test transfers huge amount of data between 2 Java virtual machines
+ * using the TCP/IP protocol, and checks if those data are transfered correctly.
+ * Both client and server VMs run on the same local computer and attach TCP/IP
+ * sockets to the local host, or to the loopback domain ``localhost''
+ * (having IP address 127.0.0.1).
+ * In this test, 128 client/server connections are established. Once a
+ * connection is established, client passes a large data parcel to server,
+ * and server reads that parcel and checks if it is same as expected
+ * (byte-to-byte equality is desired). Then server passes (some other) parcel
+ * to the client, and client reads and verifies those bytes. This ping-pong
+ * game is repeated 128 times; and after that each pair of sockets checks if
+ * there are no extra bytes accudentally passed through their connection.
+ * Parcels lengths and contents are chosen randomly, and average
+ * parcel length is 128 bytes. So totally, each pair of sockets passes ~16Kb of
+ * data to each other, and thus ~32Kb of data are transfered by each sockets
+ * pair. Totally, ~4Mb of data are transfered by all client/server pairs.
+ * COMMENTS
+ * The production Solaris_JDK_1.3-b12 Server VM intermittently crashes under
+ * this test, even when client part of the test is executed with Client HS:
+ * >>>> java -server network004 java
+ * #
+ * # HotSpot Virtual Machine Error, Unexpected Signal 10
+ * # Please report this error at
+ * # http://java.sun.com/cgi-bin/bugreport.cgi
+ * #
+ * # Error ID: 4F533F534F4C415249530E43505007D9 01
+ * #
+ * # Problematic Thread: prio=5 tid=0x214418 nid=0x103 runnable
+ * #
+ * (ErrorID == "os_solaris.cpp, 2009")
+ * If the client part of the test is executed with Server HS, the
+ * production Solaris_JDK_1.3-b12 Server VM intermittently fails
+ * this test due to timeout:
+ * >>>> time java -server network004 'java -server -showversion'
+ * java version "1.3"
+ * Java(TM) 2 Runtime Environment, Standard Edition (build Solaris_JDK_1.3-b12)
+ * Java HotSpot(TM) Server VM (build 1.3-b12, mixed mode)
+ * # Client #96: java.io.InterruptedIOException: Read timed out
+ * # Client VM has crashed: exit status=97
+ * # Test failed.
+ * 156.0u 117.0s 7:06 63% 0+0k 0+0io 0pf+0w
+ * Test was fixed:
+ * added WAITTIME parameter defined timeout for TCP/IP sockets in minutes
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.stress.network.network004
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.stress.network.network004
+ * "${test.jdk}/bin/java ${test.vm.opts} ${test.java.opts}" 5
+ */
+
+package nsk.stress.network;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Random;
+import java.util.StringTokenizer;
+
+/**
+ * This test transfers huge amount of data between 2 Java virtual machines
+ * using the TCP/IP protocol, and checks if those data are transfered correctly.
+ * Both client and server VMs run on the same local computer and attach TCP/IP
+ * sockets to the local host, or to the loopback domain ``localhost''
+ * (having IP address 127.0.0.1).
+ * MAX_CONNECTIONS connections
+ * can be open simultaneously.
+ */
+ private static int detectOSLimitation() {
+ final int CONNECTIONS_TO_TRY = MAX_CONNECTIONS + CONNECTIONS_RESERVE;
+ ServerSocket ssoc[] = new ServerSocket[CONNECTIONS_TO_TRY];
+ display("--- Trying to open " + CONNECTIONS_TO_TRY + " connections:");
+ int i;
+ for (i = 0; i < CONNECTIONS_TO_TRY; i++)
+ try {
+ ssoc[i] = new ServerSocket(0);
+ display("--- Open: ssoc[" + i + "] = " + ssoc[i]);
+ } catch (IOException ioe) {
+ display("--- OOPS! -- failed to open connection #" + i);
+ break;
+ }
+ display("--- Could open " +
+ (i < CONNECTIONS_TO_TRY ? "only " : "") + i + " connections.");
+ display("--- Closing them:");
+ for (int j = 0; j < i; j++)
+ try {
+ ssoc[j].close();
+ } catch (IOException ioe) {
+ throw new Error("FATAL error while loading the test: " + ioe);
+ }
+ display("--- OK.");
+ int safeConnections = i - CONNECTIONS_RESERVE;
+ if (safeConnections < 1)
+ safeConnections = 1;
+ if (safeConnections < MAX_CONNECTIONS) {
+ complain("------------------------- CAUTION: -------------------");
+ complain("While checking the OS limitations, the test found that");
+ complain("only " + i + " TCP/IP socket connections could be safely open");
+ complain("simultaneously. However, possibility to open at least");
+ complain("" + MAX_CONNECTIONS + "+" + CONNECTIONS_RESERVE
+ + " connections were expected.");
+ complain("");
+ complain("So, the test will check only " + safeConnections + " connection"
+ + (safeConnections == 1 ? "" : "s") + " which seem");
+ complain("safe to be open simultaneously.");
+ complain("------------------------------------------------------");
+ }
+ return safeConnections;
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Re-calls to the method run(args[],out) actually
+ * performing the test. After run(args[],out) stops,
+ * follow JDK-like convention for exit codes. I.e.: stop with
+ * exit status 95 if the test has passed, or with status 97 if
+ * the test has failed.
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+ /**
+ * Parse command-line parameters stored into args[] array,
+ * then perform the test. I.e.: start the server thread at the same VM
+ * this method runs, then start the other client VM, and verify data
+ * transfer through TCP/IP connection between those different virtual
+ * machines.
+ *
+ * java network004 java_command
+ * [IP-address | host_name | localhost ]
+ *
where parameters are:
+ *
+ * java_command - how to start java,
+ * e.g.: ``c:\jdk1.3\bin\java -classic''
+ *
+ * waittime - timeout for TCP/IP sockets in minutes
+ *
+ * IP-address - local hots's address, or 127.0.0.1
+ *
+ * host_name - local host's domain name, or the
+ * keyword ``localhost''
+ *
+ * localhost - placeholder for the IP-address 127.0.0.1
+ * java_command should point to the same
+ * Java machine just executing this test. However, every compatible Java 2
+ * implementation is appropriate.
+ * InetAddress.getLocalHost() to get the domain name and
+ * IP-address of the local computer.
+ */
+ public static int run(String args[], PrintStream out) {
+ network004.out = out;
+
+ //
+ // Get the Internet address of the local machine.
+ //
+ InetAddress address = null;
+ try {
+ switch (args.length) {
+ case 2:
+ address = InetAddress.getLocalHost();
+ break;
+ case 3:
+ address = InetAddress.getByName(args[2]);
+ break;
+ default:
+ complain("Illegal arguments number; execute:");
+ complain(" java network004 $JAVA_COMMAND " +
+ "[$IP_ADDRESS | $HOST_NAME | localhost]");
+ return 2; // FAILED
+ }
+ } catch (UnknownHostException exception) {
+ complain(exception.toString());
+ return 2; // FAILED
+ }
+ display("Host: " + address);
+
+ //
+ // Detect if it is safe to open MAX_CONNETIONS simultaneously:
+ //
+ final int CONNECTIONS = detectOSLimitation();
+
+ //
+ // Start the server thread on the same VM (which executes this method).
+ //
+ Server server[] = new Server[CONNECTIONS];
+ for (int i = 0; i < CONNECTIONS; i++) {
+ try {
+ server[i] = new Server(address);
+ } catch (Exception exception) {
+ complain("Server #" + i + ": " + exception);
+ return 2;
+ }
+ display("Server #" + i + ": " + server[i]);
+ server[i].start();
+ }
+
+ //
+ // Start the client process on different VM.
+ //
+ String command = args[0] + " " + network004.class.getName() + "$Client";
+ try {
+ SO_TIMEOUT = Integer.parseInt(args[1]) * 60 * 1000;
+ } catch (NumberFormatException e) {
+ complain("Wrong timeout argument: " + e);
+ return 2;
+ }
+
+ Runtime runtime = Runtime.getRuntime();
+
+ Process client = null;
+ IORedirector redirectOut = null;
+ IORedirector redirectErr = null;
+
+ try {
+ // Start clients on different JVM:
+ client = runtime.exec(command);
+
+ // Provide clients with access to stderr and stdout:
+ InputStream clientOut = client.getInputStream();
+ InputStream clientErr = client.getErrorStream();
+ redirectOut = new IORedirector(clientOut, DEBUG_MODE ? out : null);
+ redirectErr = new IORedirector(clientErr, out);
+ redirectOut.start();
+ redirectErr.start();
+
+ // Pass parameters to clients (number of connections, and IP adresses and ports):
+ PrintStream clientIn = new PrintStream(client.getOutputStream());
+ clientIn.println(CONNECTIONS);
+ for (int i = 0; i < CONNECTIONS; i++)
+ clientIn.println(server[i].getIPAddress() + " " + server[i].getPort());
+ clientIn.flush();
+ clientIn.close();
+
+ } catch (Exception exception) {
+ complain("Failed to start client: " + exception);
+ return 2;
+ }
+
+ //
+ // Wait until the server and client both stop.
+ //
+ boolean testFailed = false;
+ try {
+ client.waitFor();
+ // Let I/O redirectors to flush:
+ if (redirectOut.isAlive())
+ redirectOut.join();
+ if (redirectErr.isAlive())
+ redirectErr.join();
+
+ // If client has crashed, also terminate the server (to avoid hangup).
+ int clientStatus = client.exitValue();
+ if (clientStatus != 95) {
+ complain("Client VM has failed: exit status=" + clientStatus);
+ testFailed = true;
+ }
+
+ // Client has finished OK; wait for the server.
+ for (int i = 0; i < CONNECTIONS; i++) {
+ display("Server: waiting for #" + i);
+ while (server[i].isAlive())
+ server[i].join();
+ if (server[i].exception != null) {
+ complain("Server thread #" + i + ": " + server[i].exception);
+ testFailed = true;
+ }
+ }
+
+ } catch (Exception exception) {
+ complain("Test interrupted: " + exception);
+ testFailed = true;
+ }
+
+ if (testFailed)
+ complain("Test failed.");
+ else
+ display("Test passed.");
+ return testFailed ? 2 : 0;
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Log stream for error messages and/or (optional) execution trace.
+ */
+ private static PrintStream out;
+
+ /**
+ * Print error message.
+ */
+ private static synchronized void complain(Object message) {
+ out.println("# " + message);
+ out.flush();
+ }
+
+ /**
+ * Display optional report: comment ca va?
+ */
+ private static synchronized void display(Object report) {
+ if (DEBUG_MODE)
+ out.println(report.toString());
+ out.flush();
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Server thread should reply to data parcels sent by Client VM.
+ */
+ private static class Server extends Thread {
+ /**
+ * The socket to listen for a client.
+ */
+ private ServerSocket serverSocket;
+
+ /**
+ * Display the server socket.
+ */
+ public String toString() {
+ return serverSocket.toString();
+ }
+
+ /**
+ * Server's IP-address in the form ``x.y.u.z'',
+ * or ``127.0.0.1'' for loopback connection.
+ */
+ public String getIPAddress() {
+ return serverSocket.getInetAddress().getHostAddress();
+ }
+
+ /**
+ * Which port is this socket listening?
+ */
+ int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ /**
+ * Find some free port at the given address
+ * and attach new server to hear that port.
+ */
+ public Server(InetAddress address) throws IOException {
+ int someFreePort = 0;
+ int backlog = 50; // default for new ServerSocket(port)
+ serverSocket = new ServerSocket(someFreePort, backlog, address);
+ }
+
+ /**
+ * Exception just arisen while the server was working,
+ * or null if it was OK with the server.
+ */
+ Exception exception = null;
+
+ /**
+ * Accept connection, then reply to client's parcels.
+ */
+ public void run() {
+ try {
+ Socket socket = serverSocket.accept();
+ socket.setSoTimeout(SO_TIMEOUT);
+// display("Server: " + socket);
+
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(getPort());
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ complain("Server thread for port #"
+ + getPort() + " got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "server has read unexpected parcel");
+ }
+
+ etalon.send(ostream);
+ ostream.flush();
+ }
+
+ int datum = istream.read(); // wait for client close()
+ if (datum >= 0)
+ throw new TestFailure(
+ "server has read ambigous byte: " + datum);
+
+ ostream.close(); // implies: socket.close();
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Client VM should send data parcels to Server VM and
+ * recieve and verify the server's replies.
+ */
+ private static class Client extends Thread {
+ /**
+ * This thread uses the single client socket.
+ */
+ private Socket socket;
+
+ /**
+ * Address and port of this socket.
+ */
+ public String toString() {
+ return socket.toString();
+ }
+
+ /**
+ * Did the thread failed? If yes, what is the failure's reason.
+ */
+ Exception exception = null;
+
+ /**
+ * Connect client socket on the given address
+ * and port.
+ */
+ Client(InetAddress address, int port) throws IOException {
+ socket = new Socket(address, port);
+ socket.setSoTimeout(SO_TIMEOUT);
+ }
+
+ /**
+ * What is the port number this socket is listening for?
+ */
+ int getPort() {
+ return socket.getPort();
+ }
+
+ /**
+ * Establish connection, then read/respond DATA_PARCELS parcels
+ * of random data. Set initial seed for pseudo-random numbers generator
+ * to the value of the local port number.
+ *
+ * @see #DATA_PARCELS
+ * @see #getPort()
+ */
+ public void run() {
+ try {
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(getPort());
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+ etalon.send(ostream);
+ ostream.flush();
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ complain("Client thread for port #"
+ + getPort() + " got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "parcel context is unexpected to client");
+ }
+ }
+
+ if (istream.available() > 0) {
+ int datum = istream.read();
+ throw new TestFailure(
+ "client has read ambigous byte: " + datum);
+ }
+ ostream.close(); // implies: socket.close()
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ /**
+ * Establish connections to lots of server sockets, atack servers with
+ * huge data parcels, and check if it replies correctly. The addresses
+ * and port numbers for server sockets are passed through stdin.
+ * The input stream must consist of the stipulated number (up to 128+1) of
+ * lines containing the pair of symbolic server domain name and the port number,
+ * like:
+ *
actual_number_of_sockets
+ *
address_1 port_1
+ *
address_2 port_2
+ *
. . .
+ *
address_N port_N
+ *
where N must equal to the actual_number_of_sockets.
+ */
+ public static void main(String args[]) {
+ // ---- Parse stdin for the list of server sockets: ---- //
+ BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+
+ final int CONNECTIONS;
+ try {
+ String line = in.readLine();
+ if (line == null) {
+ complain("Client expects paramenets passed through stdin:");
+ complain(" actual_number_of_sockets");
+ complain(" IP-address_1 port_1");
+ complain(" IP-address_2 port_2");
+ complain(" . . .");
+ complain(" IP-address_N port_N");
+ exit(2); // FAILED
+ }
+ CONNECTIONS = Integer.parseInt(line);
+ } catch (IOException ioe) {
+ complain("Client failed to read the actual number of CONNECTIONS");
+ throw new RuntimeException(ioe.toString());
+ }
+
+ Client client[] = new Client[CONNECTIONS];
+ for (int i = 0; i < CONNECTIONS; i++)
+ try {
+ String line = in.readLine();
+ if (line == null) {
+ complain("Client: failed to read address/port for client #" + i);
+ exit(3);
+ }
+
+ StringTokenizer tokenz = new StringTokenizer(line);
+ if (tokenz.countTokens() != 2) {
+ complain("Client: illegal input string: " + line);
+ exit(3);
+ }
+ String serverName = (String) tokenz.nextElement();
+ InetAddress address = InetAddress.getByName(serverName);
+ int port = Integer.parseInt((String) tokenz.nextElement());
+
+ client[i] = new Client(address, port);
+
+ display("Client #" + i + ": " + client[i]);
+
+ } catch (IOException ioe) {
+ complain("Client #" + i + ": " + ioe);
+ exit(3);
+ }
+
+ // ---- Start testing: ---- //
+
+ for (int i = 0; i < CONNECTIONS; i++)
+ client[i].start();
+
+ int status = 0;
+ for (int i = 0; i < CONNECTIONS; i++) {
+ display("Client: waiting for #" + i);
+ while (client[i].isAlive())
+ yield();
+ if (client[i].exception != null) {
+ complain("Client #" + i + ": " + client[i].exception);
+ status = 2;
+ }
+ }
+
+ exit(status);
+ }
+
+ /**
+ * Print error message.
+ */
+ private static synchronized void complain(Object message) {
+ System.err.println("# " + message);
+ System.err.flush();
+ }
+
+ /**
+ * Display execution trace.
+ */
+ private static synchronized void display(Object message) {
+ if (!DEBUG_MODE)
+ return;
+ System.out.println(message.toString());
+ System.out.flush();
+ }
+
+ /**
+ * Exit with JCK-like status.
+ */
+ private static void exit(int exitCode) {
+ System.exit(exitCode + 95);
+ }
+
+ }
+
+ /**
+ * Two of such threads should redirect out and err
+ * streams of client VM.
+ */
+ private static class IORedirector extends Thread {
+ /**
+ * Source stream.
+ */
+ InputStream in;
+ /**
+ * Destination stream.
+ */
+ OutputStream out;
+
+ /**
+ * Redirect in to out.
+ */
+ public IORedirector(InputStream in, OutputStream out) {
+ this.in = in;
+ this.out = out;
+ }
+
+ /**
+ * Read input stream until the EOF, and write everithing to output stream.
+ * If output stream is assigned to null, do not print anything,
+ * but read the input stream anywhere.
+ */
+ public void run() {
+ try {
+ for (; ; ) {
+ int symbol = in.read();
+ if (symbol < 0)
+ break; // EOF
+ if (out != null)
+ out.write(symbol);
+ }
+
+ if (out != null)
+ out.flush();
+
+ } catch (Exception exception) {
+ throw new TestFailure("IORedirector exception: " + exception);
+ }
+ }
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * A data parcel to be sent/recieved between Client VM and Server thread.
+ * When data parcel is sent, first 4 bytes are transfered which encode the
+ * int number equal to size of the parcel minus 1. I.e.: if
+ * number of data bytes in the parcel's contents is N, then
+ * the first 4 bytes encode the number N-1. After that, the
+ * parcel's contents bytes are transered.
+ */
+ static class Parcel {
+ private byte[] parcel;
+
+ /**
+ * Display all bytes as integer values from 0 to 255;
+ * or return ``null'' if this Parcel is not
+ * yet initialized.
+ */
+ public String toString() {
+ if (parcel == null)
+ return "null";
+ String s = "{";
+ for (int i = 0; i < parcel.length; i++)
+ s += (i > 0 ? ", " : "") + ((int) parcel[i] & 0xFF);
+ return s + "}";
+ }
+
+ /**
+ * Generate new parcel[] array using the given
+ * random numbers generator. Client and Server
+ * threads should use identical random generators,
+ * so that those threads could generate equal data parcels and
+ * check the parcel just transfered.
+ */
+ public Parcel(Random random) {
+ int size = random.nextInt(MAX_PARCEL) + 1;
+ parcel = new byte[size];
+ for (int i = 0; i < size; i++)
+ parcel[i] = (byte) random.nextInt(256);
+ }
+
+ /**
+ * Read exactly size bytes from the istream
+ * if possible, or throw TestFailure if unexpected end of
+ * istream occurs.
+ */
+ private static byte[] readBytes(int size, InputStream istream)
+ throws IOException {
+
+ byte data[] = new byte[size];
+ for (int i = 0; i < size; i++) {
+ int datum = istream.read();
+ if (datum < 0)
+ throw new TestFailure(
+ "unexpected EOF: have read: " + i + " bytes of " + size);
+ data[i] = (byte) datum;
+ }
+ return data;
+ }
+
+ /**
+ * Read 4 bytes from istream and threat them to encode
+ * size of data parcel following these 4 bytes.
+ */
+ private static int getSize(InputStream istream) throws IOException {
+ byte data[] = readBytes(4, istream);
+ int data0 = (int) data[0] & 0xFF;
+ int data1 = (int) data[1] & 0xFF;
+ int data2 = (int) data[2] & 0xFF;
+ int data3 = (int) data[3] & 0xFF;
+ int sizeWord = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
+ int size = sizeWord + 1;
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+ return size;
+ }
+
+ /**
+ * Send 4 bytes encoding actual size of the parcel just to be transfered.
+ */
+ private static void putSize(OutputStream ostream, int size)
+ throws IOException {
+
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+
+ int sizeWord = size - 1;
+ byte data[] = new byte[4];
+ data[0] = (byte) sizeWord;
+ data[1] = (byte) (sizeWord >> 8);
+ data[2] = (byte) (sizeWord >> 16);
+ data[3] = (byte) (sizeWord >> 24);
+ ostream.write(data);
+ }
+
+ /**
+ * Recieve data parcel.
+ */
+ public Parcel(InputStream istream) throws IOException {
+ int size = getSize(istream);
+ parcel = readBytes(size, istream);
+ }
+
+ /**
+ * Send this data parcel.
+ */
+ public void send(OutputStream ostream) throws IOException {
+ int size = parcel.length;
+ putSize(ostream, size);
+ ostream.write(parcel);
+ }
+
+ /**
+ * Check byte-to-byte equality between this and the
+ * other parcels.
+ */
+ public boolean equals(Parcel other) {
+ if (this.parcel.length != other.parcel.length)
+ return false;
+ int size = parcel.length;
+ for (int i = 0; i < size; i++)
+ if (this.parcel[i] != other.parcel[i])
+ return false;
+ return true;
+ }
+
+ }
+
+ /**
+ * Server or Client may throw this exception to report the test failure.
+ */
+ static class TestFailure extends RuntimeException {
+ /**
+ * Report particular purpose of the test failure.
+ */
+ public TestFailure(String purpose) {
+ super(purpose);
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network005.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network005.java
new file mode 100644
index 00000000000..013b8311f3e
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network005.java
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/network/network005.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test make huge number of data transers between one server and
+ * multiple clients communicating via TCP/IP sockets, and checks if those
+ * data are transfered correctly. All TCP/IP sockets are attached to local
+ * host (by its domain name), or to the ``localhost'' loopback (having the
+ * IP address 127.0.0.1).
+ * In this test, 128 client/server connections are established. Once a
+ * connection is established, client passes a large data parcel to server,
+ * and server reads that parcel and checks if it is same as expected
+ * (byte-to-byte equality is desired). Then server passes (some other) parcel
+ * to the client, and client reads and verifies those bytes. This ping-pong
+ * game is repeated 128 times; and after that each pair of sockets checks if
+ * there are no extra bytes accudentally passed through their connection.
+ * Parcels lengths and contents are chosen randomly, and average parcel
+ * length is 128 bytes. So totally, each pair of sockets passes ~16Kb of
+ * data to each other, and thus ~32Kb of data are transfered by each sockets
+ * pair. Totally, ~4Mb of data are transfered by all client/server pairs.
+ * COMMENTS
+ *
+ * @run main/othervm nsk.stress.network.network005
+ */
+
+package nsk.stress.network;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Random;
+
+/**
+ * This test make huge number of data transers between one server and
+ * multiple clients communicating via TCP/IP sockets, and checks if those
+ * data are transfered correctly. All TCP/IP sockets are attached to local
+ * host (by its domain name), or to the ``localhost'' loopback (having the
+ * IP address 127.0.0.1).
+ * System.out.
+ */
+ static private PrintStream out = System.out;
+
+ /**
+ * Print error message: all clients and servers may print concurently.
+ */
+ static private synchronized void println(Object message) {
+ out.println(message.toString());
+ }
+
+ /**
+ * Display optional report: comment ca va.
+ */
+ static private void display(Object report) {
+ if (DEBUG_MODE)
+ println(report.toString());
+ }
+
+ /**
+ * Maximal number of connections this test should open simultaneously.
+ */
+ private final static int MAX_CONNECTIONS = 128;
+
+ /**
+ * Check few more connections to make sure that MAX_CONNECTIONS are safe.
+ */
+ private final static int CONNECTIONS_RESERVE = 10;
+
+ /**
+ * Number of client/server connections to establish.
+ */
+ private static final int CONNECTIONS = detectOSLimitation();
+
+ /**
+ * Number of parcels to be sent/recieved.
+ */
+ private static final int DATA_PARCELS = 128;
+
+ /**
+ * Maximal length of data parcel to be sent/recieved
+ * (it equals to 256 bytes now).
+ */
+ private static final int MAX_PARCEL = 1 << 8;
+
+ /**
+ * How many IP sockets can we open simultaneously?
+ * Check if MAX_CONNECTIONS connections
+ * can be open simultaneously.
+ */
+ private static int detectOSLimitation() {
+ final int CONNECTIONS_TO_TRY = MAX_CONNECTIONS + CONNECTIONS_RESERVE;
+ display("--- Trying to open " + CONNECTIONS_TO_TRY + " connections:");
+
+ InetAddress address;
+ ServerSocket serverSocket;
+ try {
+ address = InetAddress.getLocalHost();
+ int anyPort = 0;
+ int defaultBacklog = 50;
+ serverSocket = new ServerSocket(anyPort, defaultBacklog, address);
+ } catch (IOException ioe) {
+ throw new Error("FATAL error while loading the test: " + ioe);
+ }
+ display(serverSocket.toString());
+
+ Socket server[] = new Socket[CONNECTIONS_TO_TRY];
+ Socket client[] = new Socket[CONNECTIONS_TO_TRY];
+
+ int i, port = serverSocket.getLocalPort();
+ for (i = 0; i < CONNECTIONS_TO_TRY; i++)
+ try {
+ client[i] = new Socket(address, port);
+ display("--- Open: client[" + i + "] = " + client[i]);
+ server[i] = serverSocket.accept();
+ display("--- Open: server[" + i + "] = " + server[i]);
+ } catch (IOException ioe) {
+ display("--- OOPS! -- failed to open connection #" + i);
+ break;
+ }
+ display("--- Could open " +
+ (i < CONNECTIONS_TO_TRY ? "only " : "") + i + " connections.");
+ display("--- Closing them:");
+ for (int j = 0; j < i; j++)
+ try {
+ server[j].close();
+ client[j].close();
+ } catch (IOException ioe) {
+ throw new Error("FATAL error while loading the test: " + ioe);
+ }
+ display("--- OK.");
+ int safeConnections = i - CONNECTIONS_RESERVE;
+ if (safeConnections < 1)
+ safeConnections = 1;
+ if (safeConnections < MAX_CONNECTIONS) {
+ println("# ------------------------- CAUTION: -------------------");
+ println("# While checking the OS limitations, the test found that");
+ println("# only " + i + " TCP/IP socket connections could be safely open");
+ println("# simultaneously. However, possibility to open at least");
+ println("# " + MAX_CONNECTIONS + "+" + CONNECTIONS_RESERVE
+ + " connections were expected.");
+ println("# ");
+ println("# So, the test will check only " + safeConnections + " connection"
+ + (safeConnections == 1 ? "" : "s") + " which seem");
+ println("# safe to be open simultaneously.");
+ println("# ------------------------------------------------------");
+ }
+ return safeConnections;
+ }
+
+ /**
+ * Server (or client) thread intended to transfer data parcels to
+ * another client (or server) Agent.
+ */
+ static private class Agent extends Thread {
+ /**
+ * Agent's client mode.
+ */
+ final static int CLIENT = 1;
+ /**
+ * Agen's server mode.
+ */
+ final static int SERVER = 2;
+
+ /**
+ * Is this agent is client or server one?
+ */
+ private int mode;
+
+ /**
+ * This server thread listens the single socket.
+ */
+ private Socket socket;
+
+ /**
+ * What is the port number this socket is listening for?
+ */
+ int getPort() {
+ if (mode == SERVER)
+ return socket.getLocalPort();
+ else
+ return socket.getPort();
+ }
+
+ /**
+ * Address and port of this server socket.
+ */
+ public String toString() {
+ String mode = (this.mode == CLIENT) ? "Client" : "Server";
+ return mode + ": " + socket.toString();
+ }
+
+ /**
+ * Did the thread failed? If yes, what is the failure's reason.
+ */
+ Exception exception = null;
+
+ /**
+ * Find some free port at the given address
+ * and attach new server to hear that port.
+ */
+ Agent(Socket socket, int mode) {
+ if ((mode != SERVER) && (mode != CLIENT))
+ throw new IllegalArgumentException("unknown mode=" + mode);
+ this.socket = socket;
+ this.mode = mode;
+ }
+
+ /**
+ * Transfer DATA_PARCELS parcels of random data.
+ * Set initial seed for pseudo-random numbers generator
+ * to the value of the local port number.
+ *
+ * @see #DATA_PARCELS
+ * @see #getPort()
+ */
+ public void run() {
+ try {
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(getPort());
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+
+ if (mode == SERVER) {
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ println("Server agent for port #"
+ + getPort() + " got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "server has read unexpected parcel");
+ }
+
+ etalon.send(ostream); // reply
+ ostream.flush();
+
+ } else {
+ etalon.send(ostream); // init transfer
+ ostream.flush();
+
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ println("Client agent for port #"
+ + getPort() + " got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "parcel context is unexpected to client");
+ }
+ }
+ }
+
+ if (mode == SERVER) {
+ int datum = istream.read(); // wait until client's close()
+ if (datum >= 0)
+ throw new TestFailure(
+ "server has read ambigous byte: " + datum);
+
+ ostream.close(); // implies: socket.close();
+
+ } else {
+ if (istream.available() > 0) {
+ int datum = istream.read();
+ throw new TestFailure(
+ "client has read ambigous byte: " + datum);
+ }
+ ostream.close(); // implies: socket.close()
+ }
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ }
+
+ /**
+ * A data parcel to sent/recieved between Client and Server threads.
+ * When data parcel is sent, first 4 bytes transfered encode the size
+ * of the parcel (i.e.: number of data bytes in the parcel's contents).
+ * Then the parcel's contents bytes are transered.
+ */
+ static class Parcel {
+ private byte[] parcel;
+
+ /**
+ * Display all bytes as integer values from 0 to 255;
+ * or return ``null'' if this Parcel is not
+ * yet initialized.
+ */
+ public String toString() {
+ if (parcel == null)
+ return "null";
+ String s = "{";
+ for (int i = 0; i < parcel.length; i++)
+ s += (i > 0 ? ", " : "") + ((int) parcel[i] & 0xFF);
+ return s + "}";
+ }
+
+ /**
+ * Generate new parcel[] array using the given
+ * random numbers generator. Client and Server
+ * threads should use identical random generators,
+ * so that those threads could generate equal data parcels and
+ * check the parcel just transfered.
+ */
+ public Parcel(Random random) {
+ int size = random.nextInt(MAX_PARCEL) + 1;
+ parcel = new byte[size];
+ for (int i = 0; i < size; i++)
+ parcel[i] = (byte) random.nextInt(256);
+ }
+
+ /**
+ * Read exactly size bytes from the istream
+ * if possible, or throw TestFailure if unexpected end of
+ * istream occurs.
+ */
+ private static byte[] readBytes(int size, InputStream istream)
+ throws IOException {
+
+ byte data[] = new byte[size];
+ for (int i = 0; i < size; i++) {
+ int datum = istream.read();
+ if (datum < 0)
+ throw new TestFailure(
+ "unexpected EOF: have read: " + i + " bytes of " + size);
+ data[i] = (byte) datum;
+ }
+ return data;
+ }
+
+ /**
+ * Read 4 bytes from istream and threat them to encode
+ * size of data parcel following these 4 bytes.
+ */
+ private static int getSize(InputStream istream) throws IOException {
+ byte data[] = readBytes(4, istream);
+ int data0 = (int) data[0] & 0xFF;
+ int data1 = (int) data[1] & 0xFF;
+ int data2 = (int) data[2] & 0xFF;
+ int data3 = (int) data[3] & 0xFF;
+ int sizeWord = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
+ int size = sizeWord + 1;
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+ return size;
+ }
+
+ /**
+ * Send 4 bytes encoding actual size of the parcel just to be transfered.
+ */
+ private static void putSize(OutputStream ostream, int size)
+ throws IOException {
+
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+
+ int sizeWord = size - 1;
+ byte data[] = new byte[4];
+ data[0] = (byte) sizeWord;
+ data[1] = (byte) (sizeWord >> 8);
+ data[2] = (byte) (sizeWord >> 16);
+ data[3] = (byte) (sizeWord >> 24);
+ ostream.write(data);
+ }
+
+ /**
+ * Recieve data parcel.
+ */
+ public Parcel(InputStream istream) throws IOException {
+ int size = getSize(istream);
+ parcel = readBytes(size, istream);
+ }
+
+ /**
+ * Send this data parcel.
+ */
+ public void send(OutputStream ostream) throws IOException {
+ int size = parcel.length;
+ putSize(ostream, size);
+ ostream.write(parcel);
+ }
+
+ /**
+ * Check byte-to-byte equality between this and the
+ * other parcels.
+ */
+ public boolean equals(Parcel other) {
+ if (this.parcel.length != other.parcel.length)
+ return false;
+ int size = parcel.length;
+ for (int i = 0; i < size; i++)
+ if (this.parcel[i] != other.parcel[i])
+ return false;
+ return true;
+ }
+
+ }
+
+ /**
+ * Server or Client thread may throw this exception to report the test
+ * failure.
+ */
+ static class TestFailure extends RuntimeException {
+ /**
+ * Report particular purpose of the test failure.
+ */
+ public TestFailure(String purpose) {
+ super(purpose);
+ }
+
+ }
+
+ /**
+ * Attach client and server sockets to the local host, and check if
+ * huge number of data transfers could be correctly transfered between
+ * these sockets.
+ * args[] may
+ * prompt the local host IP address or domain name. Execute:
+ *
+ * java network005 [IP-address | host_name |
+ * localhost ]
+ *
where parameters are:
+ *
+ * IP-address - local hots's address, or 127.0.0.1
+ *
+ * host_name - local host's domain name, or the
+ * keyword ``localhost''
+ *
+ * localhost - placeholder for the IP-address 127.0.0.1
+ *
By default, the test uses the Internet address available via
+ * the method InetAddress.getLocalHost()
+ */
+ public static int run(String args[], PrintStream out) {
+ network005.out = out;
+
+ //
+ // Get IP address of the local machine.
+ //
+
+ InetAddress address = null;
+ try {
+ switch (args.length) {
+ case 0:
+ address = InetAddress.getLocalHost();
+ break;
+ case 1:
+ String hostName = args[0];
+ address = InetAddress.getByName(args[0]);
+ break;
+ default:
+ println("Use:");
+ println(" java network005");
+ println("or:");
+ println(" java network005 ${IP_ADDRESS}");
+ println("or:");
+ println(" java network005 ${HOST_NAME}");
+ println("or:");
+ println(" java network005 localhost");
+ return 2; // FAILED
+ }
+ } catch (UnknownHostException exception) {
+ println(exception);
+ return 2; // FAILED
+ }
+ display("Host: " + address);
+
+ //
+ // Assign ServerSocket to the local host:
+ //
+
+ ServerSocket serverSocket;
+ try {
+ final int anyPort = 0;
+ final int defaultBacklog = 50;
+ serverSocket = new ServerSocket(anyPort, defaultBacklog, address);
+ } catch (IOException ioe) {
+ println("# Failed to assign ServerSocket on: " + address);
+ return 2;
+ }
+ display(serverSocket.toString());
+
+ final int port = serverSocket.getLocalPort();
+
+ //
+ // Incarnate the server & the client agents.
+ //
+
+ Agent server[] = new Agent[CONNECTIONS];
+ Agent client[] = new Agent[CONNECTIONS];
+
+ for (int i = 0; i < CONNECTIONS; i++)
+ try {
+ Socket socket;
+ socket = new Socket(address, port);
+ client[i] = new Agent(socket, Agent.CLIENT);
+ display("Client #" + i + ": " + socket);
+ socket = serverSocket.accept();
+ server[i] = new Agent(socket, Agent.SERVER);
+ display("Server #" + i + ": " + socket);
+ } catch (IOException io) {
+ println("Failed establish conection #" + i + ": " + io);
+ return 2;
+ }
+
+ //
+ // Execute the server and client threads.
+ //
+
+ Exception exception = null;
+ for (int i = 0; i < CONNECTIONS; i++) {
+ server[i].start();
+ client[i].start();
+ }
+ try {
+ boolean someIsAlive = true;
+ while (someIsAlive) {
+ boolean aliveFound = false;
+ boolean someBroken = false;
+ for (int i = 0; i < CONNECTIONS; i++)
+ if (client[i].isAlive() || server[i].isAlive()) {
+ if ((client[i].exception != null) ||
+ (server[i].exception != null))
+ someBroken = true;
+ aliveFound = true;
+ Thread.yield();
+ }
+ someIsAlive = aliveFound;
+ if (someBroken)
+ break;
+ }
+ } catch (TestFailure failure) {
+ exception = failure;
+ }
+
+ // Failure diagnostics, if needed.
+
+ Exception problem[] = new Exception[2 * CONNECTIONS + 1];
+ problem[0] = exception;
+ for (int i = 0; i < CONNECTIONS; i++) {
+ problem[2 * i + 1] = server[i].exception;
+ problem[2 * i + 2] = client[i].exception;
+ }
+
+ int exitCode = 0;
+
+ for (int i = 0; i < 2 * CONNECTIONS + 1; i++)
+ if (problem[i] != null) {
+ out.println("#### OOPS ! ####");
+ problem[i].printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0) {
+ out.println("#### OOPS ! ####");
+ out.println("# Test failed.");
+ return 2; // FAILED
+ }
+ display("Test passed.");
+ return 0; // PASSED
+ }
+
+ /**
+ * Re-calls to the method run(args[],out) actually
+ * performing the test; and stop with exit code 95 if the test
+ * has passed, or with code 97 if the test has failed.
+ * (This is JCK-like exit codes convention.)
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit code.
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network006.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network006.java
new file mode 100644
index 00000000000..8745a9f8648
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/network/network006.java
@@ -0,0 +1,916 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/network/network006.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick, quarantine]
+ * VM testbase comments: 8185072
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test makes huge number of data transfers between 2 Java virtual
+ * machines using the TCP/IP protocol, and checks if those data are transfered
+ * correctly. Both client and server VMs run on the same local computer and
+ * attach TCP/IP sockets to the local host, or to the loopback domain
+ * ``localhost'' (having IP address 127.0.0.1).
+ * In this test, 128 client/server connections are established. Once a
+ * connection is established, client passes a data parcel to server, and server
+ * reads that parcel and checks if it is same as expected (byte-to-byte equality
+ * is desired). Then server passes (some other) parcel to the client, and client
+ * reads and verifies those bytes. This ping-pong game is repeated 128 times; and
+ * after that each pair of sockets checks if there are no extra bytes accudentally
+ * passed through their connection.
+ * Parcels lengths and contents are chosen randomly, and average parcel length
+ * is 128 bytes. So totally, each pair of sockets passes ~16Kb of data to each other,
+ * and thus ~32Kb of data are transfered by each sockets pair. Totally, ~4Mb of data
+ * are transfered by all client/server pairs.
+ * COMMENTS
+ * Test was fixed:
+ * added WAITTIME parameter defined timeout for TCP/IP sockets in minutes
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.stress.network.network006
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.stress.network.network006
+ * "${test.jdk}/bin/java ${test.vm.opts} ${test.java.opts}" 5
+ */
+
+package nsk.stress.network;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Random;
+
+/**
+ * This test makes huge number of data transfers between 2 Java virtual
+ * machines using the TCP/IP protocol, and checks if those data are transfered
+ * correctly. Both client and server VMs run on the same local computer and
+ * attach TCP/IP sockets to the local host, or to the loopback domain
+ * ``localhost'' (having IP address 127.0.0.1).
+ * MAX_CONNECTIONS connections
+ * can be open simultaneously.
+ */
+ private static int detectOSLimitation() {
+ final int CONNECTIONS_TO_TRY = MAX_CONNECTIONS + CONNECTIONS_RESERVE;
+ display("--- Trying to open " + CONNECTIONS_TO_TRY + " connections:");
+
+ InetAddress address;
+ ServerSocket serverSocket;
+ try {
+ address = InetAddress.getLocalHost();
+ int anyPort = 0;
+ int defaultBacklog = BACKLOG_QUEUE_LENGTH;
+ serverSocket = new ServerSocket(anyPort, defaultBacklog, address);
+ } catch (IOException ioe) {
+ throw new Error("FATAL error while loading the test: " + ioe);
+ }
+ display(serverSocket.toString());
+
+ Socket server[] = new Socket[CONNECTIONS_TO_TRY];
+ Socket client[] = new Socket[CONNECTIONS_TO_TRY];
+
+ int i, port = serverSocket.getLocalPort();
+ for (i = 0; i < CONNECTIONS_TO_TRY; i++)
+ try {
+ client[i] = new Socket(address, port);
+ display(">Open: client[" + i + "] = " + client[i]);
+ server[i] = serverSocket.accept();
+ display(">Open: server[" + i + "] = " + server[i]);
+ } catch (IOException ioe) {
+ display(">OOPS! -- failed to open connection #" + i);
+ break;
+ }
+ display("> Could open " +
+ (i < CONNECTIONS_TO_TRY ? "only " : "") + i + " connections.");
+ display(">Closing them:");
+ for (int j = 0; j < i; j++)
+ try {
+ server[j].close();
+ client[j].close();
+ } catch (IOException ioe) {
+ throw new Error("FATAL error while loading the test: " + ioe);
+ }
+ display(">OK.");
+ int safeConnections = i - CONNECTIONS_RESERVE;
+ if (safeConnections < 1)
+ safeConnections = 1;
+ if (safeConnections < MAX_CONNECTIONS) {
+ complain("------------------------- CAUTION: -------------------");
+ complain("While checking the OS limitations, the test found that");
+ complain("only " + i + " TCP/IP socket connections could be safely open");
+ complain("simultaneously. However, possibility to open at least");
+ complain("" + MAX_CONNECTIONS + "+" + CONNECTIONS_RESERVE
+ + " connections were expected.");
+ complain("");
+ complain("So, the test will check only " + safeConnections + " connection"
+ + (safeConnections == 1 ? "" : "s") + " which seem");
+ complain("safe to be open simultaneously.");
+ complain("------------------------------------------------------");
+ }
+ return safeConnections;
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Re-calls to the method run(args[],out) actually
+ * performing the test. After run(args[],out) stops,
+ * follow JDK-like convention for exit codes. I.e.: stop with
+ * exit status 95 if the test has passed, or with status 97 if
+ * the test has failed.
+ *
+ * @see #run(String[], PrintStream)
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status.
+ }
+
+ /**
+ * Parse command-line parameters stored into args[] array,
+ * then perform the test. I.e.: start the server thread at the same VM
+ * this method runs, then start the other client VM, and verify data
+ * transfer through TCP/IP connection between those different virtual
+ * machines.
+ *
+ * java network006 java_command
+ * [IP-address | host_name | localhost ]
+ *
where parameters are:
+ *
+ * java_command - how to start java,
+ * e.g.: ``c:\jdk1.3\bin\java -classic''
+ *
+ * waittime - timeout for TCP/IP sockets in minutes
+ *
+ * IP-address - local hots's address, or 127.0.0.1
+ *
+ * host_name - local host's domain name, or the
+ * keyword ``localhost''
+ *
+ * localhost - placeholder for the IP-address 127.0.0.1
+ * java_command should point to the same
+ * Java machine just executing this test. However, every compatible Java 2
+ * implementation is appropriate.
+ * InetAddress.getLocalHost() to get the domain name and
+ * IP-address of the local computer.
+ */
+ public static int run(String args[], PrintStream out) {
+ network006.out = out;
+
+ //
+ // Get the Internet address of the local machine.
+ //
+ InetAddress address = null;
+ try {
+ switch (args.length) {
+ case 2:
+ address = InetAddress.getLocalHost();
+ break;
+ case 3:
+ address = InetAddress.getByName(args[2]);
+ break;
+ default:
+ complain("Illegal arguments number; execute:");
+ complain(" java " + network006.class.getName() + " $JAVA_COMMAND " +
+ "[$IP_ADDRESS | $HOST_NAME | localhost]");
+ return 2; // FAILED
+ }
+ } catch (UnknownHostException exception) {
+ complain(exception.toString());
+ return 2; // FAILED
+ }
+ display("Host: " + address);
+
+ //
+ // Detect if it is safe to open MAX_CONNETIONS simultaneously:
+ //
+ final int CONNECTIONS = detectOSLimitation();
+
+ //
+ // Assign ServerSocket, and start client VM which should open
+ // the prescribed number of CONNECTIONS to that ServerSocket.
+ //
+
+ ServerSocket serverSocket;
+ try {
+ final int anyPort = 0;
+ final int defaultBacklog = BACKLOG_QUEUE_LENGTH;
+ serverSocket = new ServerSocket(anyPort, defaultBacklog, address);
+ } catch (IOException exception) {
+ complain("Cannot assign a ServerSocket on: " + address);
+ return 2;
+ }
+
+ //
+ // Start the client process on different VM.
+ //
+
+ String IPAddress = address.getHostAddress();
+ int localPort = serverSocket.getLocalPort();
+ String arguments = " " + CONNECTIONS + " " + IPAddress + " " + localPort;
+ //String command = args[0] + " " + network006.class.getName() + "$Client " + arguments;
+ String command = args[0] + " " + Client.class.getName() + " " + arguments;
+ try {
+ SO_TIMEOUT = Integer.parseInt(args[1]) * 60 * 1000;
+ } catch (NumberFormatException e) {
+ complain("Wrong timeout argument: " + e);
+ return 2;
+ }
+
+ Runtime runtime = Runtime.getRuntime();
+
+ Process client = null;
+ IORedirector redirectOut = null;
+ IORedirector redirectErr = null;
+
+ try {
+ // Start clients on different JVM:
+ client = runtime.exec(command);
+
+ // Provide clients with access to stderr and stdout:
+ InputStream clientOut = client.getInputStream();
+ InputStream clientErr = client.getErrorStream();
+ redirectOut = new IORedirector(clientOut, DEBUG_MODE ? out : null);
+ redirectErr = new IORedirector(clientErr, out);
+ redirectOut.start();
+ redirectErr.start();
+
+ } catch (Exception exception) {
+ complain("Failed to start client: " + exception);
+ return 2;
+ }
+ //
+ // Start the server threads (and let them establish connections):
+ //
+
+ Server server[] = new Server[CONNECTIONS];
+ for (int i = 0; i < CONNECTIONS; i++) {
+ server[i] = new Server(serverSocket);
+ display("Server #" + i + ": " + server[i]);
+ server[i].start();
+ }
+
+ //
+ // Wait for the servers and the clients:
+ //
+
+ boolean testFailed = false;
+
+ try {
+ client.waitFor();
+ int clientStatus = client.exitValue();
+ display("Client VM exitCode=" + clientStatus);
+
+ // Let I/O redirectors to flush:
+ if (redirectOut.isAlive())
+ redirectOut.join();
+ if (redirectErr.isAlive())
+ redirectErr.join();
+
+ // If client has crashed, also terminate the server (to avoid hangup).
+ if (clientStatus != 95) {
+ complain("Client VM has crashed: exit status=" + clientStatus);
+ testFailed = true;
+ }
+
+ // Client has finished OK; wait for the server.
+ for (int i = 0; i < CONNECTIONS; i++) {
+ display("Server: waiting for #" + i);
+ if (server[i].isAlive()) {
+ display("Server #" + i + ": (joining...)" + server[i]);
+ server[i].join();
+ }
+ if (server[i].exception != null) {
+ if (server[i].message != null)
+ complain("Server #" + i + "(finished): with message:" + server[i].message);
+
+ complain("Server #" + i + "(finished): " + server[i].exception);
+ server[i].exception.printStackTrace(out);
+ out.flush();
+// complain("Server #"+i+": "+server[i].exception.getStackTrace());
+ testFailed = true;
+ }
+ }
+
+ } catch (Exception exception) {
+ complain("Test interrupted: " + exception);
+ testFailed = true;
+ }
+
+ if (testFailed)
+ complain("Test failed.");
+ else
+ display("Test passed.");
+ return testFailed ? 2 : 0;
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Log stream for error messages and/or (optional) execution trace.
+ */
+ private static PrintStream out;
+
+ /**
+ * Print error message.
+ */
+ private static synchronized void complain(Object message) {
+ out.println("# " + message);
+ out.flush();
+ }
+
+ /**
+ * Display optional report: comment ca va?
+ */
+ private static synchronized void display(Object report) {
+ if (DEBUG_MODE)
+ out.println(report.toString());
+ out.flush(); //todo shouldn't this be inside if??
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Server thread should reply to data parcels sent by Client VM.
+ */
+ private static class Server extends Thread {
+ /**
+ * The socket is assigned at the Server instantiation.
+ */
+ private ServerSocket serverSocket;
+
+ /**
+ * The socket is assigned at the Server runtime.
+ */
+ private Socket socket;
+
+ /**
+ * Display the server socket.
+ */
+ public String toString() {
+
+ return "ServerSocket: " + serverSocket.toString();
+// + " socket: " + socket.toString();
+ }
+
+ /**
+ * Which port is this socket listening?
+ */
+ int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ /**
+ * Find some free port at the given address
+ * and attach new server to hear that port. // lidsten to??
+ */
+ public Server(ServerSocket serverSocket) {
+ this.serverSocket = serverSocket;
+ }
+
+ /**
+ * Exception just arisen while the server was working,
+ * or null if it was OK with the server.
+ */
+ Exception exception = null;
+ String message = null;
+
+ /**
+ * Accept connection, then reply to client's parcels.
+ */
+ public void run() {
+ try {
+ socket = serverSocket.accept();
+ socket.setSoTimeout(SO_TIMEOUT);
+
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(getPort());
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+ message = "reading parcel number " + i;
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ complain("Server thread for port #"
+ + getPort() + " got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure( //received??
+ "server has read unexpected parcel");
+ }
+ message = "sending parcel number " + i;
+ etalon.send(ostream);
+ ostream.flush();
+ }
+
+ int datum = istream.read(); // wait for client close()
+ if (datum >= 0)
+ throw new TestFailure(
+ "server has read ambigous byte: " + datum);
+
+ ostream.close(); // implies: socket.close();
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * Client VM should send data parcels to Server VM and
+ * recieve and verify the server's replies.
+ */
+ private static class Client extends Thread {
+ /**
+ * This thread uses the single client socket.
+ */
+ private Socket socket;
+
+ /**
+ * Address and port of this socket.
+ */
+ public String toString() {
+ return socket.toString();
+ }
+
+ /**
+ * Did the thread failed? If yes, what is the failure's reason.
+ */
+ Exception exception = null;
+ String message = null;
+
+
+ public static java.io.PrintStream complainStream = System.out;
+ public static java.io.PrintStream displayStream = System.err;
+
+ /**
+ * Connect client socket on the given address
+ * and port.
+ */
+ Client(InetAddress address, int port) throws IOException {
+ socket = new Socket(address, port);
+ socket.setSoTimeout(SO_TIMEOUT);
+ }
+
+ /**
+ * What is the port number this socket is listening for?
+ */
+ int getPort() {
+ return socket.getPort();
+ }
+
+ /**
+ * Establish connection, then read/respond DATA_PARCELS parcels
+ * of random data. Set initial seed for pseudo-random numbers generator
+ * to the value of the local port number.
+ *
+ * @see #DATA_PARCELS
+ * @see #getPort()
+ */
+ public void run() {
+ try {
+ InputStream istream = socket.getInputStream();
+ OutputStream ostream = socket.getOutputStream();
+
+ Random random = new Random(getPort());
+ // suggested by Oleg -- to avoid race conditions
+ /* try{
+ Thread.sleep(500);
+ }
+ catch (java.lang.InterruptedException e)
+ {
+ }*/
+
+ for (int i = 0; i < DATA_PARCELS; i++) {
+ Parcel etalon = new Parcel(random);
+ message = "sending parcel number: " + i;
+ etalon.send(ostream);
+ ostream.flush();
+
+ message = "reading parcel number: " + i;
+ Parcel sample = new Parcel(istream); // read
+ if (!sample.equals(etalon)) {
+ complain("Client thread for port #"
+ + getPort() + " got unexpected parcel:\n"
+ + "sample=" + sample + "\n"
+ + "etalon=" + etalon);
+ throw new TestFailure(
+ "parcel context is unexpected to client");
+ }
+ }
+
+ if (istream.available() > 0) {
+ int datum = istream.read();
+ throw new TestFailure(
+ "client has read ambigous byte: " + datum);
+ }
+ ostream.close(); // implies: socket.close()
+
+ } catch (Exception oops) {
+ exception = oops;
+ }
+ }
+
+ /**
+ * Establish lots of connections to server socket, attack servers with
+ * huge data parcels, and check if they reply correctly. The number of
+ * connections to try, the address and port number for the server socket
+ * are passed through args[], like:
+ *
+ * java network006$Client connections_to_try address port
+ *
+ */
+ public static void main(String args[]) {
+ if (DEBUG_MODE) {
+ try {
+ String filename = "Client" + ((args.length == 3) ? args[2] : "new");
+ displayStream = new PrintStream(filename + ".out");
+ complainStream = new PrintStream(filename + ".err");
+ } catch (FileNotFoundException exception) {
+ complain(exception);
+ }
+
+ }
+
+ if (args.length != 3) {
+ complain("Client expects 3 paramenets:");
+ complain(" java " + Client.class.getName() + " connections_to_try address port");
+ exit(1); // FAILED
+ }
+
+ int CONNECTIONS = Integer.parseInt(args[0]);
+ display("Client VM: will try " + CONNECTIONS + " connections.");
+ InetAddress address;
+ try {
+ address = InetAddress.getByName(args[1]);
+ } catch (UnknownHostException exception) {
+ address = null;
+ complain("Client: cannot find host: \"" + args[1] + "\"");
+ exit(4);
+ }
+ display("Client: host to contact: " + address);
+ int port = Integer.parseInt(args[2]);
+ display("Client: port to contact: " + port);
+
+ //
+ // Establish connections, and start client processes:
+ //
+
+ Client client[] = new Client[CONNECTIONS];
+ for (int i = 0; i < CONNECTIONS; i++)
+ try {
+ client[i] = new Client(address, port);
+ display("Client #" + i + ": " + client[i]);
+
+ } catch (IOException ioe) {
+ complain("Client #" + i + "(creation): " + ioe);
+ ioe.printStackTrace(complainStream);
+ complainStream.flush();
+// complain("Client #" + i + "(creation): " + ioe.getStackTrace());
+ exit(3);
+ }
+
+ for (int i = 0; i < CONNECTIONS; i++)
+ client[i].start();
+
+ //
+ // Wait until testing is not finished:
+ //
+
+ int status = 0;
+ for (int i = 0; i < CONNECTIONS; i++) {
+ display("Client: waiting for #" + i);
+ if (client[i].isAlive()) {
+ display("Client #" + i + ": (joining...)" + client[i]);
+
+ try {
+ client[i].join();
+ } catch (InterruptedException ie) {
+ complain("Client #" + i + ": " + ie);
+ status = 3;
+ }
+ }
+ if (client[i].exception != null) {
+ if (client[i].message != null)
+ complain("Client #" + i + "(finished) with message: " + client[i].message);
+ complain("Client #" + i + "(finished): " + client[i].exception);
+ client[i].exception.printStackTrace(complainStream);
+ complainStream.flush();
+ if (status == 0)
+ status = 2;
+ }
+ }
+
+ exit(status);
+ }
+
+ /**
+ * Print error message.
+ */
+ private static synchronized void complain(Object message) {
+ complainStream.println("# " + message);
+ complainStream.flush();
+ }
+
+ /**
+ * Display execution trace.
+ */
+ private static synchronized void display(Object message) {
+ if (!DEBUG_MODE)
+ return;
+ displayStream.println(message.toString());
+ displayStream.flush();
+ }
+
+ /**
+ * Exit with JCK-like status.
+ */
+ private static void exit(int exitCode) {
+ int status = exitCode + 95;
+// display("Client: exiting with code=" + status);
+ System.exit(status);
+ }
+ }
+
+ /**
+ * Two of such threads should redirect out and err
+ * streams of client VM.
+ */
+ private static class IORedirector extends Thread {
+ /**
+ * Source stream.
+ */
+ InputStream in;
+ /**
+ * Destination stream.
+ */
+ OutputStream out;
+
+ /**
+ * Redirect in to out.
+ */
+ public IORedirector(InputStream in, OutputStream out) {
+ this.in = in;
+ this.out = out;
+ }
+
+ /**
+ * Read input stream until the EOF, and write everithing to output stream.
+ * If output stream is assigned to null, do not print anything,
+ * but read the input stream anywhere.
+ */
+ public void run() {
+ try {
+ for (; ; ) {
+ int symbol = in.read();
+ if (symbol < 0)
+ break; // EOF
+ if (out != null)
+ out.write(symbol);
+ }
+
+ if (out != null)
+ out.flush();
+
+ } catch (Exception exception) {
+ throw new TestFailure("IORedirector exception: " + exception);
+ }
+ }
+ }
+
+ //----------------------------------------------------------------//
+
+ /**
+ * A data parcel to be sent/recieved between Client VM and Server thread.
+ * When data parcel is sent, first 4 bytes are transfered which encode the
+ * int number equal to size of the parcel minus 1. I.e.: if
+ * number of data bytes in the parcel's contents is N, then
+ * the first 4 bytes encode the number N-1. After that, the
+ * parcel's contents bytes are transered.
+ */
+ static class Parcel {
+ private byte[] parcel;
+
+ /**
+ * Display all bytes as integer values from 0 to 255;
+ * or return ``null'' if this Parcel is not
+ * yet initialized.
+ */
+ public String toString() {
+ if (parcel == null)
+ return "null";
+ String s = "{";
+ for (int i = 0; i < parcel.length; i++)
+ s += (i > 0 ? ", " : "") + ((int) parcel[i] & 0xFF);
+ return s + "}";
+ }
+
+ /**
+ * Generate new parcel[] array using the given
+ * random numbers generator. Client and Server
+ * threads should use identical random generators,
+ * so that those threads could generate equal data parcels and
+ * check the parcel just transfered.
+ */
+ public Parcel(Random random) {
+ int size = random.nextInt(MAX_PARCEL) + 1;
+ parcel = new byte[size];
+ for (int i = 0; i < size; i++)
+ parcel[i] = (byte) random.nextInt(256);
+ }
+
+ /**
+ * Read exactly size bytes from the istream
+ * if possible, or throw TestFailure if unexpected end of
+ * istream occurs.
+ */
+ private static byte[] readBytes(int size, InputStream istream)
+ throws IOException {
+
+ byte data[] = new byte[size];
+ for (int i = 0; i < size; i++) {
+ int datum = istream.read();
+ if (datum < 0)
+ throw new TestFailure(
+ "unexpected EOF: have read: " + i + " bytes of " + size);
+ data[i] = (byte) datum;
+ }
+ return data;
+ }
+
+ /**
+ * Read 4 bytes from istream and threat them to encode
+ * size of data parcel following these 4 bytes.
+ */
+ private static int getSize(InputStream istream) throws IOException {
+ byte data[] = readBytes(4, istream);
+ int data0 = (int) data[0] & 0xFF;
+ int data1 = (int) data[1] & 0xFF;
+ int data2 = (int) data[2] & 0xFF;
+ int data3 = (int) data[3] & 0xFF;
+ int sizeWord = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
+ int size = sizeWord + 1;
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+ return size;
+ }
+
+ /**
+ * Send 4 bytes encoding actual size of the parcel just to be transfered.
+ */
+ private static void putSize(OutputStream ostream, int size)
+ throws IOException {
+
+ if (size <= 0)
+ throw new TestFailure("illegal size: " + size);
+
+ int sizeWord = size - 1;
+ byte data[] = new byte[4];
+ data[0] = (byte) sizeWord;
+ data[1] = (byte) (sizeWord >> 8);
+ data[2] = (byte) (sizeWord >> 16);
+ data[3] = (byte) (sizeWord >> 24);
+ ostream.write(data);
+ }
+
+ /**
+ * Recieve data parcel.
+ */
+ public Parcel(InputStream istream) throws IOException {
+ int size = getSize(istream);
+ parcel = readBytes(size, istream);
+ }
+
+ /**
+ * Send this data parcel.
+ */
+ public void send(OutputStream ostream) throws IOException {
+ int size = parcel.length;
+ putSize(ostream, size);
+ ostream.write(parcel);
+ }
+
+ /**
+ * Check byte-to-byte equality between this and the
+ * other parcels.
+ */
+ public boolean equals(Parcel other) {
+ if (this.parcel.length != other.parcel.length)
+ return false;
+ int size = parcel.length;
+ for (int i = 0; i < size; i++)
+ if (this.parcel[i] != other.parcel[i])
+ return false;
+ return true;
+ }
+ }
+
+ /**
+ * Server or Client may throw this exception to report the test failure.
+ */
+ static class TestFailure extends RuntimeException {
+ /**
+ * Report particular purpose of the test failure.
+ */
+ public TestFailure(String purpose) {
+ super(purpose);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/TEST.properties
new file mode 100644
index 00000000000..8b51b2a9115
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/TEST.properties
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric001.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric001.java
new file mode 100644
index 00000000000..aac81218c61
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric001.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric001.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A of the type
+ * double[][]. Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * That product A*A is calculated twice: in a single thread, and in N
+ * separate threads, where NxN is the size of square matrix A. When executing
+ * in N threads, each thread calculate distinct row of the resulting matrix.
+ * The test checks if the resulting product A*A is the same when calculated
+ * in single thread and in N threads.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs installed
+ * on the platform executing the test is taken into account for performance
+ * testing). Note, that HotSpot may fail to adjust itself for better
+ * performance in single-thread calculation.
+ * COMMENTS
+ * The bug was filed referencing to the same numeric algorithm,
+ * which is used by this test:
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ *
+ * @run main/othervm nsk.stress.numeric.numeric001.numeric001 300 300
+ */
+
+package nsk.stress.numeric.numeric001;
+
+import java.io.PrintStream;
+
+/**
+ * This test calculates the product A.A for
+ * a square matrix A of the type double[][].
+ * Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ *
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric001 {
+ /**
+ * When testing performance, single thread calculation is allowed to
+ * be 10% slower than multi-threads calculation (TOLERANCE
+ * is assigned to 10 now).
+ */
+ public static final double TOLERANCE = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ */
+ private static boolean verbose = false;
+
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message to the out.
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric001 [-verbose] [-performance] [-CPU:number]
+ * matrixSize [threads]
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
number -
+ * number of CPU installed on the computer just executing the test
+ *
matrixSize -
+ * number of rows (and columns) in square matrix to be tested
+ *
threads -
+ * for multi-thread calculation
+ * (default: matrixSize)
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric001.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ if (argument.startsWith("-CPU:")) {
+ String value =
+ argument.substring("-CPU:".length(), argument.length());
+ numberOfCPU = Integer.parseInt(value);
+
+ if (numberOfCPU < 1) {
+ complain("Illegal number of CPU: " + argument);
+ return 2; // failure
+ }
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if ((args.length < argsShift + 1) || (args.length > argsShift + 2)) {
+ complain("Illegal argument(s). Execute:");
+ complain(
+ " java numeric001 [-verbose] [-performance] [-CPU:number] " +
+ "matrixSize [threads]");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int threads = size;
+ if (args.length >= argsShift + 2)
+ threads = Integer.parseInt(args[argsShift + 1]);
+ if ((threads < 1) || (threads > size)) {
+ complain("Threads number should be 1 to matrix size.");
+ return 2; // failure
+ }
+ if ((size % threads) != 0) {
+ complain("Threads number should evenly divide matrix size.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ SquareMatrix A = new SquareMatrix(size);
+ SquareMatrix A1 = new SquareMatrix(size);
+ SquareMatrix Am = new SquareMatrix(size);
+ println(" done.");
+
+ double singleThread = elapsedTime(out, A, A1, size, 1);
+ double multiThreads = elapsedTime(out, A, Am, size, threads);
+
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ if (A1.value[line][column] != Am.value[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Different results by single- and multi-threads:");
+ complain(" line=" + line + ", column=" + column);
+ complain("A1.value[line][column]=" + A1.value[line][column]);
+ complain("Am.value[line][column]=" + Am.value[line][column]);
+ return 2; // FAILED
+ }
+ println(" done.");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ double elapsed1 = singleThread;
+ double elapsedM = multiThreads * numberOfCPU;
+ if (elapsed1 > elapsedM * (1 + TOLERANCE / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("Single-thread calculation is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" single thread: " + singleThread);
+ complain(" multi-threads: " + multiThreads);
+ complain(" number of CPU: " + numberOfCPU);
+ complain(" tolerance: " + TOLERANCE + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ private static double elapsedTime(PrintStream out,
+ SquareMatrix A, SquareMatrix AA, int size, int threads) {
+
+ print("Computing A*A with " + threads + " thread(s):");
+ long mark1 = System.currentTimeMillis();
+ AA.setSquareOf(A, threads);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MFLOPS");
+
+ return sec;
+ }
+
+ /**
+ * This class computes A*A for square matrix A.
+ */
+ private static class SquareMatrix {
+ volatile double value[][];
+
+ /**
+ * New square matrix with random elements.
+ */
+ public SquareMatrix(int size) {
+ value = new double[size][size];
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ value[line][column] = Math.random() * size;
+ }
+
+ /**
+ * Update value[][] of this matrix.
+ *
+ * @param threads Split computation into the given number of threads.
+ */
+ public void setSquareOf(SquareMatrix A, int threads) {
+ if (this.value.length != A.value.length)
+ throw new IllegalArgumentException(
+ "this.value.length != A.value.length");
+
+ int size = value.length;
+ if ((size % threads) != 0)
+ throw new IllegalArgumentException("size%threads != 0");
+ int bunch = size / threads;
+
+ Thread task[] = new Thread[threads];
+ for (int t = 0; t < threads; t++) {
+ int line0 = bunch * t;
+ MatrixComputer computer =
+ new MatrixComputer(value, A.value, line0, bunch);
+ task[t] = new Thread(computer);
+ }
+
+ for (int t = 0; t < threads; t++)
+ task[t].start();
+
+ for (int t = 0; t < threads; t++)
+ if (task[t].isAlive())
+ try {
+ task[t].join();
+ } catch (InterruptedException exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ }
+
+ /**
+ * Thread to compute a bunch of lines of matrix square.
+ */
+ private static class MatrixComputer implements Runnable {
+ private double result[][];
+ private double source[][];
+ private int line0;
+ private int bunch;
+
+ /**
+ * Register a task for matrix multiplication.
+ */
+ public MatrixComputer(
+ double result[][], double source[][], int line0, int bunch) {
+
+ this.result = result; // reference to resulting matrix value
+ this.source = source; // reference to matrix to be squared
+ this.line0 = line0; // compute lines from line0 to ...
+ this.bunch = bunch; // number of resulting lines to compute
+ }
+
+ /**
+ * Do execute the task just registered for this thread.
+ */
+ public void run() {
+ int line1 = line0 + bunch;
+ int size = result.length;
+ for (int line = line0; line < line1; line++)
+ for (int column = 0; column < size; column++) {
+ double sum = 0;
+ for (int i = 0; i < size; i++)
+ sum += source[line][i] * source[i][column];
+ result[line][column] = sum;
+ }
+ }
+
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric002.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric002.java
new file mode 100644
index 00000000000..a39cfc05db3
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric002.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric002.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A of the type
+ * float[][]. Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * That product A*A is calculated twice: in a single thread, and in N
+ * separate threads, where NxN is the size of square matrix A. When executing
+ * in N threads, each thread calculate distinct row of the resulting matrix.
+ * The test checks if the resulting product A*A is the same when calculated
+ * in single thread and in N threads.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs installed
+ * on the platform executing the test is taken into account for performance
+ * testing). Note, that HotSpot may fail to adjust itself for better
+ * performance in single-thread calculation.
+ * COMMENTS
+ * The bug was filed referencing to the same numeric algorithm,
+ * which is used by this test:
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ *
+ * @run main/othervm nsk.stress.numeric.numeric002.numeric002 300 300
+ */
+
+package nsk.stress.numeric.numeric002;
+
+import java.io.PrintStream;
+
+/**
+ * This test calculates the product A.A for
+ * a square matrix A of the type float[][].
+ * Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ *
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric002 {
+ /**
+ * When testing performance, single thread calculation is allowed to
+ * be 10% slower than multi-threads calculation (TOLERANCE
+ * is assigned to 10 now).
+ */
+ public static final double TOLERANCE = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ */
+ private static boolean verbose = false;
+
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message to the out for a square
+ * matrix .
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke for a square
+ * matrix run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric002 [-verbose] [-performance] [-CPU:number]
+ * matrixSize [threads]
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
number -
+ * number of CPU installed on the computer just executing the test
+ *
matrixSize -
+ * number of rows (and columns) in square matrix to be tested
+ *
threads -
+ * for multi-thread calculation
+ * (default: matrixSize)
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric002.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ if (argument.startsWith("-CPU:")) {
+ String value =
+ argument.substring("-CPU:".length(), argument.length());
+ numberOfCPU = Integer.parseInt(value);
+
+ if (numberOfCPU < 1) {
+ complain("Illegal number of CPU: " + argument);
+ return 2; // failure
+ }
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if ((args.length < argsShift + 1) || (args.length > argsShift + 2)) {
+ complain("Illegal argument(s). Execute:");
+ complain(
+ " java numeric002 [-verbose] [-performance] [-CPU:number] " +
+ "matrixSize [threads]");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int threads = size;
+ if (args.length >= argsShift + 2)
+ threads = Integer.parseInt(args[argsShift + 1]);
+ if ((threads < 1) || (threads > size)) {
+ complain("Threads number should be 1 to matrix size.");
+ return 2; // failure
+ }
+ if ((size % threads) != 0) {
+ complain("Threads number should evenly divide matrix size.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ SquareMatrix A = new SquareMatrix(size);
+ SquareMatrix A1 = new SquareMatrix(size);
+ SquareMatrix Am = new SquareMatrix(size);
+ println(" done.");
+
+ double singleThread = elapsedTime(out, A, A1, size, 1);
+ double multiThreads = elapsedTime(out, A, Am, size, threads);
+
+ if (!A1.isConsistent) {
+ complain("Failed to execute 1-thread calculation.");
+ return 2; // test FAILED
+ }
+ if (!Am.isConsistent) {
+ complain("Failed to execute " + threads + "-threads calculation.");
+ if (testPerformance) {
+ complain("I.e.: VM failed to execute " + threads + " threads,");
+ complain("and this looks like a performance bug.");
+ return 2; // test FAILED
+ } else {
+ complain("This looks strange, but this is not a bug.");
+ complain("The test is thought passed.");
+ return 0; // test PASSED
+ }
+ }
+
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ if (A1.value[line][column] != Am.value[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Different results by single- and multi-threads:");
+ complain(" line=" + line + ", column=" + column);
+ complain("A1.value[line][column]=" + A1.value[line][column]);
+ complain("Am.value[line][column]=" + Am.value[line][column]);
+ return 2; // FAILED
+ }
+ println(" done.");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ double elapsed1 = singleThread;
+ double elapsedM = multiThreads * numberOfCPU;
+ if (elapsed1 > elapsedM * (1 + TOLERANCE / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("Single-thread calculation is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" single thread: " + singleThread);
+ complain(" multi-threads: " + multiThreads);
+ complain(" number of CPU: " + numberOfCPU);
+ complain(" tolerance: " + TOLERANCE + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ private static double elapsedTime(PrintStream out,
+ SquareMatrix A, SquareMatrix AA, int size, int threads) {
+
+ print("Computing A*A with " + threads + " thread(s):");
+ long mark1 = System.currentTimeMillis();
+ AA.setSquareOf(A, threads);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MFLOPS");
+
+ return sec;
+ }
+
+ /**
+ * This class computes A*A for square matrix A.
+ */
+ private static class SquareMatrix {
+ volatile float value[][];
+ boolean isConsistent = false;
+
+ /**
+ * New square matrix with random elements.
+ */
+ public SquareMatrix(int size) {
+ value = new float[size][size];
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ value[line][column] = (float) (Math.random() * size);
+ isConsistent = true;
+ }
+
+ /**
+ * Update value[][] of this matrix.
+ *
+ * @param threads Split computation into the given number of threads.
+ */
+ public void setSquareOf(SquareMatrix A, int threads) {
+ if (this.value.length != A.value.length)
+ throw new IllegalArgumentException(
+ "this.value.length != A.value.length");
+
+ int size = value.length;
+ if ((size % threads) != 0)
+ throw new IllegalArgumentException("size%threads != 0");
+ int bunch = size / threads;
+
+ Thread task[] = new Thread[threads];
+ for (int t = 0; t < threads; t++) {
+ int line0 = bunch * t;
+ MatrixComputer computer =
+ new MatrixComputer(value, A.value, line0, bunch);
+ task[t] = computer;
+ }
+
+ for (int t = 0; t < threads; t++)
+ task[t].start();
+
+ isConsistent = true;
+ for (int t = 0; t < threads; t++) {
+ if (task[t].isAlive())
+ try {
+ task[t].join();
+ } catch (InterruptedException exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ if (!((MatrixComputer) (task[t])).threadExecuted) {
+ complain("Thread #" + t + " was not actually executed.");
+ isConsistent = false;
+ }
+ }
+ }
+
+ /**
+ * Thread to compute a bunch of lines of matrix square.
+ */
+ private static class MatrixComputer extends Thread {
+ private float result[][];
+ private float source[][];
+ private int line0;
+ private int bunch;
+
+ /**
+ * Register a task for matrix multiplication.
+ */
+ public MatrixComputer(
+ float result[][], float source[][], int line0, int bunch) {
+
+ this.result = result; // reference to resulting matrix value
+ this.source = source; // reference to matrix to be squared
+ this.line0 = line0; // compute lines from line0 to ...
+ this.bunch = bunch; // number of resulting lines to compute
+ }
+
+ /**
+ * Do execute the task just registered for this thread.
+ */
+ public void run() {
+ int line1 = line0 + bunch;
+ int size = result.length;
+ for (int line = line0; line < line1; line++)
+ for (int column = 0; column < size; column++) {
+ float sum = 0;
+ for (int i = 0; i < size; i++)
+ sum += source[line][i] * source[i][column];
+ result[line][column] = sum;
+ }
+ threadExecuted = true;
+ }
+
+ /**
+ * Method run() sets this flag on is actually
+ * finishes to execute.
+ */
+ boolean threadExecuted = false;
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric003.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric003.java
new file mode 100644
index 00000000000..bb6e70831c3
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric003.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric003.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A of the type
+ * long[][]. Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * That product A*A is calculated twice: in a single thread, and in N
+ * separate threads, where NxN is the size of square matrix A. When executing
+ * in N threads, each thread calculate distinct row of the resulting matrix.
+ * The test checks if the resulting product A*A is the same when calculated
+ * in single thread and in N threads.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs installed
+ * on the platform executing the test is taken into account for performance
+ * testing). Note, that HotSpot may fail to adjust itself for better
+ * performance in single-thread calculation.
+ * COMMENTS
+ * The bug was filed referencing to the same numeric algorithm,
+ * which is used by this test:
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ *
+ * @run main/othervm nsk.stress.numeric.numeric003.numeric003 300 300
+ */
+
+package nsk.stress.numeric.numeric003;
+
+import java.io.PrintStream;
+
+/**
+ * This test calculates the product A.A for
+ * a square matrix A of the type long[][].
+ * Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ *
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric003 {
+ /**
+ * When testing performance, single thread calculation is allowed to
+ * be 10% slower than multi-threads calculation (TOLERANCE
+ * is assigned to 10 now).
+ */
+ public static final double TOLERANCE = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ */
+ private static boolean verbose = false;
+
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message to the out for
+ * a square matrix .
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke for
+ * a square matrix run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric003 [-verbose] [-performance] [-CPU:number]
+ * matrixSize [threads]
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
number -
+ * number of CPU installed on the computer just executing the test
+ *
matrixSize -
+ * number of rows (and columns) in square matrix to be tested
+ *
threads -
+ * for multi-thread calculation
+ * (default: matrixSize)
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric003.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ if (argument.startsWith("-CPU:")) {
+ String value =
+ argument.substring("-CPU:".length(), argument.length());
+ numberOfCPU = Integer.parseInt(value);
+
+ if (numberOfCPU < 1) {
+ complain("Illegal number of CPU: " + argument);
+ return 2; // failure
+ }
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if ((args.length < argsShift + 1) || (args.length > argsShift + 2)) {
+ complain("Illegal argument(s). Execute:");
+ complain(
+ " java numeric003 [-verbose] [-performance] [-CPU:number] " +
+ "matrixSize [threads]");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int threads = size;
+ if (args.length >= argsShift + 2)
+ threads = Integer.parseInt(args[argsShift + 1]);
+ if ((threads < 1) || (threads > size)) {
+ complain("Threads number should be 1 to matrix size.");
+ return 2; // failure
+ }
+ if ((size % threads) != 0) {
+ complain("Threads number should evenly divide matrix size.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ SquareMatrix A = new SquareMatrix(size);
+ SquareMatrix A1 = new SquareMatrix(size);
+ SquareMatrix Am = new SquareMatrix(size);
+ println(" done.");
+
+ double singleThread = elapsedTime(out, A, A1, size, 1);
+ double multiThreads = elapsedTime(out, A, Am, size, threads);
+
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ if (A1.value[line][column] != Am.value[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Different results by single- and multi-threads:");
+ complain(" line=" + line + ", column=" + column);
+ complain("A1.value[line][column]=" + A1.value[line][column]);
+ complain("Am.value[line][column]=" + Am.value[line][column]);
+ return 2; // FAILED
+ }
+ println(" done.");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ double elapsed1 = singleThread;
+ double elapsedM = multiThreads * numberOfCPU;
+ if (elapsed1 > elapsedM * (1 + TOLERANCE / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("Single-thread calculation is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" single thread: " + singleThread);
+ complain(" multi-threads: " + multiThreads);
+ complain(" number of CPU: " + numberOfCPU);
+ complain(" tolerance: " + TOLERANCE + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ private static double elapsedTime(PrintStream out,
+ SquareMatrix A, SquareMatrix AA, int size, int threads) {
+
+ print("Computing A*A with " + threads + " thread(s):");
+ long mark1 = System.currentTimeMillis();
+ AA.setSquareOf(A, threads);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MFLOPS");
+
+ return sec;
+ }
+
+ /**
+ * This class computes A*A for square matrix A.
+ */
+ private static class SquareMatrix {
+ volatile long value[][];
+
+ /**
+ * New square matrix with random elements.
+ */
+ public SquareMatrix(int size) {
+ value = new long[size][size];
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ value[line][column] = Math.round(Math.random() * size);
+ }
+
+ /**
+ * Update value[][] of this matrix.
+ *
+ * @param threads Split computation into the given number of threads.
+ */
+ public void setSquareOf(SquareMatrix A, int threads) {
+ if (this.value.length != A.value.length)
+ throw new IllegalArgumentException(
+ "this.value.length != A.value.length");
+
+ int size = value.length;
+ if ((size % threads) != 0)
+ throw new IllegalArgumentException("size%threads != 0");
+ int bunch = size / threads;
+
+ Thread task[] = new Thread[threads];
+ for (int t = 0; t < threads; t++) {
+ int line0 = bunch * t;
+ MatrixComputer computer =
+ new MatrixComputer(value, A.value, line0, bunch);
+ task[t] = new Thread(computer);
+ }
+
+ for (int t = 0; t < threads; t++)
+ task[t].start();
+
+ for (int t = 0; t < threads; t++)
+ if (task[t].isAlive())
+ try {
+ task[t].join();
+ } catch (InterruptedException exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ }
+
+ /**
+ * Thread to compute a bunch of lines of matrix square.
+ */
+ private static class MatrixComputer implements Runnable {
+ private long result[][];
+ private long source[][];
+ private int line0;
+ private int bunch;
+
+ /**
+ * Register a task for matrix multiplication.
+ */
+ public MatrixComputer(
+ long result[][], long source[][], int line0, int bunch) {
+
+ this.result = result; // reference to resulting matrix value
+ this.source = source; // reference to matrix to be squared
+ this.line0 = line0; // compute lines from line0 to ...
+ this.bunch = bunch; // number of resulting lines to compute
+ }
+
+ /**
+ * Do execute the task just registered for this thread.
+ */
+ public void run() {
+ int line1 = line0 + bunch;
+ int size = result.length;
+ for (int line = line0; line < line1; line++)
+ for (int column = 0; column < size; column++) {
+ long sum = 0;
+ for (int i = 0; i < size; i++)
+ sum += source[line][i] * source[i][column];
+ result[line][column] = sum;
+ }
+ }
+
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric004.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric004.java
new file mode 100644
index 00000000000..c37ce0db84b
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric004.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric004.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A of the type
+ * int[][]. Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * That product A*A is calculated twice: in a single thread, and in N
+ * separate threads, where NxN is the size of square matrix A. When executing
+ * in N threads, each thread calculate distinct row of the resulting matrix.
+ * The test checks if the resulting product A*A is the same when calculated
+ * in single thread and in N threads.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs installed
+ * on the platform executing the test is taken into account for performance
+ * testing). Note, that HotSpot may fail to adjust itself for better
+ * performance in single-thread calculation.
+ * COMMENTS
+ * The bug was filed referencing to the same numeric algorithm,
+ * which is used by this test:
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ *
+ * @run main/othervm nsk.stress.numeric.numeric004.numeric004 300 300
+ */
+
+package nsk.stress.numeric.numeric004;
+
+import java.io.PrintStream;
+
+/**
+ * This test calculates the product A.A for
+ * a square matrix A of the type int[][].
+ * Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ *
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric004 {
+ /**
+ * When testing performance, single thread calculation is allowed to
+ * be 10% slower than multi-threads calculation (TOLERANCE
+ * is assigned to 10 now).
+ */
+ public static final double TOLERANCE = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ */
+ private static boolean verbose = false;
+
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message to the out for
+ * a square matrix .
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke for
+ * a square matrix run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric004 [-verbose] [-performance] [-CPU:number]
+ * matrixSize [threads]
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
number -
+ * number of CPU installed on the computer just executing the test
+ *
matrixSize -
+ * number of rows (and columns) in square matrix to be tested
+ *
threads -
+ * for multi-thread calculation
+ * (default: matrixSize)
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric004.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ if (argument.startsWith("-CPU:")) {
+ String value =
+ argument.substring("-CPU:".length(), argument.length());
+ numberOfCPU = Integer.parseInt(value);
+
+ if (numberOfCPU < 1) {
+ complain("Illegal number of CPU: " + argument);
+ return 2; // failure
+ }
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if ((args.length < argsShift + 1) || (args.length > argsShift + 2)) {
+ complain("Illegal argument(s). Execute:");
+ complain(
+ " java numeric004 [-verbose] [-performance] [-CPU:number] " +
+ "matrixSize [threads]");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int threads = size;
+ if (args.length >= argsShift + 2)
+ threads = Integer.parseInt(args[argsShift + 1]);
+ if ((threads < 1) || (threads > size)) {
+ complain("Threads number should be 1 to matrix size.");
+ return 2; // failure
+ }
+ if ((size % threads) != 0) {
+ complain("Threads number should evenly divide matrix size.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ SquareMatrix A = new SquareMatrix(size);
+ SquareMatrix A1 = new SquareMatrix(size);
+ SquareMatrix Am = new SquareMatrix(size);
+ println(" done.");
+
+ double singleThread = elapsedTime(out, A, A1, size, 1);
+ double multiThreads = elapsedTime(out, A, Am, size, threads);
+
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ if (A1.value[line][column] != Am.value[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Different results by single- and multi-threads:");
+ complain(" line=" + line + ", column=" + column);
+ complain("A1.value[line][column]=" + A1.value[line][column]);
+ complain("Am.value[line][column]=" + Am.value[line][column]);
+ return 2; // FAILED
+ }
+ println(" done.");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ double elapsed1 = singleThread;
+ double elapsedM = multiThreads * numberOfCPU;
+ if (elapsed1 > elapsedM * (1 + TOLERANCE / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("Single-thread calculation is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" single thread: " + singleThread);
+ complain(" multi-threads: " + multiThreads);
+ complain(" number of CPU: " + numberOfCPU);
+ complain(" tolerance: " + TOLERANCE + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ private static double elapsedTime(PrintStream out,
+ SquareMatrix A, SquareMatrix AA, int size, int threads) {
+
+ print("Computing A*A with " + threads + " thread(s):");
+ long mark1 = System.currentTimeMillis();
+ AA.setSquareOf(A, threads);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MFLOPS");
+
+ return sec;
+ }
+
+ /**
+ * This class computes A*A for square matrix A.
+ */
+ private static class SquareMatrix {
+ volatile int value[][];
+
+ /**
+ * New square matrix with random elements.
+ */
+ public SquareMatrix(int size) {
+ value = new int[size][size];
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ value[line][column] = Math.round((float) (Math.random() * size));
+ }
+
+ /**
+ * Update value[][] of this matrix.
+ *
+ * @param threads Split computation into the given number of threads.
+ */
+ public void setSquareOf(SquareMatrix A, int threads) {
+ if (this.value.length != A.value.length)
+ throw new IllegalArgumentException(
+ "this.value.length != A.value.length");
+
+ int size = value.length;
+ if ((size % threads) != 0)
+ throw new IllegalArgumentException("size%threads != 0");
+ int bunch = size / threads;
+
+ Thread task[] = new Thread[threads];
+ for (int t = 0; t < threads; t++) {
+ int line0 = bunch * t;
+ MatrixComputer computer =
+ new MatrixComputer(value, A.value, line0, bunch);
+ task[t] = new Thread(computer);
+ }
+
+ for (int t = 0; t < threads; t++)
+ task[t].start();
+
+ for (int t = 0; t < threads; t++)
+ if (task[t].isAlive())
+ try {
+ task[t].join();
+ } catch (InterruptedException exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ }
+
+ /**
+ * Thread to compute a bunch of lines of matrix square.
+ */
+ private static class MatrixComputer implements Runnable {
+ private int result[][];
+ private int source[][];
+ private int line0;
+ private int bunch;
+
+ /**
+ * Register a task for matrix multiplication.
+ */
+ public MatrixComputer(
+ int result[][], int source[][], int line0, int bunch) {
+
+ this.result = result; // reference to resulting matrix value
+ this.source = source; // reference to matrix to be squared
+ this.line0 = line0; // compute lines from line0 to ...
+ this.bunch = bunch; // number of resulting lines to compute
+ }
+
+ /**
+ * Do execute the task just registered for this thread.
+ */
+ public void run() {
+ int line1 = line0 + bunch;
+ int size = result.length;
+ for (int line = line0; line < line1; line++)
+ for (int column = 0; column < size; column++) {
+ int sum = 0;
+ for (int i = 0; i < size; i++)
+ sum += source[line][i] * source[i][column];
+ result[line][column] = sum;
+ }
+ }
+
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric005.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric005.java
new file mode 100644
index 00000000000..8885ea1b191
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric005.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric005.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A of the type
+ * double[][]. Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * Calculation of the product A*A is iterated three times, and result of
+ * the 1st iteration is compared to result of the 3rd iteration. HotSpot
+ * releases 1.0 and 1.3 seem to fail to adjust itself for better performance
+ * in 1st iteration, while 3rd iteration usually runs much faster. So, the
+ * 1st iteration is probably executed by HotSpot interpreter, and HotSpot
+ * compiler is probably involved to execute the 3rd iteration. The test
+ * just tries to check if HotSpot compiler produces the same results as the
+ * HotSpot interpreter.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower than the
+ * 3rd iteration. The calculations algorithm is encoded as compact 3-levels
+ * cycle like:
+ * for (int line=0; lineA of the type double[][].
+ * Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * A.A is iterated three
+ * times, and result of the 1st iteration is compared to result of
+ * the 3rd iteration. HotSpot 1.0 and 1.3 seem to fail to adjust
+ * itself for better performance in 1st iteration, while 3rd
+ * iteration usually runs much faster. So, 1st iteration is probably
+ * executed by HotSpot interpreter, and HotSpot compiler is probably involved to
+ * execute the 3rd iteration. The test just tries to check if HotSpot
+ * compiler produces the same results as the HotSpot interpreter.
+ *
+ * for (int line=0; line<N; line++)
+ * for (int column=0; column<N; column++) {
+ * double sum = 0;
+ * for (int k=0; k<N; k++)
+ * sum += A[line][k] * A[k][column];
+ * AA[line][column] = sum;
+ * }
+ *
+ * N=300, so that A is 300x300 matrix;
+ * and multiplication A[line][k]*A[k][column] is executed
+ * 3003=27 millions times in each iteration of execution of this
+ * cycle. I believe, that this is HotSpot bug to do not adjust itself for best
+ * performance during such a huge series of executions of the same portion of
+ * program code.
+ *
+ * #4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric005 {
+ /**
+ * When testing performance, single thread calculation is allowed to
+ * be 10% slower than multi-threads calculation (TOLERANCE
+ * is assigned to 10 now).
+ */
+ public static final double TOLERANCE = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ *
+ * @see #print(Object)
+ * @see #println(Object)
+ */
+ private static boolean verbose = false;
+
+ /**
+ * Stream to print execution trace and/or error messages.
+ * This stream usually equals to System.out
+ */
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message.
+ *
+ * @see #out
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ /**
+ * Print to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ /**
+ * Print line to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric005 [-verbose] [-performance] matrixSize
+ * iterations
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
matrixSize -
+ * number of rows (and columns) in square matrix A
+ *
iterations -
+ * compute A*A several times
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric005.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ // Parse parameters starting with "-" (like: "-verbose"):
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if (args.length != argsShift + 2) {
+ complain("Illegal arguments. Execute:");
+ complain(
+ " java numeric005 [-verbose] [-performance] [-CPU:number] " +
+ "matrixSize iterations");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int iterations = Integer.parseInt(args[argsShift + 1]);
+ if ((iterations < 1) || (iterations > 100)) {
+ complain("Iterations number should be 1 to 100.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ double[][] A = newMatrix(size);
+ double[][] A1 = new double[size][size];
+ double[][] Ai = new double[size][size];
+ println(" done.");
+
+ println("Should try " + iterations + " iteration(s):");
+ println("==========================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("");
+
+ double overallTime = 0;
+ double firstTime = 0;
+ double lastTime = 0;
+
+ for (int i = 1; i <= iterations; i++) {
+ double seconds;
+
+ if (i == 1) {
+ seconds = elapsedTime(i, A, A1);
+ firstTime = seconds;
+ } else {
+ seconds = elapsedTime(i, A, Ai);
+ lastTime = seconds;
+ }
+
+ overallTime += seconds;
+ }
+
+ double averageTime = overallTime / iterations;
+ double averagePerformance = size * size * (size + size) / averageTime / 1e6;
+
+ println("");
+ println("=======================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("Overall iteration(s): " + iterations);
+ println("Overall elapsed time: " + overallTime + " seconds.");
+ println("Average elapsed time: " + averageTime + " seconds.");
+ println("Average performance: " + averagePerformance + " MFLOPS");
+
+ println("========================");
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ if (A1[line][column] != Ai[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Different results in 1st and last iterations:");
+ complain(" line=" + line + ", column=" + column);
+ return 2; // FAILED
+ }
+ println(" done.");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ if (firstTime > lastTime * (1 + TOLERANCE / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("1st iterartion is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" 1-st iteration: " + firstTime);
+ complain(" last iteration: " + lastTime);
+ complain(" tolerance: " + TOLERANCE + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ private static double elapsedTime(int i, double[][] A, double[][] AA) {
+ int size = A.length;
+
+ if (i > 1)
+ println("");
+ println("Iteration #" + i + ":");
+
+ print("Computing A*A:");
+ long mark1 = System.currentTimeMillis();
+ setSquare(A, AA);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MFLOPS");
+
+ return sec;
+ }
+
+ /**
+ * Compute A*A for the given square matrix A.
+ */
+ private static void setSquare(double[][] A, double[][] AA) {
+ if (A.length != A[0].length)
+ throw new IllegalArgumentException(
+ "the argument matrix A should be square matrix");
+ if (AA.length != AA[0].length)
+ throw new IllegalArgumentException(
+ "the resulting matrix AA should be square matrix");
+ if (A.length != AA.length)
+ throw new IllegalArgumentException(
+ "the matrices A and AA should have equal size");
+
+ int size = A.length;
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ double sum = 0;
+ for (int k = 0; k < size; k++)
+ sum += A[line][k] * A[k][line];
+ AA[line][column] = sum;
+ }
+ }
+
+ /**
+ * Generate new square matrix of the given size
+ * and with elements initiated with random numbers.
+ */
+ private static double[][] newMatrix(int size) {
+ if ((size < 1) || (size > 1000))
+ throw new IllegalArgumentException(
+ "matrix size should be 1 to 1000");
+
+ double[][] A = new double[size][size];
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ A[line][column] = (1 - 2 * Math.random()) * size;
+
+ return A;
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric006.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric006.java
new file mode 100644
index 00000000000..66383d5cde2
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric006.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric006.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A of the type
+ * float[][]. Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * Calculation of the product A*A is iterated three times, and result of
+ * the 1st iteration is compared to result of the 3rd iteration. HotSpot
+ * releases 1.0 and 1.3 seem to fail to adjust itself for better performance
+ * in 1st iteration, while 3rd iteration usually runs much faster. So, the
+ * 1st iteration is probably executed by HotSpot interpreter, and HotSpot
+ * compiler is probably involved to execute the 3rd iteration. The test
+ * just tries to check if HotSpot compiler produces the same results as the
+ * HotSpot interpreter.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower than the
+ * 3rd iteration. The calculations algorithm is encoded as compact 3-levels
+ * cycle like:
+ * for (int line=0; lineA of the type float[][].
+ * Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * A.A is iterated three
+ * times, and result of the 1st iteration is compared to result of
+ * the 3rd iteration. HotSpot 1.0 and 1.3 seem to fail to adjust
+ * itself for better performance in 1st iteration, while 3rd
+ * iteration usually runs much faster. So, 1st iteration is probably
+ * executed by HotSpot interpreter, and HotSpot compiler is probably involved to
+ * execute the 3rd iteration. The test just tries to check if HotSpot
+ * compiler produces the same results as the HotSpot interpreter.
+ *
+ * for (int line=0; line<N; line++)
+ * for (int column=0; column<N; column++) {
+ * float sum = 0;
+ * for (int k=0; k<N; k++)
+ * sum += A[line][k] * A[k][column];
+ * AA[line][column] = sum;
+ * }
+ *
+ * N=300, so that A is 300x300 matrix;
+ * and multiplication A[line][k]*A[k][column] is executed
+ * 3003=27 millions times in each iteration of execution of this
+ * cycle. I believe, that this is HotSpot bug to do not adjust itself for best
+ * performance during such a huge series of executions of the same portion of
+ * program code.
+ *
+ * #4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric006 {
+ /**
+ * When testing performance, single thread calculation is allowed to
+ * be 10% slower than multi-threads calculation (TOLERANCE
+ * is assigned to 10 now).
+ */
+ public static final double TOLERANCE = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ *
+ * @see #print(Object)
+ * @see #println(Object)
+ */
+ private static boolean verbose = false;
+
+ /**
+ * Stream to print execution trace and/or error messages.
+ * This stream usually equals to System.out
+ */
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message.
+ *
+ * @see #out
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ /**
+ * Print to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ /**
+ * Print line to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric006 [-verbose] [-performance] matrixSize
+ * iterations
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
matrixSize -
+ * number of rows (and columns) in square matrix A
+ *
iterations -
+ * compute A*A several times
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric006.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ // Parse parameters starting with "-" (like: "-verbose"):
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if (args.length != argsShift + 2) {
+ complain("Illegal arguments. Execute:");
+ complain(
+ " java numeric006 [-verbose] [-performance] [-CPU:number] " +
+ "matrixSize iterations");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int iterations = Integer.parseInt(args[argsShift + 1]);
+ if ((iterations < 1) || (iterations > 100)) {
+ complain("Iterations number should be 1 to 100.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ float[][] A = newMatrix(size);
+ float[][] A1 = new float[size][size];
+ float[][] Ai = new float[size][size];
+ println(" done.");
+
+ println("Should try " + iterations + " iteration(s):");
+ println("==========================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("");
+
+ double overallTime = 0;
+ double firstTime = 0;
+ double lastTime = 0;
+
+ for (int i = 1; i <= iterations; i++) {
+ double seconds;
+
+ if (i == 1) {
+ seconds = elapsedTime(i, A, A1);
+ firstTime = seconds;
+ } else {
+ seconds = elapsedTime(i, A, Ai);
+ lastTime = seconds;
+ }
+
+ overallTime += seconds;
+ }
+
+ double averageTime = overallTime / iterations;
+ double averagePerformance = size * size * (size + size) / averageTime / 1e6;
+
+ println("");
+ println("=======================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("Overall iteration(s): " + iterations);
+ println("Overall elapsed time: " + overallTime + " seconds.");
+ println("Average elapsed time: " + averageTime + " seconds.");
+ println("Average performance: " + averagePerformance + " MFLOPS");
+
+ println("========================");
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ if (A1[line][column] != Ai[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Different results in 1st and last iterations:");
+ complain(" line=" + line + ", column=" + column);
+ return 2; // FAILED
+ }
+ println(" done.");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ if (firstTime > lastTime * (1 + TOLERANCE / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("1st iterartion is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" 1-st iteration: " + firstTime);
+ complain(" last iteration: " + lastTime);
+ complain(" tolerance: " + TOLERANCE + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ private static double elapsedTime(int i, float[][] A, float[][] AA) {
+ int size = A.length;
+
+ if (i > 1)
+ println("");
+ println("Iteration #" + i + ":");
+
+ print("Computing A*A:");
+ long mark1 = System.currentTimeMillis();
+ setSquare(A, AA);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MFLOPS");
+
+ return sec;
+ }
+
+ /**
+ * Compute A*A for the given square matrix A.
+ */
+ private static void setSquare(float[][] A, float[][] AA) {
+ if (A.length != A[0].length)
+ throw new IllegalArgumentException(
+ "the argument matrix A should be square matrix");
+ if (AA.length != AA[0].length)
+ throw new IllegalArgumentException(
+ "the resulting matrix AA should be square matrix");
+ if (A.length != AA.length)
+ throw new IllegalArgumentException(
+ "the matrices A and AA should have equal size");
+
+ int size = A.length;
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ float sum = 0;
+ for (int k = 0; k < size; k++)
+ sum += A[line][k] * A[k][line];
+ AA[line][column] = sum;
+ }
+ }
+
+ /**
+ * Generate new square matrix of the given size
+ * and with elements initiated with random numbers.
+ */
+ private static float[][] newMatrix(int size) {
+ if ((size < 1) || (size > 1000))
+ throw new IllegalArgumentException(
+ "matrix size should be 1 to 1000");
+
+ float[][] A = new float[size][size];
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ A[line][column] = (float) ((1 - 2 * Math.random()) * size);
+
+ return A;
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric007.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric007.java
new file mode 100644
index 00000000000..bd4dbde4e20
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric007.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric007.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A of the type
+ * long[][]. Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * Calculation of the product A*A is iterated three times, and result of
+ * the 1st iteration is compared to result of the 3rd iteration. HotSpot
+ * releases 1.0 and 1.3 seem to fail to adjust itself for better performance
+ * in 1st iteration, while 3rd iteration usually runs much faster. So, the
+ * 1st iteration is probably executed by HotSpot interpreter, and HotSpot
+ * compiler is probably involved to execute the 3rd iteration. The test
+ * just tries to check if HotSpot compiler produces the same results as the
+ * HotSpot interpreter.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower than the
+ * 3rd iteration. The calculations algorithm is encoded as compact 3-levels
+ * cycle like:
+ * for (int line=0; lineA of the type long[][].
+ * Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * A.A is iterated three
+ * times, and result of the 1st iteration is compared to result of
+ * the 3rd iteration. HotSpot 1.0 and 1.3 seem to fail to adjust
+ * itself for better performance in 1st iteration, while 3rd
+ * iteration usually runs much faster. So, 1st iteration is probably
+ * executed by HotSpot interpreter, and HotSpot compiler is probably involved to
+ * execute the 3rd iteration. The test just tries to check if HotSpot
+ * compiler produces the same results as the HotSpot interpreter.
+ *
+ * for (int line=0; line<N; line++)
+ * for (int column=0; column<N; column++) {
+ * long sum = 0;
+ * for (int k=0; k<N; k++)
+ * sum += A[line][k] * A[k][column];
+ * AA[line][column] = sum;
+ * }
+ *
+ * N=300, so that A is 300x300 matrix;
+ * and multiplication A[line][k]*A[k][column] is executed
+ * 3003=27 millions times in each iteration of execution of this
+ * cycle. I believe, that this is HotSpot bug to do not adjust itself for best
+ * performance during such a huge series of executions of the same portion of
+ * program code.
+ *
+ * #4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric007 {
+ /**
+ * When testing performance, single thread calculation is allowed to
+ * be 10% slower than multi-threads calculation (TOLERANCE
+ * is assigned to 10 now).
+ */
+ public static final double TOLERANCE = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ *
+ * @see #print(Object)
+ * @see #println(Object)
+ */
+ private static boolean verbose = false;
+
+ /**
+ * Stream to print execution trace and/or error messages.
+ * This stream usually equals to System.out
+ */
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message.
+ *
+ * @see #out
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ /**
+ * Print to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ /**
+ * Print line to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric007 [-verbose] [-performance] matrixSize
+ * iterations
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
matrixSize -
+ * number of rows (and columns) in square matrix A
+ *
iterations -
+ * compute A*A several times
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric007.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ // Parse parameters starting with "-" (like: "-verbose"):
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if (args.length != argsShift + 2) {
+ complain("Illegal arguments. Execute:");
+ complain(
+ " java numeric007 [-verbose] [-performance] [-CPU:number] " +
+ "matrixSize iterations");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int iterations = Integer.parseInt(args[argsShift + 1]);
+ if ((iterations < 1) || (iterations > 100)) {
+ complain("Iterations number should be 1 to 100.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ long[][] A = newMatrix(size);
+ long[][] A1 = new long[size][size];
+ long[][] Ai = new long[size][size];
+ println(" done.");
+
+ println("Should try " + iterations + " iteration(s):");
+ println("==========================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("");
+
+ double overallTime = 0;
+ double firstTime = 0;
+ double lastTime = 0;
+
+ for (int i = 1; i <= iterations; i++) {
+ double seconds;
+
+ if (i == 1) {
+ seconds = elapsedTime(i, A, A1);
+ firstTime = seconds;
+ } else {
+ seconds = elapsedTime(i, A, Ai);
+ lastTime = seconds;
+ }
+
+ overallTime += seconds;
+ }
+
+ double averageTime = overallTime / iterations;
+ double averagePerformance = size * size * (size + size) / averageTime / 1e6;
+
+ println("");
+ println("=======================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("Overall iteration(s): " + iterations);
+ println("Overall elapsed time: " + overallTime + " seconds.");
+ println("Average elapsed time: " + averageTime + " seconds.");
+ println("Average performance: " + averagePerformance + " MFLOPS");
+
+ println("========================");
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ if (A1[line][column] != Ai[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Different results in 1st and last iterations:");
+ complain(" line=" + line + ", column=" + column);
+ return 2; // FAILED
+ }
+ println(" done.");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ if (firstTime > lastTime * (1 + TOLERANCE / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("1st iterartion is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" 1-st iteration: " + firstTime);
+ complain(" last iteration: " + lastTime);
+ complain(" tolerance: " + TOLERANCE + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ private static double elapsedTime(int i, long[][] A, long[][] AA) {
+ int size = A.length;
+
+ if (i > 1)
+ println("");
+ println("Iteration #" + i + ":");
+
+ print("Computing A*A:");
+ long mark1 = System.currentTimeMillis();
+ setSquare(A, AA);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MFLOPS");
+
+ return sec;
+ }
+
+ /**
+ * Compute A*A for the given square matrix A.
+ */
+ private static void setSquare(long[][] A, long[][] AA) {
+ if (A.length != A[0].length)
+ throw new IllegalArgumentException(
+ "the argument matrix A should be square matrix");
+ if (AA.length != AA[0].length)
+ throw new IllegalArgumentException(
+ "the resulting matrix AA should be square matrix");
+ if (A.length != AA.length)
+ throw new IllegalArgumentException(
+ "the matrices A and AA should have equal size");
+
+ int size = A.length;
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ long sum = 0;
+ for (int k = 0; k < size; k++)
+ sum += A[line][k] * A[k][line];
+ AA[line][column] = sum;
+ }
+ }
+
+ /**
+ * Generate new square matrix of the given size
+ * and with elements initiated with random numbers.
+ */
+ private static long[][] newMatrix(int size) {
+ if ((size < 1) || (size > 1000))
+ throw new IllegalArgumentException(
+ "matrix size should be 1 to 1000");
+
+ long[][] A = new long[size][size];
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ A[line][column] = Math.round((1 - 2 * Math.random()) * size);
+
+ return A;
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric008.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric008.java
new file mode 100644
index 00000000000..27ab9d31fe5
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric008.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric008.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A of the type
+ * int[][]. Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * Calculation of the product A*A is iterated three times, and result of
+ * the 1st iteration is compared to result of the 3rd iteration. HotSpot
+ * releases 1.0 and 1.3 seem to fail to adjust itself for better performance
+ * in 1st iteration, while 3rd iteration usually runs much faster. So, the
+ * 1st iteration is probably executed by HotSpot interpreter, and HotSpot
+ * compiler is probably involved to execute the 3rd iteration. The test
+ * just tries to check if HotSpot compiler produces the same results as the
+ * HotSpot interpreter.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower than the
+ * 3rd iteration. The calculations algorithm is encoded as compact 3-levels
+ * cycle like:
+ * for (int line=0; lineA of the type int[][].
+ * Elements of the matrix A are initiated with random numbers,
+ * so that optimizing compiler could not eliminate any essential portion
+ * of calculations.
+ * A.A is iterated three
+ * times, and result of the 1st iteration is compared to result of
+ * the 3rd iteration. HotSpot 1.0 and 1.3 seem to fail to adjust
+ * itself for better performance in 1st iteration, while 3rd
+ * iteration usually runs much faster. So, 1st iteration is probably
+ * executed by HotSpot interpreter, and HotSpot compiler is probably involved to
+ * execute the 3rd iteration. The test just tries to check if HotSpot
+ * compiler produces the same results as the HotSpot interpreter.
+ *
+ * for (int line=0; line<N; line++)
+ * for (int column=0; column<N; column++) {
+ * int sum = 0;
+ * for (int k=0; k<N; k++)
+ * sum += A[line][k] * A[k][column];
+ * AA[line][column] = sum;
+ * }
+ *
+ * N=300, so that A is 300x300 matrix;
+ * and multiplication A[line][k]*A[k][column] is executed
+ * 3003=27 millions times in each iteration of execution of this
+ * cycle. I believe, that this is HotSpot bug to do not adjust itself for best
+ * performance during such a huge series of executions of the same portion of
+ * program code.
+ *
+ * #4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric008 {
+ /**
+ * When testing performance, single thread calculation is allowed to
+ * be 10% slower than multi-threads calculation (TOLERANCE
+ * is assigned to 10 now).
+ */
+ public static final double TOLERANCE = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ *
+ * @see #print(Object)
+ * @see #println(Object)
+ */
+ private static boolean verbose = false;
+
+ /**
+ * Stream to print execution trace and/or error messages.
+ * This stream usually equals to System.out
+ */
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message.
+ *
+ * @see #out
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ /**
+ * Print to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ /**
+ * Print line to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric008 [-verbose] [-performance] matrixSize
+ * iterations
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
matrixSize -
+ * number of rows (and columns) in square matrix A
+ *
iterations -
+ * compute A*A several times
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric008.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ // Parse parameters starting with "-" (like: "-verbose"):
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if (args.length != argsShift + 2) {
+ complain("Illegal arguments. Execute:");
+ complain(
+ " java numeric008 [-verbose] [-performance] [-CPU:number] " +
+ "matrixSize iterations");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int iterations = Integer.parseInt(args[argsShift + 1]);
+ if ((iterations < 1) || (iterations > 100)) {
+ complain("Iterations number should be 1 to 100.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ int[][] A = newMatrix(size);
+ int[][] A1 = new int[size][size];
+ int[][] Ai = new int[size][size];
+ println(" done.");
+
+ println("Should try " + iterations + " iteration(s):");
+ println("==========================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("");
+
+ double overallTime = 0;
+ double firstTime = 0;
+ double lastTime = 0;
+
+ for (int i = 1; i <= iterations; i++) {
+ double seconds;
+
+ if (i == 1) {
+ seconds = elapsedTime(i, A, A1);
+ firstTime = seconds;
+ } else {
+ seconds = elapsedTime(i, A, Ai);
+ lastTime = seconds;
+ }
+
+ overallTime += seconds;
+ }
+
+ double averageTime = overallTime / iterations;
+ double averagePerformance = size * size * (size + size) / averageTime / 1e6;
+
+ println("");
+ println("=======================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("Overall iteration(s): " + iterations);
+ println("Overall elapsed time: " + overallTime + " seconds.");
+ println("Average elapsed time: " + averageTime + " seconds.");
+ println("Average performance: " + averagePerformance + " MFLOPS");
+
+ println("========================");
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ if (A1[line][column] != Ai[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Different results in 1st and last iterations:");
+ complain(" line=" + line + ", column=" + column);
+ return 2; // FAILED
+ }
+ println(" done.");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ if (firstTime > lastTime * (1 + TOLERANCE / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("1st iterartion is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" 1-st iteration: " + firstTime);
+ complain(" last iteration: " + lastTime);
+ complain(" tolerance: " + TOLERANCE + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ private static double elapsedTime(int i, int[][] A, int[][] AA) {
+ int size = A.length;
+
+ if (i > 1)
+ println("");
+ println("Iteration #" + i + ":");
+
+ print("Computing A*A:");
+ long mark1 = System.currentTimeMillis();
+ setSquare(A, AA);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MFLOPS");
+
+ return sec;
+ }
+
+ /**
+ * Compute A*A for the given square matrix A.
+ */
+ private static void setSquare(int[][] A, int[][] AA) {
+ if (A.length != A[0].length)
+ throw new IllegalArgumentException(
+ "the argument matrix A should be square matrix");
+ if (AA.length != AA[0].length)
+ throw new IllegalArgumentException(
+ "the resulting matrix AA should be square matrix");
+ if (A.length != AA.length)
+ throw new IllegalArgumentException(
+ "the matrices A and AA should have equal size");
+
+ int size = A.length;
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ int sum = 0;
+ for (int k = 0; k < size; k++)
+ sum += A[line][k] * A[k][line];
+ AA[line][column] = sum;
+ }
+ }
+
+ /**
+ * Generate new square matrix of the given size
+ * and with elements initiated with random numbers.
+ */
+ private static int[][] newMatrix(int size) {
+ if ((size < 1) || (size > 1000))
+ throw new IllegalArgumentException(
+ "matrix size should be 1 to 1000");
+
+ int[][] A = new int[size][size];
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ A[line][column] = Math.round((float) ((1 - 2 * Math.random()) * size));
+
+ return A;
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric009.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric009.java
new file mode 100644
index 00000000000..5ecce624825
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric009.java
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric009.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A, and checks
+ * if such product is calculated correctly. Elements of the matrix A are
+ * initiated with integer numbers, so that A*A must be the same if calculated
+ * with double, float, long, or int precision. The test just checks, if
+ * double, float, long, and int variants of the product calculation result
+ * in the same A*A matrix.
+ * Calculation of the product A*A is iterated two times, because HotSpot
+ * releases 1.0 and 1.3 seem to do not adjust JVM for better performance
+ * in 1st iteration, while 2nd iteration usually runs much faster. I guess,
+ * that the 1st iteration is probably executed by HotSpot interpreter, and
+ * HotSpot compiler is probably involved to execute the 2nd iteration. So,
+ * the test apparently checks accuracy of A*A calculation in both compilation
+ * and interpretation modes.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if 1st iteration is essentially slower than the
+ * 2nd iteration. The calculations algorithm is encoded as rather compact
+ * 3-levels cycle like:
+ * for (int line=0; lineA, and checks if such product is calculated correctly.
+ * Elements of the matrix A are initiated with integer numbers,
+ * so that A.A must be the same if calculated with
+ * double, float, long, or
+ * int precision. The test just checks, if double,
+ * float, long, and int variants of
+ * the product calculation result in the same A.A
+ * matrix.
+ * A.A is iterated two
+ * times, because HotSpot releases 1.0 and 1.3 seem to do not adjust JVM for
+ * better performance in 1st iteration, while 2nd
+ * iteration usually runs much faster. I guess, that the 1st iteration
+ * is probably executed by HotSpot interpreter, and HotSpot compiler is probably
+ * involved to execute the 2nd iteration. So, the test apparently
+ * checks accuracy of A.A calculation in both compilation
+ * and interpretation modes.
+ *
+ * for (int line=0; line<N; line++)
+ * for (int column=0; column<N; column++) {
+ * float sum = 0;
+ * for (int k=0; k<N; k++)
+ * sum += A[line][k] * A[k][column];
+ * AA[line][column] = sum;
+ * }
+ *
+ * N=200, so that A is 200x200 matrix;
+ * and multiplication A[line][k]*A[k][column] is executed
+ * 2003=8 millions times in each iteration of execution of this
+ * cycle. I believe, that this is HotSpot bug to do not adjust JVM for best
+ * performance during such a huge series of executions of the rather compact
+ * portion of program code.
+ *
+ * #4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric009 {
+ /**
+ * When testing performance, 1st iteration is allowed to be 10% slower
+ * than 2nd iteration (tolerance is assigned to 10 now).
+ */
+ public static double tolerance = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better
+ * diagnostics.
+ *
+ * @see #print(Object)
+ * @see #println(Object)
+ */
+ private static boolean verbose = false;
+
+ /**
+ * Stream to print execution trace and/or error messages.
+ * This stream usually equals to System.out
+ */
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message.
+ *
+ * @see #out
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ /**
+ * Print to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ /**
+ * Print line to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric009 [-verbose] [-performance]
+ * [-tolerance:percents]
+ * matrixSize iterations
+ *
-verbose -
+ * keyword alowing to print execution trace
+ *
-performance -
+ * keyword turning on performance testing
+ *
-tolerance -
+ * setup tolerance of performance checking
+ *
percents -
+ * 1st iteration is allowed to be
+ * percents% slower
+ *
matrixSize -
+ * number of rows (and columns) in square matrix A
+ *
iterations -
+ * how many times to execute the test for stronger checking
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric009.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ // Parse parameters starting with "-" (like: "-verbose"):
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ if (argument.startsWith("-tolerance:")) {
+ String percents =
+ argument.substring("-tolerance:".length(), argument.length());
+ tolerance = Integer.parseInt(percents);
+ if ((tolerance < 0) || (tolerance > 100)) {
+ complain("Tolerance should be 0 to 100%: " + argument);
+ return 2; // failure
+ }
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if (args.length != argsShift + 2) {
+ complain("Illegal arguments. Execute:");
+ complain(
+ " java numeric009 [-verbose] [-performance] " +
+ "[-tolerance:percents] matrixSize iterations");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int iterations = Integer.parseInt(args[argsShift + 1]);
+ if ((iterations < 1) || (iterations > 100)) {
+ complain("Iterations number should be 1 to 100.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ int[][] intA = newIntegerMatrix(size);
+ int[][] intAA = new int[size][size];
+ long[][] longA = newLongMatrix(intA);
+ long[][] longAA = new long[size][size];
+ double[][] doubleA = newDoubleMatrix(intA);
+ double[][] doubleAA = new double[size][size];
+ float[][] floatA = newFloatMatrix(intA);
+ float[][] floatAA = new float[size][size];
+ println(" done.");
+
+ println("Should try " + iterations + " iteration(s):");
+ println("==========================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("");
+
+ double overallTime = 0;
+ double firstTime = 0;
+ double lastTime = 0;
+
+ for (int i = 1; i <= iterations; i++) {
+ double seconds = elapsedTime(i,
+ intA, intAA, longA, longAA, floatA, floatAA, doubleA, doubleAA);
+
+ if (i == 1)
+ firstTime = seconds;
+ else
+ lastTime = seconds;
+ overallTime += seconds;
+
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ if (intAA[line][column] != longAA[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Integer and Long results differ at:");
+ complain(" line=" + line + ", column=" + column);
+ return 2; // FAILED
+ }
+ if (intAA[line][column] != floatAA[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Integer and Float results differ at:");
+ complain(" line=" + line + ", column=" + column);
+ return 2; // FAILED
+ }
+ if (intAA[line][column] != doubleAA[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Integer and Double results differ at:");
+ complain(" line=" + line + ", column=" + column);
+ return 2; // FAILED
+ }
+ }
+ println(" done.");
+ }
+
+ double averageTime = overallTime / iterations / 4;
+ double averagePerformance = size * size * (size + size) / averageTime / 1e6;
+
+ println("");
+ println("=======================" +
+ ((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
+ println("Overall iteration(s): " + iterations);
+ println("Overall elapsed time: " + overallTime + " seconds.");
+ println("Average elapsed time: " + averageTime + " seconds.");
+ println("Average performance: " + averagePerformance + " MFLOPS");
+
+ if (testPerformance) {
+ print("Checking performance: ");
+ if (firstTime > lastTime * (1 + tolerance / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("1st iterartion is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" 1-st iteration: " + firstTime);
+ complain(" last iteration: " + lastTime);
+ complain(" tolerance: " + tolerance + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ /**
+ * Return time (in seconds) elapsed for calculation of matrix
+ * product A*A with int, long,
+ * float, and double representations.
+ */
+ private static double elapsedTime(int i,
+ int[][] intA, int[][] intAA,
+ long[][] longA, long[][] longAA,
+ float[][] floatA, float[][] floatAA,
+ double[][] doubleA, double[][] doubleAA) {
+
+ int size = intA.length;
+
+ if (i > 1)
+ println("");
+ println("Iteration #" + i + ":");
+
+ print("Computing int, long, float, and double A*A:");
+ long mark1 = System.currentTimeMillis();
+ setSquare(intA, intAA);
+ setSquare(longA, longAA);
+ setSquare(floatA, floatAA);
+ setSquare(doubleA, doubleAA);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = size * size * (size + size) / (sec / 4);
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MOPS");
+
+ return sec;
+ }
+
+ /**
+ * Compute A*A for the given square matrix A.
+ */
+ private static void setSquare(int[][] A, int[][] AA) {
+ if (A.length != A[0].length)
+ throw new IllegalArgumentException(
+ "the argument matrix A should be square matrix");
+ if (AA.length != AA[0].length)
+ throw new IllegalArgumentException(
+ "the resulting matrix AA should be square matrix");
+ if (A.length != AA.length)
+ throw new IllegalArgumentException(
+ "the matrices A and AA should have equal size");
+
+ int size = A.length;
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ int sum = 0;
+ for (int k = 0; k < size; k++)
+ sum += A[line][k] * A[k][line];
+ AA[line][column] = sum;
+ }
+ }
+
+ /**
+ * Compute A*A for the given square matrix A.
+ */
+ private static void setSquare(long[][] A, long[][] AA) {
+ if (A.length != A[0].length)
+ throw new IllegalArgumentException(
+ "the argument matrix A should be square matrix");
+ if (AA.length != AA[0].length)
+ throw new IllegalArgumentException(
+ "the resulting matrix AA should be square matrix");
+ if (A.length != AA.length)
+ throw new IllegalArgumentException(
+ "the matrices A and AA should have equal size");
+
+ int size = A.length;
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ long sum = 0;
+ for (int k = 0; k < size; k++)
+ sum += A[line][k] * A[k][line];
+ AA[line][column] = sum;
+ }
+ }
+
+ /**
+ * Compute A*A for the given square matrix A.
+ */
+ private static void setSquare(float[][] A, float[][] AA) {
+ if (A.length != A[0].length)
+ throw new IllegalArgumentException(
+ "the argument matrix A should be square matrix");
+ if (AA.length != AA[0].length)
+ throw new IllegalArgumentException(
+ "the resulting matrix AA should be square matrix");
+ if (A.length != AA.length)
+ throw new IllegalArgumentException(
+ "the matrices A and AA should have equal size");
+
+ int size = A.length;
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ float sum = 0;
+ for (int k = 0; k < size; k++)
+ sum += A[line][k] * A[k][line];
+ AA[line][column] = sum;
+ }
+ }
+
+ /**
+ * Compute A*A for the given square matrix A.
+ */
+ private static void setSquare(double[][] A, double[][] AA) {
+ if (A.length != A[0].length)
+ throw new IllegalArgumentException(
+ "the argument matrix A should be square matrix");
+ if (AA.length != AA[0].length)
+ throw new IllegalArgumentException(
+ "the resulting matrix AA should be square matrix");
+ if (A.length != AA.length)
+ throw new IllegalArgumentException(
+ "the matrices A and AA should have equal size");
+
+ int size = A.length;
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ double sum = 0;
+ for (int k = 0; k < size; k++)
+ sum += A[line][k] * A[k][line];
+ AA[line][column] = sum;
+ }
+ }
+
+ /**
+ * Generate new square matrix of the given size
+ * and with elements initiated with random numbers.
+ */
+ private static int[][] newIntegerMatrix(int size) {
+ if ((size < 1) || (size > 1000))
+ throw new IllegalArgumentException(
+ "matrix size should be 1 to 1000");
+
+ int[][] A = new int[size][size];
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ A[line][column] =
+ Math.round((float) ((1 - 2 * Math.random()) * size));
+
+ return A;
+ }
+
+ /**
+ * Generate new square matrix with long elements,
+ * and initiate them with the same values as in the given matrix
+ * intA.
+ */
+ private static long[][] newLongMatrix(int[][] intA) {
+ if (intA.length != intA[0].length)
+ throw new IllegalArgumentException(
+ "need square argument matrix");
+
+ int size = intA.length;
+ long[][] longA = new long[size][size];
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ longA[line][column] = intA[line][column];
+
+ return longA;
+ }
+
+ /**
+ * Generate new square matrix with double elements,
+ * and initiate them with the same values as in the given matrix
+ * intA.
+ */
+ private static double[][] newDoubleMatrix(int[][] intA) {
+ if (intA.length != intA[0].length)
+ throw new IllegalArgumentException(
+ "need square argument matrix");
+
+ int size = intA.length;
+ double[][] doubleA = new double[size][size];
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ doubleA[line][column] = intA[line][column];
+
+ return doubleA;
+ }
+
+ /**
+ * Generate new square matrix with float elements,
+ * and initiate them with the same values as in the given matrix
+ * intA.
+ */
+ private static float[][] newFloatMatrix(int[][] intA) {
+ if (intA.length != intA[0].length)
+ throw new IllegalArgumentException(
+ "need square argument matrix");
+
+ int size = intA.length;
+ float[][] floatA = new float[size][size];
+
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ floatA[line][column] = intA[line][column];
+
+ return floatA;
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric010.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric010.java
new file mode 100644
index 00000000000..63db9c04060
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric010.java
@@ -0,0 +1,809 @@
+/*
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/numeric/numeric010.
+ * VM testbase keywords: [stress, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test calculates the product A*A for a square matrix A, and checks
+ * if such product is calculated correctly. Elements of the matrix A are
+ * initiated with integer numbers, so that A*A must be the same if calculated
+ * with double, float, long, or int precision. The test just checks, if
+ * double, float, long, and int variants of the product calculation result
+ * in the same A*A matrix.
+ * The product A*A is calculated twice: in a single thread, and in N separate
+ * threads, where NxN is the size of square matrix A. When executing in N
+ * threads, each thread calculate distinct row of the resulting matrix.
+ * HotSpot releases 1.0 and 1.3 seem to do not adjust JVM for better
+ * performance in single-thread calculation, while milti-threads calculation
+ * usually runs much faster. I guess, that the 1-thread calculation is probably
+ * executed by HotSpot interpreter, and HotSpot compiler is probably involved
+ * to execute N-threads calculation. So, the test apparently checks accuracy
+ * of A*A calculation in both compilation and interpretation modes.
+ * By the way, the test checks JVM performance. The test is treated failed
+ * due to poor performance, if single-thread calculation is essentially
+ * slower than N-threads calculation (surely, the number of CPUs installed
+ * on the platform executing the test is taken into account for performance
+ * testing). The calculation algorithm is encoded with 3-levels cycle like:
+ * for (int line=0; lineA, and checks if such product is calculated correctly.
+ * Elements of the matrix A are initiated with integer numbers,
+ * so that A.A must be the same if calculated with
+ * double, float, long, or
+ * int precision. The test just checks, if double,
+ * float, long, and int variants of
+ * the product calculation result in the same A.A
+ * matrix.
+ * A.A is calculated twice: in a single
+ * thread, and in N separate threads, where NxN is
+ * the size of square matrix A. When executing in N
+ * threads, each thread calculate distinct row of the resulting matrix. HotSpot
+ * releases 1.0 and 1.3 seem to do not adjust JVM for better performance in
+ * single-thread calculation, while milti-threads calculation usually runs much
+ * faster. I guess, that the 1-thread calculation is probably executed by HotSpot
+ * interpreter, and HotSpot compiler is probably involved to execute
+ * N-threads calculation. So, the test apparently checks accuracy
+ * of A.A calculation in both compilation and
+ * interpretation modes.
+ * N-threads calculation (surely, the number of CPUs
+ * installed on the platform executing the test is taken into account for
+ * performance testing). The calculation algorithm is encoded with 3-levels
+ * cycle like:
+ *
+ * for (int line=0; line<N; line++)
+ * for (int column=0; column<N; column++) {
+ * float sum = 0;
+ * for (int k=0; k<N; k++)
+ * sum += A[line][k] * A[k][column];
+ * AA[line][column] = sum;
+ * }
+ *
+ * N=200, so that A is 200x200 matrix;
+ * and multiplication A[line][k]*A[k][column] is executed
+ * 2003=8 millions times in this cycle. I believe, that this is HotSpot
+ * bug to do not adjust JVM for best performance during such a huge series of
+ * executions of the rather compact portion of program code.
+ *
+ * 4242172 (P3/S5) 2.0: poor performance in matrix calculations
+ */
+public class numeric010 {
+ /**
+ * When testing performance, 1-thread calculation is allowed to be 10%
+ * slower than multi-thread calculation (tolerance is
+ * assigned to 10 now).
+ */
+ public static double tolerance = 100; // 10;
+
+ /**
+ * Re-assign this value to true for better diagnostics.
+ *
+ * @see #print(Object)
+ * @see #println(Object)
+ */
+ private static boolean verbose = false;
+
+ /**
+ * Stream to print execution trace and/or error messages.
+ * This stream usually equals to System.out
+ */
+ private static PrintStream out = null;
+
+ /**
+ * Print error-message.
+ *
+ * @see #out
+ */
+ private static void complain(Object x) {
+ out.println("# " + x);
+ }
+
+ /**
+ * Print to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void print(Object x) {
+ if (verbose)
+ out.print(x);
+ }
+
+ /**
+ * Print line to execution trace, if mode is verbose.
+ *
+ * @see #verbose
+ * @see #out
+ */
+ private static void println(Object x) {
+ print(x + "\n");
+ }
+
+ /**
+ * Re-invoke run(args,out) in order to simulate
+ * JCK-like test interface.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ // JCK-like exit status
+ }
+
+ /**
+ * Parse command-line parameters stored in args[] and run
+ * the test.
+ *
+ * java numeric010 [-verbose] [-performance]
+ * [-tolerance:percents] [-CPU:number]
+ * matrixSize [threads]
+ *
-verbose -
+ * keyword, which alows to print execution trace
+ *
-performance -
+ * keyword, which alows performance testing
+ *
-tolerance -
+ * setup tolerance of performance checking
+ *
percents -
+ * 1-thread calculation is allowed to be
+ * percents% slower
+ *
number -
+ * number of CPU installed on the computer just executing the test
+ *
matrixSize -
+ * number of rows (and columns) in square matrix to be tested
+ *
threads -
+ * for multi-thread calculation
+ * (default: matrixSize)
+ *
+ * @param args strings array containing command-line parameters
+ * @param out the test log, usually System.out
+ */
+ public static int run(String args[], PrintStream out) {
+ numeric010.out = out;
+
+ boolean testPerformance = false;
+ int numberOfCPU = 1;
+
+ int argsShift = 0;
+ for (; argsShift < args.length; argsShift++) {
+ String argument = args[argsShift];
+
+ if (!argument.startsWith("-"))
+ break;
+
+ if (argument.equals("-performance")) {
+ testPerformance = true;
+ continue;
+ }
+
+ if (argument.equals("-verbose")) {
+ verbose = true;
+ continue;
+ }
+
+ if (argument.startsWith("-tolerance:")) {
+ String percents =
+ argument.substring("-tolerance:".length(), argument.length());
+ tolerance = Integer.parseInt(percents);
+
+ if ((tolerance < 0) || (tolerance > 100)) {
+ complain("Tolerance should be 0 to 100%: " + argument);
+ return 2; // failure
+ }
+ continue;
+ }
+
+ if (argument.startsWith("-CPU:")) {
+ String value =
+ argument.substring("-CPU:".length(), argument.length());
+ numberOfCPU = Integer.parseInt(value);
+
+ if (numberOfCPU < 1) {
+ complain("Illegal number of CPU: " + argument);
+ return 2; // failure
+ }
+ continue;
+ }
+
+ complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
+ return 2; // failure
+ }
+
+ if ((args.length < argsShift + 1) || (args.length > argsShift + 2)) {
+ complain("Illegal argument(s). Execute:");
+ complain(
+ " java numeric010 [-verbose] [-performance] " +
+ "[-tolerance:percents] [-CPU:number] matrixSize [threads]");
+ return 2; // failure
+ }
+
+ int size = Integer.parseInt(args[argsShift]);
+ if ((size < 100) || (size > 10000)) {
+ complain("Matrix size should be 100 to 1000 lines & columns.");
+ return 2; // failure
+ }
+
+ int threads = size;
+ if (args.length >= argsShift + 2)
+ threads = Integer.parseInt(args[argsShift + 1]);
+ if ((threads < 1) || (threads > size)) {
+ complain("Threads number should be 1 to matrix size.");
+ return 2; // failure
+ }
+ if ((size % threads) != 0) {
+ complain("Threads number should evenly divide matrix size.");
+ return 2; // failure
+ }
+
+ print("Preparing A[" + size + "," + size + "]:");
+ IntegerMatrix intA = new IntegerMatrix(size);
+ IntegerMatrix intAA = new IntegerMatrix(size);
+ LongMatrix longA = new LongMatrix(intA);
+ LongMatrix longAA = new LongMatrix(intA);
+ FloatMatrix floatA = new FloatMatrix(intA);
+ FloatMatrix floatAA = new FloatMatrix(intA);
+ DoubleMatrix doubleA = new DoubleMatrix(intA);
+ DoubleMatrix doubleAA = new DoubleMatrix(intA);
+ println(" done.");
+
+ double elapsed[] = {0, 0};
+
+ for (int i = 0; i < 2; i++) {
+ double seconds =
+ elapsedTime((i == 0 ? 1 : threads),
+ intA, intAA,
+ longA, longAA,
+ floatA, floatAA,
+ doubleA, doubleAA);
+ elapsed[i] = seconds;
+
+ print("Checking accuracy:");
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++) {
+ if (intAA.value[line][column] != longAA.value[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Integer and Long results differ at:");
+ complain(" line=" + line + ", column=" + column);
+ complain(" intAA.value[line][column]=" + intAA.value[line][column]);
+ complain("longAA.value[line][column]=" + longAA.value[line][column]);
+ return 2; // FAILED
+ }
+ if (intAA.value[line][column] != floatAA.value[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Integer and Float results differ at:");
+ complain(" line=" + line + ", column=" + column);
+ complain(" intAA.value[line][column]=" + intAA.value[line][column]);
+ complain("floatAA.value[line][column]=" + floatAA.value[line][column]);
+ return 2; // FAILED
+ }
+ if (intAA.value[line][column] != doubleAA.value[line][column]) {
+ println("");
+ complain("Test failed:");
+ complain("Integer and Double results differ at:");
+ complain(" line=" + line + ", column=" + column);
+ complain(" intAA.value[line][column]=" + intAA.value[line][column]);
+ complain("doubleAA.value[line][column]=" + doubleAA.value[line][column]);
+ return 2; // FAILED
+ }
+ }
+ println(" done.");
+ }
+
+ double overallTime = elapsed[0] + elapsed[1];
+ double averageTime = overallTime / 2; // 2 excutions
+ double averagePerformance = 4 * size * size * (size + size) / averageTime / 1e6;
+ println("");
+ println("Overall elapsed time: " + overallTime + " seconds.");
+ println("Average elapsed time: " + averageTime + " seconds.");
+ println("Average performance: " + averagePerformance + " MOPS");
+
+ if (testPerformance) {
+ println("");
+ print("Checking performance: ");
+ double elapsed1 = elapsed[0];
+ double elapsedM = elapsed[1] * numberOfCPU;
+ if (elapsed1 > elapsedM * (1 + tolerance / 100)) {
+ println("");
+ complain("Test failed:");
+ complain("Single-thread calculation is essentially slower:");
+ complain("Calculation time elapsed (seconds):");
+ complain(" single thread: " + elapsed[0]);
+ complain(" multi-threads: " + elapsed[1]);
+ complain(" number of CPU: " + numberOfCPU);
+ complain(" tolerance: " + tolerance + "%");
+ return 2; // FAILED
+ }
+ println("done.");
+ }
+
+ println("Test passed.");
+ return 0; // PASSED
+ }
+
+ /**
+ * Return time (in seconds) elapsed for calculation of matrix
+ * product A*A with int, long,
+ * float, and double representations.
+ */
+ private static double elapsedTime(int threads,
+ IntegerMatrix intA, IntegerMatrix intAA,
+ LongMatrix longA, LongMatrix longAA,
+ FloatMatrix floatA, FloatMatrix floatAA,
+ DoubleMatrix doubleA, DoubleMatrix doubleAA) {
+
+ println("");
+ print("Computing A*A with " + threads + " thread(s):");
+ long mark1 = System.currentTimeMillis();
+ intAA.setSquareOf(intA, threads);
+ longAA.setSquareOf(longA, threads);
+ floatAA.setSquareOf(floatA, threads);
+ doubleAA.setSquareOf(doubleA, threads);
+ long mark2 = System.currentTimeMillis();
+ println(" done.");
+
+ int size = intA.size();
+ double sec = (mark2 - mark1) / 1000.0;
+ double perf = 4 * size * size * (size + size) / sec;
+ println("Elapsed time: " + sec + " seconds");
+ println("Performance: " + perf / 1e6 + " MOPS");
+
+ return sec;
+ }
+
+ /**
+ * Compute A*A for int matrix A.
+ */
+ private static class IntegerMatrix {
+ volatile int value[][];
+
+ /**
+ * Number of lines and columns in this square matrix.
+ */
+ public int size() {
+ return value.length;
+ }
+
+ /**
+ * New square matrix with random elements.
+ */
+ public IntegerMatrix(int size) {
+ value = new int[size][size];
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ value[line][column] =
+ Math.round((float) ((1 - 2 * Math.random()) * size));
+ }
+
+ /**
+ * Assign this matrix with A*A.
+ *
+ * @param threads Split computation into the given number of threads.
+ */
+ public void setSquareOf(IntegerMatrix A, int threads) {
+ if (this.size() != A.size())
+ throw new IllegalArgumentException(
+ "this.size() != A.size()");
+
+ if ((size() % threads) != 0)
+ throw new IllegalArgumentException("size()%threads != 0");
+ int bunch = size() / threads;
+
+ Thread task[] = new Thread[threads];
+ for (int t = 0; t < threads; t++) {
+ int line0 = bunch * t;
+ MatrixComputer computer =
+ new MatrixComputer(value, A.value, line0, bunch);
+ task[t] = new Thread(computer);
+ }
+
+ for (int t = 0; t < threads; t++)
+ task[t].start();
+
+ for (int t = 0; t < threads; t++)
+ if (task[t].isAlive())
+ try {
+ task[t].join();
+ } catch (InterruptedException exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ }
+
+ /**
+ * Thread to compute a bunch of lines of matrix square.
+ */
+ private static class MatrixComputer implements Runnable {
+ private int result[][];
+ private int source[][];
+ private int line0;
+ private int bunch;
+
+ /**
+ * Register a task for matrix multiplication.
+ */
+ public MatrixComputer(
+ int result[][], int source[][], int line0, int bunch) {
+
+ this.result = result; // reference to resulting matrix value
+ this.source = source; // reference to matrix to be squared
+ this.line0 = line0; // compute lines from line0 to ...
+ this.bunch = bunch; // number of resulting lines to compute
+ }
+
+ /**
+ * Do execute the task just registered for this thread.
+ */
+ public void run() {
+ int line1 = line0 + bunch;
+ int size = result.length;
+ for (int line = line0; line < line1; line++)
+ for (int column = 0; column < size; column++) {
+ int sum = 0;
+ for (int i = 0; i < size; i++)
+ sum += source[line][i] * source[i][column];
+ result[line][column] = sum;
+ }
+ }
+
+ }
+
+ }
+
+ /**
+ * Compute A*A for long matrix A.
+ */
+ private static class LongMatrix {
+ volatile long value[][];
+
+ /**
+ * Number of lines and columns in this square matrix.
+ */
+ public int size() {
+ return value.length;
+ }
+
+
+ /**
+ * New square matrix with the given integer elements.
+ */
+ public LongMatrix(IntegerMatrix A) {
+ int size = A.size();
+ value = new long[size][size];
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ value[line][column] = A.value[line][column];
+ }
+
+ /**
+ * Assign this matrix with A*A.
+ *
+ * @param threads Split computation into the given number of threads.
+ */
+ public void setSquareOf(LongMatrix A, int threads) {
+ if (this.size() != A.size())
+ throw new IllegalArgumentException(
+ "this.size() != A.size()");
+
+ if ((size() % threads) != 0)
+ throw new IllegalArgumentException("size()%threads != 0");
+ int bunch = size() / threads;
+
+ Thread task[] = new Thread[threads];
+ for (int t = 0; t < threads; t++) {
+ int line0 = bunch * t;
+ MatrixComputer computer =
+ new MatrixComputer(value, A.value, line0, bunch);
+ task[t] = new Thread(computer);
+ }
+
+ for (int t = 0; t < threads; t++)
+ task[t].start();
+
+ for (int t = 0; t < threads; t++)
+ if (task[t].isAlive())
+ try {
+ task[t].join();
+ } catch (InterruptedException exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ }
+
+ /**
+ * Thread to compute a bunch of lines of matrix square.
+ */
+ private static class MatrixComputer implements Runnable {
+ private long result[][];
+ private long source[][];
+ private int line0;
+ private int bunch;
+
+ /**
+ * Register a task for matrix multiplication.
+ */
+ public MatrixComputer(
+ long result[][], long source[][], int line0, int bunch) {
+
+ this.result = result; // reference to resulting matrix value
+ this.source = source; // reference to matrix to be squared
+ this.line0 = line0; // compute lines from line0 to ...
+ this.bunch = bunch; // number of resulting lines to compute
+ }
+
+ /**
+ * Do execute the task just registered for this thread.
+ */
+ public void run() {
+ int line1 = line0 + bunch;
+ int size = result.length;
+ for (int line = line0; line < line1; line++)
+ for (int column = 0; column < size; column++) {
+ long sum = 0;
+ for (int i = 0; i < size; i++)
+ sum += source[line][i] * source[i][column];
+ result[line][column] = sum;
+ }
+ }
+
+ }
+
+ }
+
+ /**
+ * Compute A*A for float matrix A.
+ */
+ private static class FloatMatrix {
+ volatile float value[][];
+
+ /**
+ * Number of lines and columns in this square matrix.
+ */
+ public int size() {
+ return value.length;
+ }
+
+
+ /**
+ * New square matrix with the given integer elements.
+ */
+ public FloatMatrix(IntegerMatrix A) {
+ int size = A.size();
+ value = new float[size][size];
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ value[line][column] = A.value[line][column];
+ }
+
+ /**
+ * Assign this matrix with A*A.
+ *
+ * @param threads Split computation into the given number of threads.
+ */
+ public void setSquareOf(FloatMatrix A, int threads) {
+ if (this.size() != A.size())
+ throw new IllegalArgumentException(
+ "this.size() != A.size()");
+
+ if ((size() % threads) != 0)
+ throw new IllegalArgumentException("size()%threads != 0");
+ int bunch = size() / threads;
+
+ Thread task[] = new Thread[threads];
+ for (int t = 0; t < threads; t++) {
+ int line0 = bunch * t;
+ MatrixComputer computer =
+ new MatrixComputer(value, A.value, line0, bunch);
+ task[t] = new Thread(computer);
+ }
+
+ for (int t = 0; t < threads; t++)
+ task[t].start();
+
+ for (int t = 0; t < threads; t++)
+ if (task[t].isAlive())
+ try {
+ task[t].join();
+ } catch (InterruptedException exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ }
+
+ /**
+ * Thread to compute a bunch of lines of matrix square.
+ */
+ private static class MatrixComputer implements Runnable {
+ private float result[][];
+ private float source[][];
+ private int line0;
+ private int bunch;
+
+ /**
+ * Register a task for matrix multiplication.
+ */
+ public MatrixComputer(
+ float result[][], float source[][], int line0, int bunch) {
+
+ this.result = result; // reference to resulting matrix value
+ this.source = source; // reference to matrix to be squared
+ this.line0 = line0; // compute lines from line0 to ...
+ this.bunch = bunch; // number of resulting lines to compute
+ }
+
+ /**
+ * Do execute the task just registered for this thread.
+ */
+ public void run() {
+ int line1 = line0 + bunch;
+ int size = result.length;
+ for (int line = line0; line < line1; line++)
+ for (int column = 0; column < size; column++) {
+ float sum = 0;
+ for (int i = 0; i < size; i++)
+ sum += source[line][i] * source[i][column];
+ result[line][column] = sum;
+ }
+ }
+
+ }
+
+ }
+
+ /**
+ * Compute A*A for float matrix A.
+ */
+ private static class DoubleMatrix {
+ volatile double value[][];
+
+ /**
+ * Number of lines and columns in this square matrix.
+ */
+ public int size() {
+ return value.length;
+ }
+
+
+ /**
+ * New square matrix with the given integer elements.
+ */
+ public DoubleMatrix(IntegerMatrix A) {
+ int size = A.size();
+ value = new double[size][size];
+ for (int line = 0; line < size; line++)
+ for (int column = 0; column < size; column++)
+ value[line][column] = A.value[line][column];
+ }
+
+ /**
+ * Assign this matrix with A*A.
+ *
+ * @param threads Split computation into the given number of threads.
+ */
+ public void setSquareOf(DoubleMatrix A, int threads) {
+ if (this.size() != A.size())
+ throw new IllegalArgumentException(
+ "this.size() != A.size()");
+
+ if ((size() % threads) != 0)
+ throw new IllegalArgumentException("size()%threads != 0");
+ int bunch = size() / threads;
+
+ Thread task[] = new Thread[threads];
+ for (int t = 0; t < threads; t++) {
+ int line0 = bunch * t;
+ MatrixComputer computer =
+ new MatrixComputer(value, A.value, line0, bunch);
+ task[t] = new Thread(computer);
+ }
+
+ for (int t = 0; t < threads; t++)
+ task[t].start();
+
+ for (int t = 0; t < threads; t++)
+ if (task[t].isAlive())
+ try {
+ task[t].join();
+ } catch (InterruptedException exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ }
+
+ /**
+ * Thread to compute a bunch of lines of matrix square.
+ */
+ private static class MatrixComputer implements Runnable {
+ private double result[][];
+ private double source[][];
+ private int line0;
+ private int bunch;
+
+ /**
+ * Register a task for matrix multiplication.
+ */
+ public MatrixComputer(
+ double result[][], double source[][], int line0, int bunch) {
+
+ this.result = result; // reference to resulting matrix value
+ this.source = source; // reference to matrix to be squared
+ this.line0 = line0; // compute lines from line0 to ...
+ this.bunch = bunch; // number of resulting lines to compute
+ }
+
+ /**
+ * Do execute the task just registered for this thread.
+ */
+ public void run() {
+ int line1 = line0 + bunch;
+ int size = result.length;
+ for (int line = line0; line < line1; line++)
+ for (int column = 0; column < size; column++) {
+ double sum = 0;
+ for (int i = 0; i < size; i++)
+ sum += source[line][i] * source[i][column];
+ result[line][column] = sum;
+ }
+ }
+
+ }
+
+ }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/TEST.properties
new file mode 100644
index 00000000000..8b51b2a9115
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/TEST.properties
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack001.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack001.java
new file mode 100644
index 00000000000..9922f82515f
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack001.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack001.
+ * VM testbase keywords: [stress, quick, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * Provoke StackOverflowError by infinite recursion in Java method,
+ * intercept the exception try to make one more invocation.
+ * COMMENTS
+ * Kestrel for Solaris_JDK_1.3-b10 crashes while trying to execute
+ * this test with Client HS VM.
+ * See lots of bugs concerning similar failuires:
+ * Evaluated:
+ * 4217960 [native stack overflow bug] reflection test causes crash
+ * Accepted:
+ * 4285716 native stack overflow causes crash on Solaris
+ * 4281578 Second stack overflow crashes HotSpot VM
+ * Closed (duplicate):
+ * 4027933 Native stack overflows not detected or handled correctly
+ * 4134353 (hpi) sysThreadCheckStack is a no-op on win32
+ * 4185411 Various crashes when using recursive reflection.
+ * 4167055 infinite recursion in FindClass
+ * 4222359 Infinite recursion crashes jvm
+ * Closed (will not fix):
+ * 4231968 StackOverflowError in a native method causes Segmentation Fault
+ * 4254634 println() while catching StackOverflowError causes hotspot VM crash
+ * 4302288 the second stack overflow causes Classic VM to exit on win32
+ *
+ * @run main/othervm nsk.stress.stack.stack001
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack001 {
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ stack001 test = new stack001();
+ test.recurse(0);
+ out.println("Maximal depth: " + test.maxdepth);
+ return 0;
+ }
+
+ private int maxdepth;
+
+ private void recurse(int depth) {
+ maxdepth = depth;
+ try {
+ recurse(depth + 1);
+ } catch (Error error) {
+ if (!(error instanceof StackOverflowError) &&
+ !(error instanceof OutOfMemoryError))
+ throw error;
+
+ if (maxdepth == depth)
+ recurse(depth + 1);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack002.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack002.java
new file mode 100644
index 00000000000..66f9924d1a8
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack002.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack002.
+ * VM testbase keywords: [stress, quick, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * Provoke StackOverflowError by infinite recursion in Java method,
+ * intercept the exception and continue to invoke that method until
+ * the test exceeds timeout, or until Java VM crashes.
+ * COMMENTS
+ * I believe that the test causes HS crashes due to the following bug:
+ * 4330318 (P2/S2) NSK test fails as An irrecoverable stack overflow
+ * See also bugs (lots of bugs!):
+ * Evaluated:
+ * 4217960 [native stack overflow bug] reflection test causes crash
+ * Accepted:
+ * 4285716 native stack overflow causes crash on Solaris
+ * 4281578 Second stack overflow crashes HotSpot VM
+ * Closed (duplicate):
+ * 4027933 Native stack overflows not detected or handled correctly
+ * 4134353 (hpi) sysThreadCheckStack is a no-op on win32
+ * 4185411 Various crashes when using recursive reflection.
+ * 4167055 infinite recursion in FindClass
+ * 4222359 Infinite recursion crashes jvm
+ * Closed (will not fix):
+ * 4231968 StackOverflowError in a native method causes Segmentation Fault
+ * 4254634 println() while catching StackOverflowError causes hotspot VM crash
+ * 4302288 the second stack overflow causes Classic VM to exit on win32
+ *
+ * @run main/othervm nsk.stress.stack.stack002
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack002 {
+ static final long timeout = 10000; // 10 seconds
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ Tester tester = new Tester(out);
+ Timer timer = new Timer(tester);
+ timer.start();
+ tester.start();
+ while (timer.isAlive())
+ try {
+ timer.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace(out);
+ return 2;
+ }
+ // if (tester.isAlive())
+// return 2;
+ out.println("Maximal depth: " + tester.maxdepth);
+ return 0;
+ }
+
+ private static class Tester extends Thread {
+ int maxdepth;
+ PrintStream out;
+
+ public Tester(PrintStream out) {
+ this.out = out;
+ maxdepth = 0;
+ }
+
+ public void run() {
+ recurse(0);
+ }
+
+ void recurse(int depth) {
+ maxdepth = depth;
+ try {
+ recurse(depth + 1);
+// } catch (StackOverflowError e) {
+//
+// OutOfMemoryError is also eligible to indicate stack overflow:
+//
+ } catch (Error error) {
+ if (!(error instanceof StackOverflowError) &&
+ !(error instanceof OutOfMemoryError))
+ throw error;
+
+/***
+ *** Originally, I supposed that VM crashes because of unexpected
+ *** native stack overflow (println() invokes native method).
+ *** However, I found that HS 1.3 and HS 2.0 crash even on
+ *** invocation of Java (not native) method.
+ ***
+ out.println("StackOverflowError, depth=" + depth);
+ ***/
+ recurse(depth + 1);
+ }
+ }
+ }
+
+ private static class Timer extends Thread {
+ private Tester tester;
+
+ public Timer(Tester tester) {
+ this.tester = tester;
+ }
+
+ public void run() {
+ long started;
+ started = System.currentTimeMillis();
+ while (System.currentTimeMillis() - started < timeout)
+ ; /***
+ *** The test hangs on JDK 1.2.2 Classic VM if sleep() is invoked.
+ ***
+ try {
+ this.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace(tester.out);
+ return;
+ };
+ ***/
+ tester.stop();
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack003.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack003.java
new file mode 100644
index 00000000000..8463467ce94
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack003.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack003.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the same thread
+ * by invoking static recursive method for the given fixed depth
+ * of recursion (though, for a large depth).
+ * This test makes measures a number of recursive invocations
+ * before 1st StackOverflowError, and then tries to reproduce
+ * such StackOverflowError 100 times -- each time by trying to
+ * invoke the same recursive method for the given fixed depth
+ * of invocations (which is twice that depth just measured).
+ * The test is deemed passed, if VM have not crashed.
+ * COMMENTS
+ * This test crashes all HS versions (2.0, 1.3, 1.4) on all
+ * platforms (Win32, Solaris, Linux) in all execution modes
+ * (-Xint, -Xmixed, -Xcomp) in 100% of executions in which
+ * I had tryied it.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack003
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack003 {
+ final static int ITERATIONS = 100;
+ final static int INCREMENT = 100;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ int depth;
+ for (depth = 1; ; depth += INCREMENT)
+ try {
+ recurse(depth);
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + depth);
+ for (int i = 0; i < ITERATIONS; i++)
+ try {
+ recurse(2 * depth);
+ out.println("?");
+ } catch (StackOverflowError soe) {
+ // OK.
+ } catch (OutOfMemoryError oome) {
+ // Also OK.
+ }
+ return 0;
+ }
+
+ static void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack004.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack004.java
new file mode 100644
index 00000000000..6aded614756
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack004.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack004.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the same thread
+ * by invoking final static recursive method for the given fixed
+ * depth of recursion (though, for a large depth).
+ * This test makes measures a number of recursive invocations
+ * before 1st StackOverflowError, and then tries to reproduce
+ * such StackOverflowError 100 times -- each time by trying to
+ * invoke the same recursive method for the given fixed depth
+ * of invocations (which is twice that depth just measured).
+ * The test is deemed passed, if VM have not crashed.
+ * COMMENTS
+ * This test crashes all HS versions (2.0, 1.3, 1.4) on all
+ * platforms (Win32, Solaris, Linux) in all execution modes
+ * (-Xint, -Xmixed, -Xcomp) in 100% of executions in which
+ * I had tryied it.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack004
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack004 {
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ stack004 test = new stack004();
+ int exitCode = test.doRun(args, out);
+ return exitCode;
+ }
+
+ public int doRun(String args[], PrintStream out) {
+ int depth;
+ for (depth = 100; ; depth += 100)
+ try {
+ recurse(depth);
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + depth);
+ for (int i = 0; i < 100; i++)
+ try {
+ recurse(2 * depth);
+ out.println("?");
+ } catch (StackOverflowError soe) {
+ // OK.
+ } catch (OutOfMemoryError oome) {
+ // Also OK.
+ }
+ return 0;
+ }
+
+ final static void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack005.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack005.java
new file mode 100644
index 00000000000..0a19cf271af
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack005.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack005.
+ * VM testbase keywords: [stress, quick, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the same thread
+ * by invoking final recursive method for the given fixed depth of
+ * recursion (though, for a large depth).
+ * This test makes measures a number of recursive invocations
+ * before 1st StackOverflowError, and then tries to reproduce
+ * such StackOverflowError 100 times -- each time by trying to
+ * invoke the same recursive method for the given fixed depth
+ * of invocations (which is twice that depth just measured).
+ * The test is deemed passed, if VM have not crashed.
+ * COMMENTS
+ * This test crashes all HS versions (2.0, 1.3, 1.4) on all
+ * platforms (Win32, Solaris, Linux) in all execution modes
+ * (-Xint, -Xmixed, -Xcomp) in 100% of executions in which
+ * I had tryied it.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack005
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack005 {
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ stack005 test = new stack005();
+ int depth;
+ for (depth = 100; ; depth += 100)
+ try {
+ test.recurse(depth);
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + depth);
+ for (int i = 0; i < 100; i++)
+ try {
+ test.recurse(2 * depth);
+ out.println("?");
+ } catch (StackOverflowError soe) {
+ // OK.
+ } catch (OutOfMemoryError oome) {
+ // Also OK.
+ }
+ return 0;
+ }
+
+ final void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack006.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack006.java
new file mode 100644
index 00000000000..aac7f9d2b72
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack006.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack006.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the same thread
+ * by invoking virtual recursive method for the given fixed depth
+ * of recursion (though, for a large depth).
+ * This test makes measures a number of recursive invocations
+ * before 1st StackOverflowError, and then tries to reproduce
+ * such StackOverflowError 100 times -- each time by trying to
+ * invoke the same recursive method for the given fixed depth
+ * of invocations (which is twice that depth just measured).
+ * The test is deemed passed, if VM have not crashed.
+ * COMMENTS
+ * This test crashes all HS versions (2.0, 1.3, 1.4) on all
+ * platforms (Win32, Solaris, Linux) in all execution modes
+ * (-Xint, -Xmixed, -Xcomp) in 100% of executions in which
+ * I had tryied it.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack006
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack006 implements stack006i {
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ stack006i test = new stack006();
+ int depth;
+ for (depth = 100; ; depth += 100)
+ try {
+ test.recurse(depth);
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + depth);
+ for (int i = 0; i < 100; i++)
+ try {
+ test.recurse(2 * depth);
+ out.println("?");
+ } catch (StackOverflowError soe) {
+ // OK.
+ } catch (OutOfMemoryError oome) {
+ // Also OK.
+ }
+ return 0;
+ }
+
+ public void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
+
+interface stack006i {
+ void recurse(int depth);
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack007.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack007.java
new file mode 100644
index 00000000000..6c06aade86c
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack007.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack007.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the same thread
+ * by invoking synchronized virtual recursive method for the given
+ * fixed depth of recursion (though, for a large depth).
+ * This test makes measures a number of recursive invocations
+ * before 1st StackOverflowError, and then tries to reproduce
+ * such StackOverflowError 10000 times -- each time by trying to
+ * invoke the same recursive method for the given fixed depth
+ * of invocations (which is 10 times that depth just measured).
+ * The test is deemed passed, if VM have not crashed.
+ * COMMENTS
+ * This test crashes HS versions 1.3 and 1.4 on Win32, Solaris,
+ * and Linux platforms in all execution modes. However, it passes
+ * against HS 2.0 on Win32 platform.
+ * See also the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack007
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack007 implements stack007i {
+ final static int ITERATIONS = 1000;
+ final static int INCREMENT = 100;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ stack007i test = new stack007();
+ int depth;
+ for (depth = 100; ; depth += INCREMENT)
+ try {
+ test.recurse(depth);
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + depth);
+ for (int i = 0; i < ITERATIONS; i++)
+ try {
+ test.recurse(10 * depth);
+ out.println("?");
+ } catch (StackOverflowError soe) {
+ // OK.
+ } catch (OutOfMemoryError oome) {
+ // Also OK.
+ }
+ return 0;
+ }
+
+ public synchronized void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
+
+interface stack007i {
+ void recurse(int depth);
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack008.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack008.java
new file mode 100644
index 00000000000..5c6a1b09623
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack008.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack008.
+ * VM testbase keywords: [stress, stack, nonconcurrent, exclude]
+ * VM testbase comments: 8139875
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the same thread
+ * by invocations via reflection. Recursive method is invoked for
+ * the given fixed depth of recursion (though, for a large depth).
+ * This test makes measures a number of recursive invocations
+ * before 1st StackOverflowError, and then tries to reproduce
+ * such StackOverflowError 100 times -- each time by trying to
+ * invoke the same recursive method for the given fixed depth
+ * of invocations (which is twice that depth just measured).
+ * The test is deemed passed, if VM have not crashed.
+ * COMMENTS
+ * This test crashes all HS versions (2.0, 1.3, 1.4) on Solaris,
+ * and crashes HS 2.0 on win32. However, it passes against HS 1.3
+ * and 1.4 on Win32.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @ignore 8139875
+ * @run main/othervm nsk.stress.stack.stack008
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class stack008 {
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ int depth;
+ //
+ // Measure maximal recursion depth until stack overflow:
+ //
+ for (depth = 100; ; depth += 100)
+ try {
+ invokeRecurse(depth);
+ } catch (Throwable exception) {
+ Throwable target = getTargetException(exception);
+ if ((target instanceof StackOverflowError) ||
+ (target instanceof OutOfMemoryError))
+ break; // OK.
+ target.printStackTrace(out);
+ if (target instanceof ThreadDeath)
+ throw (ThreadDeath) target;
+ return 2;
+ }
+ out.println("Max. depth: " + depth);
+ //
+ // Provoke stack overflow multiple times:
+ //
+ for (int i = 0; i < 100; i++)
+ try {
+ invokeRecurse(2 * depth);
+// out.println("?");
+ } catch (Throwable exception) {
+ Throwable target = getTargetException(exception);
+ if ((target instanceof StackOverflowError) ||
+ (target instanceof OutOfMemoryError))
+ continue; // OK.
+ target.printStackTrace(out);
+ if (target instanceof ThreadDeath)
+ throw (ThreadDeath) target;
+ return 2;
+ }
+ return 0;
+ }
+
+ private static Throwable getTargetException(Throwable exception) {
+ Throwable target;
+ //
+ // Unwrap deep chain of exceptions:
+ //
+ for (
+ target = exception;
+ target instanceof InvocationTargetException;
+ target = ((InvocationTargetException) target).getTargetException()
+ )
+ ;
+ return target;
+ }
+
+ static Method method = null;
+ static stack008 instance = null;
+ static Object params[] = null;
+
+ private static void invokeRecurse(int depth) throws Exception {
+ if (method == null) {
+ //
+ // Optimization trick: allocate once, use everywhere.
+ //
+ instance = new stack008();
+ method = stack008.class.getMethod("recurse");
+ params = new Object[]{};
+ }
+ //
+ // Note, that the same instance.depth is used in all invocations:
+ //
+ instance.depth = depth;
+ method.invoke(instance, params);
+ }
+
+ int depth = 0;
+
+ public void recurse() throws Exception {
+ if (depth > 0)
+ //
+ // Self-invoke via reflection:
+ //
+ invokeRecurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack009.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack009.java
new file mode 100644
index 00000000000..2739daf126d
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack009.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack009.
+ * VM testbase keywords: [stress, quick, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * The test provokes second stack overflow from within the
+ * stack overflow handler.
+ * This test measures a number of recursive invocations until
+ * StackOverflowError, and then tries to make an invocation
+ * for the fixed invocations depth from within the "catch"
+ * block just caught the 1st stack overflow. The depth of new
+ * invocations is 10 times that depth seen at the 1st stack
+ * overflow; so that another stack overflow occurs.
+ * The test is deemed passed, if VM have not crashed, and
+ * if there is no exception thrown other than due to stack
+ * overflow.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, and 1.4 on Win32
+ * and Solaris platforms.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack009
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack009 {
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ for (int depth = 100; ; depth += 100)
+ try {
+ recurse(depth);
+ } catch (Error error1) {
+ if (!(error1 instanceof StackOverflowError) &&
+ !(error1 instanceof OutOfMemoryError))
+ throw error1;
+
+ out.println("Max. depth: " + depth);
+
+ try {
+ recurse(10 * depth);
+ out.println("?");
+ } catch (Error error2) {
+ if (!(error2 instanceof StackOverflowError) &&
+ !(error2 instanceof OutOfMemoryError))
+ throw error2;
+
+ // Stack overflow is OK here.
+ }
+
+ break;
+ }
+ return 0;
+ }
+
+ static void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack010.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack010.java
new file mode 100644
index 00000000000..6fcdcc81b9c
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack010.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack010.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the multiple
+ * threads -- by invoking static recursive method for the given
+ * fixed depth of recursion (though, for a large depth).
+ * This test measures a number of recursive invocations until
+ * stack overflow, and then tries to provoke similar stack overflows
+ * 10 times in each of 10 threads. Each provocation consists of
+ * invoking that recursive method for the given fixed depth
+ * of invocations which is 10 times that depth measured before.
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, 1.4 on Win32 and Solaris
+ * platforms.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack010
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack010 extends Thread {
+ final static int THREADS = 10;
+ final static int CYCLES = 10;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ //
+ // Measure maximal recursion depth until stack overflow:
+ //
+ int maxDepth = 0;
+ for (int depth = 10; ; depth += 10)
+ try {
+ recurse(depth);
+ maxDepth = depth;
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + maxDepth);
+
+ //
+ // Execute multiple threads repeatedly provoking stack overflows:
+ //
+ stack010 threads[] = new stack010[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack010();
+ threads[i].depthToTry = 10 * maxDepth;
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were not thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ threads[i].thrown.printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ int depthToTry = 0;
+ Throwable thrown = null;
+
+ public void run() {
+ for (int i = 0; i < CYCLES; i++)
+ try {
+ recurse(depthToTry);
+ throw new Exception(
+ "TEST_RFE: no stack overflow thrown" +
+ ", need to try deeper recursion?");
+
+ } catch (StackOverflowError soe) {
+ // It's OK: stack overflow was expected.
+ } catch (OutOfMemoryError oome) {
+ // Also OK: out of memory may indacate stack overflow.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ // It isn't OK!
+ thrown = throwable;
+ break;
+ }
+ }
+
+ static void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack011.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack011.java
new file mode 100644
index 00000000000..14c928fd13f
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack011.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack011.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the multiple
+ * threads -- by invoking final static recursive method for the
+ * given fixed depth of recursion (though, for a large depth).
+ * This test measures a number of recursive invocations until
+ * stack overflow, and then tries to provoke similar stack overflows
+ * 10 times in each of 10 threads. Each provocation consists of
+ * invoking that recursive method for the given fixed depth
+ * of invocations which is 10 times that depth measured before.
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, 1.4 on Win32 and Solaris
+ * platforms.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack011
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack011 extends Thread {
+ final static int THREADS = 10;
+ final static int CYCLES = 10;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ //
+ // Measure maximal recursion depth until stack overflow:
+ //
+ int maxDepth = 0;
+ for (int depth = 10; ; depth += 10)
+ try {
+ recurse(depth);
+ maxDepth = depth;
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + maxDepth);
+
+ //
+ // Execute multiple threads repeatedly provoking stack overflows:
+ //
+ stack011 threads[] = new stack011[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack011();
+ threads[i].depthToTry = 10 * maxDepth;
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were not thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ threads[i].thrown.printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ int depthToTry = 0;
+ Throwable thrown = null;
+
+ public void run() {
+ for (int i = 0; i < CYCLES; i++)
+ try {
+ recurse(depthToTry);
+ throw new Exception(
+ "TEST_RFE: no stack overflow thrown" +
+ ", need to try deeper recursion?");
+
+ } catch (StackOverflowError error) {
+ // It's OK: stack overflow was expected.
+ } catch (OutOfMemoryError oome) {
+ // Also OK: recursion may result in memory lack.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ // It isn't OK!
+ thrown = throwable;
+ break;
+ }
+ }
+
+ final static void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack012.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack012.java
new file mode 100644
index 00000000000..18a391d04c7
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack012.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack012.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the multiple
+ * threads -- by invoking final recursive method for the given
+ * fixed depth of recursion (though, for a large depth).
+ * This test measures a number of recursive invocations until
+ * stack overflow, and then tries to provoke similar stack overflows
+ * 10 times in each of 10 threads. Each provocation consists of
+ * invoking that recursive method for the given fixed depth
+ * of invocations which is 10 times that depth measured before.
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 1.3, 1.4 on Win32, and HS versions
+ * 2.0, 1.3, and 1.4 on Solaris. However, it passes against HS 2.0
+ * on Win32.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack012
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack012 extends Thread {
+ final static int THREADS = 10;
+ final static int CYCLES = 10;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ stack012 test = new stack012();
+ //
+ // Measure maximal recursion depth until stack overflow:
+ //
+ int maxDepth = 0;
+ for (int depth = 10; ; depth += 10)
+ try {
+ test.recurse(depth);
+ maxDepth = depth;
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + maxDepth);
+
+ //
+ // Execute multiple threads repeatedly provoking stack overflows:
+ //
+ stack012 threads[] = new stack012[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack012();
+ threads[i].depthToTry = 10 * maxDepth;
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were not thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ threads[i].thrown.printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ int depthToTry = 0;
+ Throwable thrown = null;
+
+ public void run() {
+ for (int i = 0; i < CYCLES; i++)
+ try {
+ this.recurse(depthToTry);
+ throw new Exception(
+ "TEST_RFE: no stack overflow thrown" +
+ ", need to try deeper recursion?");
+
+ } catch (StackOverflowError error) {
+ // It's OK: stack overflow was expected.
+ } catch (OutOfMemoryError oome) {
+ // Also OK: invocation may result in out of memory.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ // It isn't OK!
+ thrown = throwable;
+ break;
+ }
+ }
+
+ final void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack013.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack013.java
new file mode 100644
index 00000000000..db66eb6df0c
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack013.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack013.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the multiple
+ * threads -- by invoking virtual recursive method for the given
+ * fixed depth of recursion (though, for a large depth).
+ * This test measures a number of recursive invocations until
+ * stack overflow, and then tries to provoke similar stack overflows
+ * 10 times in each of 10 threads. Each provocation consists of
+ * invoking that recursive method for the given fixed depth
+ * of invocations which is 10 times that depth measured before.
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, and 1.4 on both Win32
+ * and Solaris platforms.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack013
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack013 extends stack013i {
+ final static int THREADS = 10;
+ final static int CYCLES = 10;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ stack013i test = new stack013();
+ //
+ // Measure maximal recursion depth until stack overflow:
+ //
+ int maxDepth = 0;
+ for (int depth = 10; ; depth += 10)
+ try {
+ test.recurse(depth);
+ maxDepth = depth;
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + maxDepth);
+
+ //
+ // Execute multiple threads repeatedly provoking stack overflows:
+ //
+ stack013i threads[] = new stack013i[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack013();
+ threads[i].depthToTry = 10 * maxDepth;
+ threads[i].cycles = CYCLES;
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ threads[i].thrown.printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
+
+abstract class stack013i extends Thread {
+ //
+ // Pure virtual method:
+ //
+ abstract void recurse(int depth);
+
+ Throwable thrown = null;
+ int depthToTry;
+ int cycles;
+
+ public void run() {
+ //
+ // Provoke multiple stack overflows:
+ //
+ for (int i = 0; i < cycles; i++)
+ try {
+ recurse(depthToTry);
+ throw new Exception(
+ "TEST_RFE: no stack overflow thrown" +
+ ", need to try deeper recursion?");
+
+ } catch (StackOverflowError error) {
+ // It's OK: stack overflow was expected.
+ } catch (OutOfMemoryError oome) {
+ // Also OK: out of memory is eligible here.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ // It isn't OK!
+ thrown = throwable;
+ break;
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack014.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack014.java
new file mode 100644
index 00000000000..4b2da9ba9e5
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack014.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack014.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the multiple
+ * threads -- by invoking synchronized virtual recursive method
+ * for the given fixed depth of recursion (though, for a large
+ * depth). Note however, that different threads are not actual
+ * synchronized, because different instances having the recursive
+ * method are used.
+ * This test measures a number of recursive invocations until
+ * stack overflow, and then tries to provoke similar stack overflows
+ * 10 times in each of 10 threads. Each provocation consists of
+ * invoking that recursive method for the given fixed depth
+ * of invocations which is 10 times that depth measured before.
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, and 1.4 on Solaris.
+ * However, it passes against all these HS versions on Win32.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack014
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack014 extends stack014i {
+ final static int THREADS = 10;
+ final static int CYCLES = 10;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ stack014i test = new stack014();
+ //
+ // Measure maximal recursion depth until stack overflow:
+ //
+ int maxDepth = 0;
+ for (int depth = 10; ; depth += 10)
+ try {
+ test.recurse(depth);
+ maxDepth = depth;
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + maxDepth);
+
+ //
+ // Execute multiple threads repeatedly provoking stack overflows:
+ //
+ stack014i threads[] = new stack014i[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack014();
+ threads[i].depthToTry = 10 * maxDepth;
+ threads[i].cycles = CYCLES;
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ threads[i].thrown.printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ synchronized void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+}
+
+abstract class stack014i extends Thread {
+ //
+ // Pure virtual method:
+ //
+ abstract void recurse(int depth);
+
+ Throwable thrown = null;
+ int depthToTry;
+ int cycles;
+
+ public void run() {
+ //
+ // Provoke multiple stack overflows:
+ //
+ for (int i = 0; i < cycles; i++)
+ try {
+ recurse(depthToTry);
+ throw new Exception(
+ "TEST_RFE: no stack overflow thrown" +
+ ", need to try deeper recursion?");
+
+ } catch (StackOverflowError error) {
+ // It's OK: stack overflow was expected.
+ } catch (OutOfMemoryError oome) {
+ // Also OK: if there is no memory for stack expansion.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ // It isn't OK!
+ thrown = throwable;
+ break;
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack015.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack015.java
new file mode 100644
index 00000000000..0cb34acaf4e
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack015.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack015.
+ * VM testbase keywords: [stress, stack, nonconcurrent]
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows in the multiple
+ * threads -- by invoking synchronized virtual recursive method
+ * for the given fixed depth of recursion from within another
+ * recursive method already deeply invoked.
+ * This test measures a number of recursive invocations until
+ * stack overflow, and then tries to provoke similar stack overflows
+ * in 10 times in each of 10 threads. Each provocation consists of
+ * invoking that recursive method for the given fixed depth
+ * of invocations which is 10 times that depth measured before.
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, and 1.4 on Solaris.
+ * However, it passes against all these HS versions on Win32.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @run main/othervm nsk.stress.stack.stack015
+ */
+
+package nsk.stress.stack;
+
+
+import java.io.PrintStream;
+
+public class stack015 extends stack015i {
+ final static int THREADS = 10;
+ final static int CYCLES = 10;
+ final static int STEP = 10;
+ final static int RESERVE = 10;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ //
+ // The test will invoke the particular stack015.recurse()
+ // method via abstract test.recurse() invocations.
+ //
+ stack015i test = new stack015();
+ stack015i.test = test;
+
+ //
+ // Measure maximal recursion depth until stack overflow:
+ //
+ int maxDepth = 0;
+ for (int depth = 0; ; depth += STEP)
+ try {
+ test.recurse(depth);
+ maxDepth = depth;
+ } catch (StackOverflowError soe) {
+ break;
+ } catch (OutOfMemoryError oome) {
+ break;
+ }
+ out.println("Max. depth: " + maxDepth);
+
+ //
+ // Execute multiple threads repeatedly provoking stack overflows:
+ //
+ stack015i threads[] = new stack015i[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack015();
+ threads[i].depthToTry = RESERVE * maxDepth;
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ threads[i].thrown.printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ synchronized void syncRecurse(int depth) {
+ if (depth > 0)
+ syncRecurse(depth - 1);
+ }
+}
+
+abstract class stack015i extends Thread {
+ //
+ // Pure virtual method:
+ //
+ abstract void syncRecurse(int depth);
+
+ void recurse(int depth) {
+ //
+ // Stack overflow must occur here:
+ //
+ syncRecurse(stack015.STEP);
+ //
+ // If no stack overflow occured, try again with deeper stack:
+ //
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+
+ Throwable thrown = null;
+ int depthToTry;
+
+ static stack015i test;
+
+ public void run() {
+ //
+ // Provoke multiple stack overflows:
+ //
+ for (int i = 0; i < stack015.CYCLES; i++)
+ try {
+ //
+ // All threads invoke the same synchronized method:
+ //
+ test.recurse(depthToTry);
+
+ throw new Exception(
+ "TEST_RFE: no stack overflow thrown" +
+ ", need to try deeper recursion?");
+
+ } catch (StackOverflowError error) {
+ // It's OK: stack overflow was expected.
+ } catch (OutOfMemoryError oome) {
+ // Also OK: there may be no memory for stack expansion.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ // It isn't OK!
+ thrown = throwable;
+ break;
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack016.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack016.java
new file mode 100644
index 00000000000..507da331e92
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack016.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack016.
+ * VM testbase keywords: [stress, diehard, stack, nonconcurrent, exclude]
+ * VM testbase comments: 8139875
+ * VM testbase readme:
+ * DESCRIPTION
+ * The test provokes second stack overflow from within the
+ * stack overflow handler -- repeatedly multiple times, and
+ * in multiple threads.
+ * This test measures a number of recursive invocations until
+ * stack overflow, and then tries to provoke similar stack overflows
+ * in 10 times in each of 10 threads. Each provocation consists of
+ * invoking that recursive method for the given fixed depth
+ * of invocations which is 10 times that depth measured before,
+ * and then trying to invoke that recursive method once again
+ * from within the catch clause just caught StackOverflowError.
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, and 1.4 on both
+ * Solaris and Win32 platforms.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @ignore 8139875
+ * @run main/othervm nsk.stress.stack.stack016 -eager
+ */
+
+package nsk.stress.stack;
+
+
+import nsk.share.Harakiri;
+
+import java.io.PrintStream;
+
+public class stack016 extends Thread {
+ private final static int THREADS = 10;
+ private final static int CYCLES = 10;
+ private final static int STEP = 10;
+ private final static int RESERVE = 10;
+ private final static int PROBES = STEP * RESERVE;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ verbose = false;
+ boolean eager = false;
+ for (int i = 0; i < args.length; i++)
+ if (args[i].toLowerCase().equals("-verbose"))
+ verbose = true;
+ else if (args[i].toLowerCase().equals("-eager"))
+ eager = true;
+ if (!eager)
+ Harakiri.appoint(Harakiri.parseAppointment(args));
+ stack016.out = out;
+ stack016 test = new stack016();
+ return test.doRun();
+ }
+
+ private static boolean verbose;
+ private static PrintStream out;
+
+ private void display(Object message) {
+ if (!verbose)
+ return;
+ synchronized (out) {
+ out.println(message.toString());
+ }
+ }
+
+ private int doRun() {
+ //
+ // Measure recursive depth before stack overflow:
+ //
+ int maxDepth = 0;
+ for (depthToTry = 0; ; depthToTry += STEP)
+ try {
+ trickyRecurse(depthToTry);
+ maxDepth = depthToTry;
+ } catch (Error error) {
+ break;
+ }
+ out.println("Maximal recursion depth: " + maxDepth);
+
+ //
+ // Run the tested threads:
+ //
+ stack016 threads[] = new stack016[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack016();
+ threads[i].setName("Thread: " + (i + 1) + "/" + THREADS);
+ threads[i].depthToTry = RESERVE * maxDepth;
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ threads[i].thrown.printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ private int stackTop = 0;
+ private int depthToTry = 0;
+ private Throwable thrown = null;
+
+ private void trickyRecurse(int depth) {
+ stackTop = depthToTry - depth;
+ if (depth > 0)
+ try {
+ trickyRecurse(depth - 1);
+ } catch (Error error) {
+ if (!(error instanceof StackOverflowError) &&
+ !(error instanceof OutOfMemoryError))
+ throw error;
+
+ //
+ // Provoke more stack overflow,
+ // if current stack is deep enough:
+ //
+ if (depthToTry - depth < stackTop - PROBES)
+ throw error;
+ recurse(depthToTry);
+
+ throw new Error("TEST_RFE: try deeper recursion!");
+ }
+ }
+
+ private static void recurse(int depth) {
+ if (depth > 0)
+ recurse(depth - 1);
+ }
+
+ public void run() {
+ String threadName = Thread.currentThread().getName();
+ for (int i = 1; i <= CYCLES; i++)
+ try {
+ display(threadName + ", iteration: " + i + "/" + CYCLES);
+ trickyRecurse(depthToTry);
+ throw new Error(
+ "TEST_BUG: trickyRecursion() must throw an error anyway!");
+
+ } catch (StackOverflowError error) {
+ // It's OK: stack overflow was expected.
+ } catch (OutOfMemoryError oome) {
+ // Also OK, if there is no memory for stack expansion.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ thrown = throwable;
+ break;
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack017.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack017.java
new file mode 100644
index 00000000000..c1d5d85efe1
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack017.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack017.
+ * VM testbase keywords: [stress, diehard, stack, nonconcurrent, exclude]
+ * VM testbase comments: 8139875
+ * VM testbase readme:
+ * DESCRIPTION
+ * The test invokes infinitely recursive method from within stack
+ * overflow handler -- repeatedly multiple times, and in multiple
+ * threads.
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, and 1.4 on both
+ * Solaris and Win32 platforms.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @ignore 8139875
+ * @run main/othervm nsk.stress.stack.stack017 -eager
+ */
+
+package nsk.stress.stack;
+
+
+import nsk.share.Harakiri;
+
+import java.io.PrintStream;
+
+public class stack017 extends Thread {
+ private final static int THREADS = 10;
+ private final static int CYCLES = 10;
+ private final static int PROBES = 100;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ verbose = false;
+ boolean eager = false;
+ for (int i = 0; i < args.length; i++)
+ if (args[i].toLowerCase().equals("-verbose"))
+ verbose = true;
+ else if (args[i].toLowerCase().equals("-eager"))
+ eager = true;
+ if (!eager)
+ Harakiri.appoint(Harakiri.parseAppointment(args));
+ stack017.out = out;
+ stack017 test = new stack017();
+ return test.doRun();
+ }
+
+ private static boolean verbose;
+ private static PrintStream out;
+
+ private void display(Object message) {
+ if (!verbose)
+ return;
+ synchronized (out) {
+ out.println(message.toString());
+ }
+ }
+
+ private static int depthToTry;
+
+ private int doRun() {
+ //
+ // Measure recursive depth before stack overflow:
+ //
+ try {
+ recurse(0);
+ } catch (StackOverflowError soe) {
+ } catch (OutOfMemoryError oome) {
+ }
+ out.println("Maximal recursion depth: " + maxDepth);
+ depthToTry = maxDepth;
+
+ //
+ // Run the tested threads:
+ //
+ stack017 threads[] = new stack017[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack017();
+ threads[i].setName("Thread: " + (i + 1) + "/" + THREADS);
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ threads[i].thrown.printStackTrace(out);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ private int maxDepth = 0;
+
+ private void recurse(int depth) {
+ maxDepth = depth;
+ recurse(depth + 1);
+ }
+
+ private void trickyRecurse(int depth) {
+ try {
+ maxDepth = depth;
+ trickyRecurse(depth + 1);
+ } catch (Error error) {
+ if (!(error instanceof StackOverflowError) &&
+ !(error instanceof OutOfMemoryError))
+ throw error;
+
+ //
+ // Stack problem caugth: provoke it again,
+ // if current stack is enough deep:
+ //
+ if (depth < depthToTry - PROBES)
+ throw error;
+ recurse(depth + 1);
+ }
+ }
+
+ private Throwable thrown = null;
+
+ public void run() {
+ String threadName = Thread.currentThread().getName();
+ for (int i = 1; i <= CYCLES; i++)
+ try {
+ display(threadName + ", iteration: " + i + "/" + CYCLES);
+ trickyRecurse(0);
+ throw new Exception(
+ "TEST_BUG: stack overflow was expected!");
+
+ } catch (StackOverflowError oome) {
+ // It's OK: stack overflow was expected.
+ } catch (OutOfMemoryError oome) {
+ // Also OK, if there is no memory for stack expansion.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ // It isn't OK!
+ thrown = throwable;
+ break;
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack018.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack018.java
new file mode 100644
index 00000000000..5e7ee98dc1f
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack018.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack018.
+ * VM testbase keywords: [stress, diehard, stack, nonconcurrent, exclude]
+ * VM testbase comments: 8139875
+ * VM testbase readme:
+ * DESCRIPTION
+ * This test provokes multiple stack overflows by invocations via
+ * reflection -- repeatedly multiple times, and in multiple threads.
+ * Recursive method is invoked for the given fixed depth of recursion
+ * (though, for a large depth). The test measures a number of recursive
+ * invocations until stack overflow, and then tries to reproduce similar
+ * stack overflows 10 times in each of 10 threads -- each time by trying
+ * to invoke the same recursive method for the given fixed depth
+ * of invocations (which is 10 times that crucial depth just measured).
+ * The test is deemed passed, if VM have not crashed, and
+ * if exception other than due to stack overflow was not
+ * thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, and 1.4 on both
+ * Solaris and Win32 platforms.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @ignore 8139875
+ * @run main/othervm nsk.stress.stack.stack018 -eager
+ */
+
+package nsk.stress.stack;
+
+
+import nsk.share.Harakiri;
+
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class stack018 extends Thread {
+ private final static int THREADS = 10;
+ private final static int CYCLES = 10;
+ private final static int STEP = 100;
+ private final static int RESERVE = 100;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ verbose = false;
+ boolean eager = false;
+ for (int i = 0; i < args.length; i++)
+ if (args[i].toLowerCase().equals("-verbose"))
+ verbose = true;
+ else if (args[i].toLowerCase().equals("-eager"))
+ eager = true;
+ if (!eager)
+ Harakiri.appoint(Harakiri.parseAppointment(args));
+ stack018.out = out;
+ stack018 test = new stack018();
+ return test.doRun();
+ }
+
+ private static boolean verbose;
+ private static PrintStream out;
+
+ private void display(Object message) {
+ if (!verbose)
+ return;
+ synchronized (out) {
+ out.println(message.toString());
+ }
+ }
+
+ private int doRun() {
+ //
+ // Measure maximal recursion depth until stack overflow:
+ //
+ int maxDepth = 0;
+ for (depthToTry = 0; ; depthToTry += STEP)
+ try {
+ invokeRecurse(depthToTry);
+ maxDepth = depthToTry;
+ } catch (Throwable exception) {
+ Throwable target = getTargetException(exception);
+ if ((target instanceof StackOverflowError) ||
+ (target instanceof OutOfMemoryError))
+ break; // OK.
+ target.printStackTrace(out);
+ if (target instanceof ThreadDeath)
+ throw (ThreadDeath) target;
+ return 2;
+ }
+ out.println("Maximal recursion depth: " + maxDepth);
+
+ //
+ // Run the tested threads:
+ //
+ stack018 threads[] = new stack018[THREADS];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new stack018();
+ threads[i].setName("Thread: " + (i + 1) + "/" + THREADS);
+ threads[i].depthToTry = RESERVE * maxDepth;
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].isAlive())
+ try {
+ threads[i].join();
+ } catch (InterruptedException exception) {
+ exception.printStackTrace(out);
+ return 2;
+ }
+
+ //
+ // Check if unexpected exceptions were thrown:
+ //
+ int exitCode = 0;
+ for (int i = 0; i < threads.length; i++)
+ if (threads[i].thrown != null) {
+ out.println("# " + threads[i].getName()
+ + ": " + threads[i].thrown);
+ exitCode = 2;
+ }
+
+ if (exitCode != 0)
+ out.println("# TEST FAILED");
+ return exitCode;
+ }
+
+ private int depthToTry = 0;
+ private Throwable thrown = null;
+
+ public void run() {
+ String threadName = Thread.currentThread().getName();
+ for (int i = 1; i <= CYCLES; i++)
+ try {
+ display(threadName + ", iteration: " + i + "/" + CYCLES);
+ invokeRecurse(depthToTry);
+ throw new Error("TEST_RFE: try deeper invocations!");
+
+ } catch (Throwable exception) {
+ Throwable target = getTargetException(exception);
+ if ((target instanceof StackOverflowError) ||
+ (target instanceof OutOfMemoryError))
+ continue; // OK.
+ if (target instanceof ThreadDeath)
+ throw (ThreadDeath) target;
+ thrown = target;
+ break;
+ }
+ }
+
+ private static Throwable getTargetException(Throwable exception) {
+ Throwable target;
+ //
+ // Unwrap deep chain of exceptions to find StackOverflowError:
+ //
+ for (
+ target = exception;
+ target instanceof InvocationTargetException;
+ target = ((InvocationTargetException) target).getTargetException()
+ )
+ ;
+ return target;
+ }
+
+ private Method method = null;
+ private Object params[] = null;
+
+ private void invokeRecurse(int depth) throws Exception {
+ if (method == null) {
+ //
+ // Optimization trick: allocate once, use everywhere.
+ //
+ method = stack018.class.getMethod("recurse");
+ params = new Object[]{};
+ }
+ this.depth = depth; // actual parameter
+ method.invoke(this, params);
+ }
+
+ private int depth = 0; // actual parameter for recurse()
+
+ public void recurse() throws Exception {
+ if (depth > 0)
+ //
+ // Self-invoke via reflection:
+ //
+ invokeRecurse(depth - 1);
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack019.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack019.java
new file mode 100644
index 00000000000..0e880e4cd88
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack019.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/stack/stack019.
+ * VM testbase keywords: [stress, diehard, stack, nonconcurrent, exclude]
+ * VM testbase comments: 8139875
+ * VM testbase readme:
+ * DESCRIPTION
+ * The test invokes infinitely recursive method from within stack
+ * overflow handler -- repeatedly multiple times in a single thread.
+ * The test is deemed passed, if VM have not crashed, and if exception
+ * other than due to stack overflow was not thrown.
+ * COMMENTS
+ * This test crashes HS versions 2.0, 1.3, and 1.4 on both
+ * Solaris and Win32 platforms.
+ * See the bug:
+ * 4366625 (P4/S4) multiple stack overflow causes HS crash
+ *
+ * @ignore 8139875
+ * @run main/othervm nsk.stress.stack.stack019 -eager
+ */
+
+package nsk.stress.stack;
+
+
+import nsk.share.Harakiri;
+
+import java.io.PrintStream;
+
+public class stack019 {
+ private final static int CYCLES = 100;
+ private final static int PROBES = 100;
+
+ public static void main(String[] args) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ public static int run(String args[], PrintStream out) {
+ boolean verbose = false, eager = false;
+ for (int i = 0; i < args.length; i++)
+ if (args[i].toLowerCase().equals("-verbose"))
+ verbose = true;
+ else if (args[i].toLowerCase().equals("-eager"))
+ eager = true;
+ if (!eager)
+ Harakiri.appoint(Harakiri.parseAppointment(args));
+ //
+ // Measure recursive depth before stack overflow:
+ //
+ try {
+ recurse(0);
+ } catch (StackOverflowError soe) {
+ } catch (OutOfMemoryError oome) {
+ }
+ out.println("Maximal recursion depth: " + maxDepth);
+ depthToTry = maxDepth;
+
+ //
+ // Run the tested threads:
+ //
+ for (int i = 0; i < CYCLES; i++) {
+ try {
+ out.println("Iteration: " + i + "/" + CYCLES);
+ trickyRecurse(0);
+ out.println("# TEST_BUG: stack overflow was expected!");
+ return 2;
+
+ } catch (StackOverflowError error) {
+ } catch (OutOfMemoryError oome) {
+ // It's OK: stack overflow was expected.
+
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath)
+ throw (ThreadDeath) throwable;
+ throwable.printStackTrace(out);
+ return 2;
+ }
+ }
+ return 0;
+ }
+
+ private static int maxDepth;
+ private static int depthToTry;
+
+ private static void recurse(int depth) {
+ maxDepth = depth;
+ recurse(depth + 1);
+ }
+
+ private static void trickyRecurse(int depth) {
+ try {
+ maxDepth = depth;
+ trickyRecurse(depth + 1);
+ } catch (Error error) {
+ if (!(error instanceof StackOverflowError) &&
+ !(error instanceof OutOfMemoryError))
+ throw error;
+
+ //
+ // Stack problem caugth: provoke it again,
+ // if current stack is enough deep:
+ //
+ if (depth < depthToTry - PROBES)
+ throw error;
+ recurse(depth + 1);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace003.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace003.c
new file mode 100644
index 00000000000..fbf6e224451
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace003.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace003.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace004.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace004.c
new file mode 100644
index 00000000000..f0b30df1f07
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace004.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace004.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace005.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace005.c
new file mode 100644
index 00000000000..1468d6ad7a7
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace005.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace005.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace006.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace006.c
new file mode 100644
index 00000000000..264275d4fa2
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace006.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace006.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace008.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace008.c
new file mode 100644
index 00000000000..d164192a912
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace008.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace008.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace009.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace009.c
new file mode 100644
index 00000000000..d933cf6475c
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace009.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace009.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace011.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace011.c
new file mode 100644
index 00000000000..6bf1ed9106a
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace011.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace011.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace012.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace012.c
new file mode 100644
index 00000000000..0c8092d2363
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace012.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace012.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace014.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace014.c
new file mode 100644
index 00000000000..c436f7b5e90
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace014.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace014.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace015.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace015.c
new file mode 100644
index 00000000000..22b7ccb89b9
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/libstrace015.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni_tools.c"
+#include "nsk_tools.c"
+#include "strace015.c"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.h b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.h
new file mode 100644
index 00000000000..0f6644e6f5e
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/nsk_strace.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include java.lang.Thread.getStackTrace() method for many threads,
+ * that recursively invoke a pure java method in running mode ("alive" stack).
+ * THRD_COUNT instances of strace001Thread
+ * class, tries to get their stack traces and checks up that returned array contains
+ * correct stack frames. Each stack frame must be corresponded to one of the following
+ * methods defined by the EXPECTED_METHODS array.REPEAT_COUNT times.java.lang.Thread.getAllStackTraces() method for many
+ * threads, that recursively invoke a pure java method in running mode ("alive" stack).
+ * THRD_COUNT instances of strace002Thread
+ * class, tries to get their stack traces and checks up that returned array contains
+ * correct stack frames. Each stack frame must be corresponded to one of the following
+ * methods defined by the EXPECTED_METHODS array.REPEAT_COUNT times.java.lang.Thread.getStackTrace() method for many threads,
+ * that recursively invoke a native method in running mode ("alive" stack).
+ * THRD_COUNT instances of strace003Thread
+ * class, tries to get their stack traces and checks up that returned array contains
+ * correct stack frames. Each stack frame must be corresponded to one of the following
+ * methods defined by the EXPECTED_METHODS array.REPEAT_COUNT times.java.lang.Thread.getAllStackTraces() method for many
+ * threads, that recursively invoke a native method in running mode ("alive" stack).
+ * THRD_COUNT instances of strace004Thread
+ * class, tries to get their stack traces and checks up that returned array contains
+ * correct stack frames. Each stack frame must be corresponded to one of the following
+ * methods defined by the EXPECTED_METHODS array.REPEAT_COUNT times.java.lang.Thread.getStackTrace() method for many threads,
+ * that recursively invoke pure java and native methods by turns in running mode
+ * ("alive" stack).
+ * THRD_COUNT instances of strace005Thread
+ * class, tries to get their stack traces and checks up that returned array contains
+ * correct stack frames. Each stack frame must be corresponded to one of the following
+ * methods defined by the EXPECTED_METHODS array.REPEAT_COUNT times.strace005Thread class and tries
+ * to get their stack traces.
+ */
+class strace005Thread extends Thread {
+
+ private int currentDepth = 0;
+ public boolean isNativeResolved = false;
+
+ strace005 test;
+
+ static {
+ try {
+ System.loadLibrary("strace005");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Could not load strace005 library");
+ System.err.println("java.library.path:"
+ + System.getProperty("java.library.path"));
+ throw e;
+ }
+ }
+
+ strace005Thread(strace005 test, String name) {
+ this.test = test;
+ setName(name);
+ }
+
+ public void run() {
+
+ recursiveMethod1();
+
+ }
+
+ void recursiveMethod1() {
+
+ currentDepth++;
+
+ if (currentDepth == 1) {
+ synchronized (test) {
+ test.achivedCount++;
+ }
+
+ int alltime = 0;
+ while (!strace005.isLocked) {
+ synchronized (test) {
+ try {
+ test.wait(1);
+ alltime++;
+ } catch (InterruptedException e) {
+ strace005.complain("" + e);
+ }
+ if (alltime > strace005.waitTime) {
+ throw new Failure("out of wait time");
+ }
+ }
+ }
+ } else if (currentDepth > 1 && !isNativeResolved)
+ isNativeResolved = true;
+
+ if (strace005.DEPTH - currentDepth > 0) {
+ try {
+ yield();
+ recursiveMethod2();
+ } catch (StackOverflowError e) {
+ // ignore this exception
+ }
+ }
+
+ currentDepth--;
+ }
+
+ native void recursiveMethod2();
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace006.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace006.c
new file mode 100644
index 00000000000..50b89cbe033
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace006.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include java.lang.Thread.getStackTrace() method for the pure
+ * java recursion.
+ * THRD_COUNT instances of strace006Thread
+ * class, tries to get their stack traces and checks up that returned array contains
+ * correct stack frames. Each stack frame must be corresponded to one of the following
+ * methods defined by the expectedMethod array.REPEAT_COUNT times.strace006Thread class and tries
+ * to get their stack traces.
+ */
+class strace006Thread extends Thread {
+
+ private int currentDepth = 0;
+ public boolean isNativeResolved = false;
+
+ strace006 test;
+
+ static {
+ try {
+ System.loadLibrary("strace006");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Could not load strace006 library");
+ System.err.println("java.library.path:"
+ + System.getProperty("java.library.path"));
+ throw e;
+ }
+ }
+
+ strace006Thread(strace006 test, String name) {
+ this.test = test;
+ setName(name);
+ }
+
+ public void run() {
+
+ recursiveMethod1();
+
+ }
+
+ void recursiveMethod1() {
+
+ currentDepth++;
+
+ if (currentDepth == 1) {
+ synchronized (test) {
+ test.achivedCount++;
+ }
+
+ int alltime = 0;
+ while (!strace006.isLocked) {
+ synchronized (test) {
+ try {
+ test.wait(1);
+ alltime++;
+ } catch (InterruptedException e) {
+ strace006.complain("" + e);
+ }
+ if (alltime > strace006.waitTime) {
+ throw new Failure("out of wait time");
+ }
+ }
+ }
+ } else if (currentDepth > 1 && !isNativeResolved)
+ isNativeResolved = true;
+
+ if (strace006.DEPTH - currentDepth > 0) {
+ try {
+ yield();
+ recursiveMethod2();
+ } catch (StackOverflowError e) {
+ // ignore this exception
+ }
+ }
+
+ currentDepth--;
+ }
+
+ native void recursiveMethod2();
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace007.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace007.java
new file mode 100644
index 00000000000..96a46164bd0
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace007.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/strace/strace007.
+ * VM testbase keywords: [stress, quick, strace]
+ * VM testbase readme:
+ * DESCRIPTION
+ * The test runs many threads, that recursively invoke a pure java method.
+ * After arriving at defined depth of recursion, the test calls
+ * java.lang.Thread.getStackTrace() and java.lang.Thread.getAllStackTraces()
+ * methods and checks their results. All threads are running in a loop
+ * as long as these methods are executed.
+ * The test fails if:
+ * - amount of stack trace elements and stack trace elements themselves are
+ * the same for both methods;
+ * - there is at least one element corresponding to invocation of unexpected
+ * method. Expected methods are Thread.sleep(), Thread.run() and the
+ * recursive method.
+ *
+ * @library /vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @run main/othervm nsk.stress.strace.strace007
+ */
+
+package nsk.stress.strace;
+
+import nsk.share.ArgumentParser;
+import nsk.share.Log;
+
+import java.io.PrintStream;
+import java.util.Map;
+
+/**
+ * The test runs THRD_COUNT instances of strace007Thread,
+ * that recursively invoke a pure java method. After arriving at defined depth
+ * DEPTH of recursion, the test calls
+ * java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.THRD_COUNT instances of strace008Thread,
+ * that recursively invoke a native method. After arriving at defined depth
+ * DEPTH of recursion, the test calls
+ * java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.THRD_COUNT instances of strace009Thread,
+ * that recursively invoke pure java and native method by turns. After arriving at
+ * defined depth DEPTH of recursion, the test calls
+ * java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.THRD_COUNT instances of strace010Thread,
+ * that recursively invoke a pure java method. After arriving at defined depth
+ * DEPTH of recursion, each thread is blocked on entering a monitor.
+ * Then the test calls java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.THRD_COUNT instances of strace011Thread,
+ * that recursively invoke a native method. After arriving at defined depth
+ * DEPTH of recursion, each thread is blocked on entering a monitor.
+ * Then the test calls java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.THRD_COUNT instances of strace012Thread,
+ * that recursively invoke pure java and native method by turns. After arriving at
+ * defined depth DEPTH of recursion, each thread is blocked on entering
+ * a monitor. Then the test calls java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.THRD_COUNT instances of strace010Thread,
+ * that recursively invoke a pure java method. After arriving at defined depth
+ * DEPTH of recursion, each thread is switched to wait a monitor.
+ * Then the test calls java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.THRD_COUNT instances of strace010Thread,
+ * that recursively invoke a native method. After arriving at defined depth
+ * DEPTH of recursion, each thread is switched to wait a monitor.
+ * Then the test calls java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.strace014Thread class and tries
+ * to get their stack traces.
+ */
+class strace014Thread extends Thread {
+
+ private int currentDepth = 0;
+
+ strace014 test;
+
+ static {
+ try {
+ System.loadLibrary("strace014");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Could not load strace014 library");
+ System.err.println("java.library.path:"
+ + System.getProperty("java.library.path"));
+ throw e;
+ }
+ }
+
+ strace014Thread(strace014 test, String name) {
+ this.test = test;
+ setName(name);
+ }
+
+ public void run() {
+
+ recursiveMethod();
+
+ }
+
+ native void recursiveMethod();
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace015.c b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace015.c
new file mode 100644
index 00000000000..e0fe9f1792f
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace015.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include THRD_COUNT instances of strace010Thread,
+ * that recursively invoke pure java and native method by turns. After arriving at
+ * defined depth DEPTH of recursion, each thread is switched to wait
+ * a monitor. Then the test calls java.lang.Thread.getStackTrace() and
+ * java.lang.Thread.getAllStackTraces() methods and checks their results.
+ * EXPECTED_METHODS array.strace015Thread class and tries
+ * to get their stack traces.
+ */
+class strace015Thread extends Thread {
+
+ private int currentDepth = 0;
+
+ strace015 test;
+
+ static {
+ try {
+ System.loadLibrary("strace015");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Could not load strace015 library");
+ System.err.println("java.library.path:"
+ + System.getProperty("java.library.path"));
+ throw e;
+ }
+ }
+
+ strace015Thread(strace015 test, String name) {
+ this.test = test;
+ setName(name);
+ }
+
+ public void run() {
+
+ recursiveMethod1();
+
+ }
+
+ void recursiveMethod1() {
+ currentDepth++;
+
+ if (strace015.DEPTH - currentDepth > 0) {
+ recursiveMethod2();
+ }
+
+ if (strace015.DEPTH == currentDepth) {
+
+ strace015.display(getName() + ">waiting on a monitor");
+
+ synchronized (test) {
+ test.achivedCount++;
+ }
+
+ synchronized (strace015.lockedObject) {
+ try {
+ strace015.lockedObject.wait();
+ } catch (InterruptedException e) {
+ strace015.complain("" + e);
+ }
+ }
+ strace015.display(getName() + ">notified");
+ }
+
+ currentDepth--;
+ }
+
+ native void recursiveMethod2();
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/TEST.properties
new file mode 100644
index 00000000000..8b51b2a9115
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/TEST.properties
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread001.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread001.java
new file mode 100644
index 00000000000..4fdab351c79
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread001.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/thread/thread001.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * Try to start the given number of threads of the priority
+ * lower than the main thread.
+ *
+ * @library /test/lib
+ * @run main/othervm nsk.stress.thread.thread001 500 2m 5s
+ */
+
+package nsk.stress.thread;
+
+import java.io.PrintStream;
+import java.util.Vector;
+
+/**
+ * Try to start the given number of threads of the priority
+ * lower than the main thread.
+ */
+public class thread001 extends Thread {
+ /**
+ * Enable/disable printing of debugging info.
+ */
+ private static boolean DEBUG_MODE = false;
+
+ /**
+ * The minimal number of threads that the tested JVM must support.
+ * This number may be re-assigned by the command-line parameter.
+ */
+ private static int THREADS_EXPECTED = 1000;
+
+ /**
+ * Timeout (in milliseconds) after which all threads must halt.
+ */
+ private static long TIMEOUT = 300000; // 5 minutes
+
+ /**
+ * Wait few seconds to allow child threads actually start.
+ */
+ private static long YIELD_TIME = 5000; // 5 seconds
+
+ /**
+ * Once arg is ``XXXs'', or ``XXXm'', or ``XXXms'',
+ * return the given number of seconds, minutes, or milliseconds
+ * correspondingly.
+ */
+ private static long parseTime(String arg) {
+ for (int i = arg.lastIndexOf("ms"); i > -1; )
+ return Long.parseLong(arg.substring(0, i));
+ for (int i = arg.lastIndexOf("s"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 1000;
+ for (int i = arg.lastIndexOf("m"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 60000;
+ throw new IllegalArgumentException(
+ "cannot recognize time scale: " + arg);
+ }
+
+ /**
+ * Re-invoke to run(args,out) in a JCK style.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ /**
+ * Entry point for the JavaTest harness: args[0] must
+ * prescribe the value for the THREADS_EXPECTED field.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0)
+ THREADS_EXPECTED = Integer.parseInt(args[0]);
+ if (args.length > 1)
+ TIMEOUT = parseTime(args[1]);
+ if (args.length > 2)
+ YIELD_TIME = parseTime(args[2]);
+ if (args.length > 3)
+ DEBUG_MODE = args[3].toLowerCase().startsWith("-v");
+ if (args.length > 4) {
+ out.println("#");
+ out.println("# Too namy command-line arguments!");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE) {
+ out.println("Start " + THREADS_EXPECTED + " threads of lower priority,");
+ out.println("wait " + YIELD_TIME + " milliseconds to let them go,");
+ out.println("and halt after " + TIMEOUT + " milliseconds:");
+ }
+
+ Vector threadList = new Vector();
+ for (int i = 1; i <= THREADS_EXPECTED; i++)
+ try {
+ Thread thread = new thread001();
+ if (thread.getPriority() == Thread.MIN_PRIORITY) {
+ out.println("#");
+ out.println("# Sorry! -- The test cannot execute because");
+ out.println("# it cannot create threads with lower priority");
+ out.println("# than that executint run(args[],out) method.");
+ out.println("#");
+ out.println("# However, since no JVM mistakes were found,");
+ out.println("# the test finishes as PASSED.");
+ out.println("#");
+ return 0;
+ }
+ thread.setPriority(Thread.MIN_PRIORITY);
+ threadList.addElement(thread);
+ thread.start();
+
+ if (DEBUG_MODE)
+ out.println("Threads started: " + i);
+
+ } catch (OutOfMemoryError oome) {
+ oome.printStackTrace(out);
+ out.println("#");
+ out.println("# The test have FAILED:");
+ out.println("# Only " + i + " threads could start,");
+ out.println("# while at least " + THREADS_EXPECTED +
+ " were expected.");
+ out.println("#");
+ return 2;
+ }
+
+ // Actually let them go:
+ try {
+ doSleep(YIELD_TIME);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace(out);
+ out.println("#");
+ out.println("# OOPS! Could not let threads actually start!");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE)
+ out.println("The test have PASSED.");
+ return 0;
+ }
+
+ /**
+ * The thread activity: do nothing special, but do not
+ * free CPU time so that the thread's memory could not
+ * be moved to swap file.
+ */
+ public void run() {
+ while (!timeout())
+ continue;
+ }
+
+ private static long startTime = System.currentTimeMillis();
+
+ /**
+ * Check if timeout for this test is exceeded.
+ */
+ private boolean timeout() {
+ long elapsedTime = System.currentTimeMillis() - startTime;
+ return elapsedTime > TIMEOUT;
+ }
+
+ /**
+ * Yield to other threads for the given amount of
+ * time (milliseconds).
+ */
+ private static void doSleep(long time) throws InterruptedException {
+ //
+ // Since Java 2, the method Thread.sleep() doesn't guarantee
+ // to yield to other threads. So, call Object.wait() to yield:
+ //
+ Object lock = new Object(); // local scope, nobody can notify it
+ synchronized (lock) {
+ lock.wait(time);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread002.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread002.java
new file mode 100644
index 00000000000..a574533581f
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread002.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/thread/thread002.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * Try to start the given number of threads of the same
+ * priority that the main thread.
+ *
+ * @run main/othervm nsk.stress.thread.thread002 500 2m 5s
+ */
+
+package nsk.stress.thread;
+
+import java.io.PrintStream;
+import java.util.Vector;
+
+/**
+ * Try to start the given number of threads of the same
+ * priority that the main thread.
+ */
+public class thread002 extends Thread {
+ /**
+ * Enable/disable printing of debugging info.
+ */
+ private static boolean DEBUG_MODE = false;
+
+ /**
+ * The minimal number of threads that the tested JVM must support.
+ * (This number should be specified by the command-line parameter.
+ */
+ private static int THREADS_EXPECTED = 1000;
+
+ /**
+ * Timeout (in milliseconds) after which all threads must halt.
+ */
+ private static long TIMEOUT = 300000; // 5 minutes
+
+ /**
+ * Wait few seconds to allow child threads actually start.
+ */
+ private static long YIELD_TIME = 5000; // 5 seconds
+
+ /**
+ * Once arg is ``XXXs'', or ``XXXm'', or ``XXXms'',
+ * return the given number of seconds, minutes, or milliseconds
+ * correspondingly.
+ */
+ private static long parseTime(String arg) {
+ for (int i = arg.lastIndexOf("ms"); i > -1; )
+ return Long.parseLong(arg.substring(0, i));
+ for (int i = arg.lastIndexOf("s"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 1000;
+ for (int i = arg.lastIndexOf("m"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 60000;
+ throw new IllegalArgumentException(
+ "cannot recognize time scale: " + arg);
+ }
+
+ /**
+ * Re-invoke to run(args,out) in a JCK style.
+ */
+ public static void main(String args[]) {
+ System.exit(run(args, System.out) + 95);
+ }
+
+ /**
+ * Entry point for the JavaTest harness: args[0] must
+ * prescribe the value for the THREADS_EXPECTED field.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0)
+ THREADS_EXPECTED = Integer.parseInt(args[0]);
+ if (args.length > 1)
+ TIMEOUT = parseTime(args[1]);
+ if (args.length > 2)
+ YIELD_TIME = parseTime(args[2]);
+ if (args.length > 3)
+ DEBUG_MODE = args[3].toLowerCase().startsWith("-v");
+ if (args.length > 4) {
+ out.println("#");
+ out.println("# Too namy command-line arguments!");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE) {
+ out.println("Start " + THREADS_EXPECTED + " threads,");
+ out.println("wait " + YIELD_TIME + " milliseconds to let them go,");
+ out.println("and halt after " + TIMEOUT + " milliseconds:");
+ }
+
+ Vector threadList = new Vector();
+ for (int i = 1; i <= THREADS_EXPECTED; i++)
+ try {
+ Thread thread = new thread002();
+ threadList.addElement(thread);
+ thread.start();
+
+ if (DEBUG_MODE)
+ out.println("Threads started: " + i);
+
+ } catch (OutOfMemoryError oome) {
+ oome.printStackTrace(out);
+ out.println("#");
+ out.println("# The test have FAILED:");
+ out.println("# Only " + i + " threads could start,");
+ out.println("# while at least " + THREADS_EXPECTED +
+ " were expected.");
+ out.println("#");
+ return 2;
+ }
+
+ // Actually let them go:
+ try {
+ doSleep(YIELD_TIME);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace(out);
+ out.println("#");
+ out.println("# OOPS! Could not let threads actually start!");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE)
+ out.println("The test have PASSED.");
+ return 0;
+ }
+
+ /**
+ * The thread activity: do nothing special, but do not
+ * free CPU time so that the thread's memory could not
+ * be moved to swap file.
+ */
+ public void run() {
+ while (!timeout())
+ continue;
+ }
+
+ private static long startTime = System.currentTimeMillis();
+
+ /**
+ * Check if timeout for this test is exceeded.
+ */
+ private boolean timeout() {
+ long elapsedTime = System.currentTimeMillis() - startTime;
+ return elapsedTime > TIMEOUT;
+ }
+
+ /**
+ * Yield to other threads for the given amount of
+ * time (milliseconds).
+ */
+ private static void doSleep(long time) throws InterruptedException {
+ //
+ // Since Java 2, the method Thread.sleep() doesn't guarantee
+ // to yield to other threads. So, call Object.wait() to yield:
+ //
+ Object lock = new Object(); // local scope, nobody can notify it
+ synchronized (lock) {
+ lock.wait(time);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread005.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread005.java
new file mode 100644
index 00000000000..3d5fc0af8ab
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread005.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/thread/thread005.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * Try many threads starting simultaneously.
+ *
+ * @run main/othervm nsk.stress.thread.thread005 500 2m 5s
+ */
+
+package nsk.stress.thread;
+
+import java.io.PrintStream;
+
+/**
+ * Try many threads starting simultaneously.
+ */
+public class thread005 extends Thread {
+ /**
+ * Enable/disable printing of debugging info.
+ */
+ private static boolean DEBUG_MODE = false;
+
+ /**
+ * The number of threads that the tested JVM must support.
+ */
+ private static int THREADS_EXPECTED = 1000;
+
+ /**
+ * Timeout (in milliseconds) after which all threads must halt.
+ */
+ private static long TIMEOUT = 300000; // 5 minutes
+
+ /**
+ * Wait few seconds to allow child threads actually start.
+ */
+ private static long YIELD_TIME = 5000; // 5 seconds
+
+ /**
+ * Once arg is ``XXXs'', or ``XXXm'', or ``XXXms'',
+ * return the given number of seconds, minutes, or milliseconds
+ * correspondingly.
+ */
+ private static long parseTime(String arg) {
+ for (int i = arg.lastIndexOf("ms"); i > -1; )
+ return Long.parseLong(arg.substring(0, i));
+ for (int i = arg.lastIndexOf("s"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 1000;
+ for (int i = arg.lastIndexOf("m"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 60000;
+ throw new IllegalArgumentException(
+ "cannot recognize time scale: " + arg);
+ }
+
+ /**
+ * Re-invoke to run(args,out) to follow JCK style.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ /**
+ * JavaTest-like entry: args[] may reset
+ * THREADS_EXPECTED and TIMEOUT
+ * values.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0)
+ THREADS_EXPECTED = Integer.parseInt(args[0]);
+ if (args.length > 1)
+ TIMEOUT = parseTime(args[1]);
+ if (args.length > 2)
+ YIELD_TIME = parseTime(args[2]);
+ if (args.length > 3)
+ DEBUG_MODE = args[3].toLowerCase().startsWith("-v");
+ if (args.length > 4) {
+ out.println("#");
+ out.println("# Too namy command-line arguments!");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE) {
+ out.println(
+ "Start " + THREADS_EXPECTED + " threads, "
+ + "halt after " + TIMEOUT + " milliseconds:");
+ }
+
+ Thread thread[] = new Thread[THREADS_EXPECTED];
+ for (int i = 0; i < THREADS_EXPECTED; i++)
+ try {
+ thread[i] = new thread005();
+ thread[i].start();
+ if (DEBUG_MODE)
+ out.println("Threads started: " + (i + 1));
+ } catch (OutOfMemoryError oome) {
+ oome.printStackTrace(out);
+ out.println("#");
+ out.println("# The test have FAILED:");
+ out.println("# Only " + i + " threads could start,");
+ out.println("# while at least " + THREADS_EXPECTED +
+ " were expected.");
+ out.println("#");
+ return 2;
+ }
+
+ // Actually start:
+ GO = true;
+ // ...and let them go:
+ try {
+ doSleep(YIELD_TIME);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace(out);
+ out.println("#");
+ out.println("# OOPS! Could not let threads actually start!");
+ out.println("#");
+ return 2;
+ }
+ STOP = true;
+
+ if (DEBUG_MODE)
+ out.println("The test have PASSED.");
+ return 0;
+ }
+
+ private static boolean GO = false;
+ private static boolean STOP = false;
+
+ /**
+ * The thread activity: do nothing special, but do not
+ * free CPU time so that the thread's memory could not
+ * be moved to swap file.
+ */
+ public void run() {
+ while (!GO && !timeout())
+ yield();
+ while (!STOP && !timeout())
+ ;
+ }
+
+ private static long startTime = System.currentTimeMillis();
+
+ /**
+ * Check if timeout for this test is exceeded.
+ */
+ private boolean timeout() {
+ long elapsedTime = System.currentTimeMillis() - startTime;
+ return elapsedTime > TIMEOUT;
+ }
+
+ /**
+ * Yield to other threads for the given amount of
+ * time (milliseconds).
+ */
+ private static void doSleep(long time) throws InterruptedException {
+ //
+ // Since Java 2, the method Thread.sleep() doesn't guarantee
+ // to yield to other threads. So, call Object.wait() to yield:
+ //
+ Object lock = new Object(); // local scope, nobody can notify it
+ synchronized (lock) {
+ lock.wait(time);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread006.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread006.java
new file mode 100644
index 00000000000..34cff779638
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread006.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/thread/thread006.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * Try many threads of lower priority
+ * starting simultaneously.
+ *
+ * @run main/othervm nsk.stress.thread.thread006 500 2m 5s
+ */
+
+package nsk.stress.thread;
+
+
+import java.io.PrintStream;
+
+/**
+ * Try many threads of lower priority starting simultaneously.
+ */
+public class thread006 extends Thread {
+ /**
+ * Enable/disable printing of debugging info.
+ */
+ private static boolean DEBUG_MODE = false;
+
+ /**
+ * The minimal number of threads that the tested JVM must support.
+ * (This number should be specified by the command-line parameter.
+ */
+ private static int THREADS_EXPECTED = 1000;
+
+ /**
+ * Timeout (in milliseconds) after which all threads must halt.
+ */
+ private static long TIMEOUT = 300000; // 5 minutes
+
+ /**
+ * Wait few seconds to allow child threads actually start.
+ */
+ private static long YIELD_TIME = 5000; // 5 seconds
+
+ /**
+ * Once arg is ``XXXs'', or ``XXXm'', or ``XXXms'',
+ * return the given number of seconds, minutes, or milliseconds
+ * correspondingly.
+ */
+ private static long parseTime(String arg) {
+ for (int i = arg.lastIndexOf("ms"); i > -1; )
+ return Long.parseLong(arg.substring(0, i));
+ for (int i = arg.lastIndexOf("s"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 1000;
+ for (int i = arg.lastIndexOf("m"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 60000;
+ throw new IllegalArgumentException(
+ "cannot recognize time scale: " + arg);
+ }
+
+ /**
+ * Re-invoke to run(args,out) in a JCK style.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ /**
+ * JavaTest-like entry: args[] may reset
+ * THREADS_EXPECTED, TIMEOUT
+ * and YIELD_TIME values.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0)
+ THREADS_EXPECTED = Integer.parseInt(args[0]);
+ if (args.length > 1)
+ TIMEOUT = parseTime(args[1]);
+ if (args.length > 2)
+ YIELD_TIME = parseTime(args[2]);
+ if (args.length > 3)
+ DEBUG_MODE = args[3].toLowerCase().startsWith("-v");
+ if (args.length > 4) {
+ out.println("#");
+ out.println("# Too namy command-line arguments!");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE) {
+ out.println("Start " + THREADS_EXPECTED + " threads of lower priority,");
+ out.println("wait " + YIELD_TIME + " milliseconds to let them go,");
+ out.println("and halt after " + TIMEOUT + " milliseconds:");
+ }
+
+ Thread thread[] = new Thread[THREADS_EXPECTED];
+ for (int i = 0; i < THREADS_EXPECTED; i++)
+ try {
+ thread[i] = new thread006();
+ thread[i].setPriority(Thread.MIN_PRIORITY);
+ if (thread[i].getPriority() == currentThread().getPriority()) {
+ out.println("*");
+ out.println("* Sorry! -- The test cannot execute because");
+ out.println("* it cannot create threads with lower priority");
+ out.println("* than that executing run(args[],out) method.");
+ out.println("*");
+ out.println("* However, since no JVM mistakes were found,");
+ out.println("* the test finishes as PASSED.");
+ out.println("*");
+ return 0;
+ }
+ thread[i].start();
+ if (DEBUG_MODE)
+ out.println("Threads started: " + (i + 1));
+ } catch (OutOfMemoryError oome) {
+ oome.printStackTrace(out);
+ out.println("#");
+ out.println("# The test have FAILED:");
+ out.println("# Only " + i + " threads could start,");
+ out.println("# while at least " + THREADS_EXPECTED +
+ " were expected.");
+ out.println("#");
+ return 2;
+ }
+
+ // Actually start:
+ GO = true;
+ // ...and let them go:
+ try {
+ doSleep(YIELD_TIME);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace(out);
+ out.println("#");
+ out.println("# OOPS! Could not let threads actually start!");
+ out.println("#");
+ return 2;
+ }
+ STOP = true;
+
+ if (DEBUG_MODE)
+ out.println("The test have PASSED.");
+ return 0;
+ }
+
+ private static boolean GO = false;
+ private static boolean STOP = false;
+
+
+ /**
+ * The thread activity: do nothing special, but do not
+ * free CPU time so that the thread's memory could not
+ * be moved to swap file.
+ */
+ public void run() {
+ while (!GO && !timeout())
+ yield();
+ while (!STOP && !timeout())
+ ;
+ }
+
+ private static long startTime = System.currentTimeMillis();
+
+ /**
+ * Check if timeout for this test is exceeded.
+ */
+ private boolean timeout() {
+ long elapsedTime = System.currentTimeMillis() - startTime;
+ return elapsedTime > TIMEOUT;
+ }
+
+ /**
+ * Yield to other threads for the given amount of
+ * time (milliseconds).
+ */
+ private static void doSleep(long time) throws InterruptedException {
+ //
+ // Since Java 2, the method Thread.sleep() doesn't guarantee
+ // to yield to other threads. So, call Object.wait() to yield:
+ //
+ Object lock = new Object(); // local scope, nobody can notify it
+ synchronized (lock) {
+ lock.wait(time);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread007.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread007.java
new file mode 100644
index 00000000000..07031a783bf
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread007.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/thread/thread007.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * Try to start the given number of threads starting simultaneously
+ * when notifyall() is signaled at the stopLine object.
+ *
+ * @run main/othervm nsk.stress.thread.thread007 500 2m 5s
+ */
+
+package nsk.stress.thread;
+
+import java.io.PrintStream;
+
+/**
+ * Try to start the given number of threads starting simultaneously
+ * when notifyall() is signaled at the stopLine
+ * object.
+ */
+public class thread007 extends Thread {
+ /**
+ * Enable/disable printing of debugging info.
+ */
+ private static boolean DEBUG_MODE = false;
+
+ /**
+ * The minimal number of threads that the tested JVM must support.
+ * (This number should be specified by the command-line parameter.
+ */
+ private static int THREADS_EXPECTED = 1000;
+
+ /**
+ * Timeout (in milliseconds) after which all threads must halt.
+ */
+ private static long TIMEOUT = 300000; // 5 minutes
+
+ /**
+ * Wait few seconds to allow child threads actually start.
+ */
+ private static long YIELD_TIME = 5000; // 5 seconds
+
+ /**
+ * Once arg is ``XXXs'', or ``XXXm'', or ``XXXms'',
+ * return the given number of seconds, minutes, or milliseconds
+ * correspondingly.
+ */
+ private static long parseTime(String arg) {
+ for (int i = arg.lastIndexOf("ms"); i > -1; )
+ return Long.parseLong(arg.substring(0, i));
+ for (int i = arg.lastIndexOf("s"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 1000;
+ for (int i = arg.lastIndexOf("m"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 60000;
+ throw new IllegalArgumentException(
+ "cannot recognize time scale: " + arg);
+ }
+
+ /**
+ * Re-invoke to run(args,out) in a JCK style.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ /**
+ * Entry point for the JavaTest harness: args[0] must
+ * prescribe the value for the THREADS_EXPECTED field.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0)
+ THREADS_EXPECTED = Integer.parseInt(args[0]);
+ if (args.length > 1)
+ TIMEOUT = parseTime(args[1]);
+ if (args.length > 2)
+ YIELD_TIME = parseTime(args[2]);
+ if (args.length > 3)
+ DEBUG_MODE = args[3].toLowerCase().startsWith("-v");
+ if (args.length > 4) {
+ out.println("#");
+ out.println("# Too namy command-line arguments!");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE) {
+ out.println("Start " + THREADS_EXPECTED + " threads,");
+ out.println("wait " + YIELD_TIME + " milliseconds to let them go,");
+ out.println("and halt after " + TIMEOUT + " milliseconds:");
+ }
+
+ Thread thread[] = new Thread[THREADS_EXPECTED];
+ int i;
+ for (i = 0; i < THREADS_EXPECTED; i++)
+ try {
+ thread[i] = new thread007();
+ thread[i].start();
+ if (DEBUG_MODE)
+ out.println("Threads started: " + (i + 1));
+ } catch (OutOfMemoryError oome) {
+ oome.printStackTrace(out);
+ out.println("#");
+ out.println("# The test have FAILED:");
+ out.println("# Only " + i + " threads could start,");
+ out.println("# while at least " + THREADS_EXPECTED +
+ " were expected.");
+ out.println("#");
+ return 2;
+ }
+
+ // Actually start:
+ synchronized (stopLine) {
+ stopLine.notifyAll();
+ }
+ // ...and let them go:
+ try {
+ doSleep(YIELD_TIME);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace(out);
+ out.println("#");
+ out.println("# OOPS! Could not let threads actually start!");
+ out.println("#");
+ return 2;
+ }
+
+ if (oopsCounter > 0) {
+ out.println("#");
+ out.println("# The test have FAILED, because:");
+ out.println("# " + oopsCounter + " threads were interrupted.");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE)
+ out.println("The test have PASSED.");
+ return 0;
+ }
+
+ static Object stopLine = new Object();
+ static int oopsCounter = 0;
+
+ /**
+ * The thread activity: do nothing special, but do not
+ * free CPU time so that the thread's memory could not
+ * be moved to swap file.
+ */
+ public void run() {
+ synchronized (stopLine) {
+ try {
+ stopLine.wait();
+ } catch (InterruptedException oops) {
+ oopsCounter++;
+ return;
+ }
+ }
+ while (!timeout())
+ continue;
+ }
+
+ private static long startTime = System.currentTimeMillis();
+
+ /**
+ * Check if timeout for this test is exceeded.
+ */
+ private boolean timeout() {
+ long elapsedTime = System.currentTimeMillis() - startTime;
+ return elapsedTime > TIMEOUT;
+ }
+
+ /**
+ * Yield to other threads for the given amount of
+ * time (milliseconds).
+ */
+ private static void doSleep(long time) throws InterruptedException {
+ //
+ // Since Java 2, the method Thread.sleep() doesn't guarantee
+ // to yield to other threads. So, call Object.wait() to yield:
+ //
+ Object lock = new Object(); // local scope, nobody can notify it
+ synchronized (lock) {
+ lock.wait(time);
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread008.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread008.java
new file mode 100644
index 00000000000..40a76e00d11
--- /dev/null
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread008.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key stress
+ *
+ * @summary converted from VM testbase nsk/stress/thread/thread008.
+ * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
+ * VM testbase readme:
+ * DESCRIPTION
+ * Try to start the given number of threads of the lower priority
+ * starting simultaneously when notifyall() is signaled at the
+ * stopLine object.
+ *
+ * @run main/othervm nsk.stress.thread.thread008 500 2m 5s
+ */
+
+package nsk.stress.thread;
+
+import java.io.PrintStream;
+
+/**
+ * Try to start the given number of threads of lower priority and
+ * starting simultaneously when notifyall() is signaled
+ * at the stopLine object.
+ */
+public class thread008 extends Thread {
+ /**
+ * Enable/disable printing of debugging info.
+ */
+ private static boolean DEBUG_MODE = false;
+
+ /**
+ * The minimal number of threads that the tested JVM must support.
+ * (This number should be specified by the command-line parameter.
+ */
+ private static int THREADS_EXPECTED = 1000;
+
+ /**
+ * Timeout (in milliseconds) after which all threads must halt.
+ */
+ private static long TIMEOUT = 300000; // 5 minutes
+
+ /**
+ * Wait few seconds to allow child threads actually start.
+ */
+ private static long YIELD_TIME = 5000; // 5 seconds
+
+ /**
+ * Once arg is ``XXXs'', or ``XXXm'', or ``XXXms'',
+ * return the given number of seconds, minutes, or milliseconds
+ * correspondingly.
+ */
+ private static long parseTime(String arg) {
+ for (int i = arg.lastIndexOf("ms"); i > -1; )
+ return Long.parseLong(arg.substring(0, i));
+ for (int i = arg.lastIndexOf("s"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 1000;
+ for (int i = arg.lastIndexOf("m"); i > -1; )
+ return Long.parseLong(arg.substring(0, i)) * 60000;
+ throw new IllegalArgumentException(
+ "cannot recognize time scale: " + arg);
+ }
+
+ /**
+ * Re-invoke to run(args,out) in a JCK style.
+ */
+ public static void main(String args[]) {
+ int exitCode = run(args, System.out);
+ System.exit(exitCode + 95);
+ }
+
+ /**
+ * Entry point for the JavaTest harness: args[0] must
+ * prescribe the value for the THREADS_EXPECTED field.
+ */
+ public static int run(String args[], PrintStream out) {
+ if (args.length > 0)
+ THREADS_EXPECTED = Integer.parseInt(args[0]);
+ if (args.length > 1)
+ TIMEOUT = parseTime(args[1]);
+ if (args.length > 2)
+ YIELD_TIME = parseTime(args[2]);
+ if (args.length > 3)
+ DEBUG_MODE = args[3].toLowerCase().startsWith("-v");
+ if (args.length > 4) {
+ out.println("#");
+ out.println("# Too namy command-line arguments!");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE) {
+ out.println("Start " + THREADS_EXPECTED + " threads of lower priority,");
+ out.println("wait " + YIELD_TIME + " milliseconds to let them go,");
+ out.println("and halt after " + TIMEOUT + " milliseconds:");
+ }
+
+ Thread thread[] = new Thread[THREADS_EXPECTED];
+ int i;
+ for (i = 0; i < THREADS_EXPECTED; i++)
+ try {
+ thread[i] = new thread008();
+ if (thread[i].getPriority() == Thread.MIN_PRIORITY) {
+ out.println("#");
+ out.println("# Sorry! -- The test cannot execute because");
+ out.println("# it cannot create threads with lower priority");
+ out.println("# than that executint run(args[],out) method.");
+ out.println("#");
+ out.println("# However, since no JVM mistakes were found,");
+ out.println("# the test finishes as PASSED.");
+ out.println("#");
+ return 0;
+ }
+ thread[i].setPriority(Thread.MIN_PRIORITY);
+ thread[i].start();
+ if (DEBUG_MODE)
+ out.println("Threads started: " + (i + 1));
+ } catch (OutOfMemoryError oome) {
+ oome.printStackTrace(out);
+ out.println("#");
+ out.println("# The test have FAILED:");
+ out.println("# Only " + i + " threads could start,");
+ out.println("# while at least " + THREADS_EXPECTED +
+ " were expected.");
+ out.println("#");
+ return 2;
+ }
+
+ // Actually start:
+ synchronized (stopLine) {
+ stopLine.notifyAll();
+ }
+ // ...and let them go:
+ try {
+ doSleep(YIELD_TIME);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace(out);
+ out.println("#");
+ out.println("# OOPS! Could not let threads actually start!");
+ out.println("#");
+ return 2;
+ }
+
+ if (oopsCounter > 0) {
+ out.println("#");
+ out.println("# The test have FAILED, because:");
+ out.println("# " + oopsCounter + " threads were interrupted.");
+ out.println("#");
+ return 2;
+ }
+
+ if (DEBUG_MODE)
+ out.println("The test have PASSED.");
+ return 0;
+ }
+
+ static Object stopLine = new Object();
+ static int oopsCounter = 0;
+
+ /**
+ * The thread activity: do nothing special, but do not
+ * free CPU time so that the thread's memory could not
+ * be moved to swap file.
+ */
+ public void run() {
+ synchronized (stopLine) {
+ try {
+ stopLine.wait();
+ } catch (InterruptedException oops) {
+ oopsCounter++;
+ return;
+ }
+ }
+ while (!timeout())
+ continue;
+ }
+
+ private static long startTime = System.currentTimeMillis();
+
+ /**
+ * Check if timeout for this test is exceeded.
+ */
+ private boolean timeout() {
+ long elapsedTime = System.currentTimeMillis() - startTime;
+ return elapsedTime > TIMEOUT;
+ }
+
+ /**
+ * Yield to other threads for the given amount of
+ * time (milliseconds).
+ */
+ private static void doSleep(long time) throws InterruptedException {
+ //
+ // Since Java 2, the method Thread.sleep() doesn't guarantee
+ // to yield to other threads. So, call Object.wait() to yield:
+ //
+ Object lock = new Object(); // local scope, nobody can notify it
+ synchronized (lock) {
+ lock.wait(time);
+ }
+ }
+}