8199271: [TESTBUG] open source VM testbase stress tests

Reviewed-by: mseledtsov, sspitsyn, erikj
This commit is contained in:
Leonid Mesnik 2018-05-17 16:21:27 -07:00
parent 072459a055
commit 5dcd1ced4c
118 changed files with 28387 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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=.

View File

@ -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 <code>OutOfMemoryError</code> exception is correctly
* enwrapped into <code>InvocationTargetException</code> when thrown inside
* a method invoked via reflection.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* ``empty'' type <code>Object</code> 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
* <code>Throwable</code> instance, and VM possibly could crash while trying
* to throw new <code>OutOfMemoryError</code> and enwrap it into new
* <code>InvocationTargetException</code> instance.
* <p>
* <p>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 <code>Object</code> in this case
* (tested on Pentium-II, 350MHz, 128Mb RAM). To workaround this problem,
* the test enforces <code>OutOfMemoryError</code> if more then 5 minutes
* is spent to allocate ``last bytes'' of the memory.
*/
public class except001 {
/**
* This field allows or supresses printing with <code>display()</code>
* 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 <code>MODE_VERBOSE</code> is <code>true</code>
* (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 <code>message</code>.
*
* @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
* <code>run(args,out)</code>.
*
* @see #display(Object)
* @see #complain(Object)
* @see #run(String[], PrintStream)
*/
private static PrintStream out;
/**
* Try to allocate lots of instances of the type <code>Object</code>.
* Such instances are most fine-grained, and thus they should occupy
* smallest fragments of free memory in the heap.
* <p>
* <p>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 <code>raiseOutOfMemory()</code> with reflection,
* and check if the exception it throws is just
* <code>OutOfMemoryError</code> enwrapped into
* <code>InvocationTargetException</code> instance.
* <p>
* <p>Before the test begins, <code>this.out</code> filed is assigned
* to the parameter <code>out</code>. Parameter <code>args[]</code>
* 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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.
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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 <code>ClassNotFoundException</code>
* and <code>IllegalAccessException</code>.
*/
private static class Abra {
/**
* Will try to incorrectly find this class as <code>Cadabra</code>
* instead of <code>Abra$Cadabra</code>.
*/
public static class Cadabra {
}
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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 <code>ClassNotFoundException</code>
* and <code>IllegalAccessException</code>.
*/
private static class Abra {
/**
* Will try to incorrectly find this class as <code>Cadabra</code>
* instead of <code>Abra$Cadabra</code>.
*/
public static class Cadabra {
}
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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 <code>CloneNotSupportedException</code>,
* <code>IllegalAccessException</code>, and <code>IllegalArgumentException</code>.
* The class extends <code>except004</code> in order that its (protected)
* method <code>clone()</code> be available from <code>except004</code>.
*/
private static class Abra extends except004 {
/**
* Will try to incorrectly find this class as <code>Cadabra</code>
* instead of <code>Abra$Cadabra</code>.
*/
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 <code>int<code> zero.
*/
public static final boolean NOT_AN_INTEGER = false;
/**
* Will try to correctly instantiate <code>Abra.Cadabra</code>,
* not <code>Abra</code>.
*/
private Abra() {
}
/**
* Yet another constructor, which is <code>public</code>.
*/
public Abra(String nothingSpecial) {
}
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* <code>pool</code> to store tiny objects to fill up the Heap
*/
private static volatile Object pool[] = null;
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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 <code>CloneNotSupportedException</code>,
* <code>IllegalAccessException</code>, and <code>IllegalArgumentException</code>.
* The class extends <code>except005</code> in order that its (protected)
* method <code>clone()</code> be available from <code>except005</code>.
*/
private static class Abra {
/**
* Will correctly instantiate <code>Abra.Cadabra</code> object.
*/
public static class Cadabra {
}
/**
* Will try to correctly instantiate <code>Abra.Cadabra</code>,
* not <code>Abra</code>.
*/
private Abra() {
}
}
/**
* Will try to incorrectly instantiate and object of this class.
*/
private interface Abra_Cadabra {
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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 <code>CloneNotSupportedException</code>,
* <code>IllegalAccessException</code>, and <code>IllegalArgumentException</code>.
* The class extends <code>except006</code> in order that its (protected)
* method <code>clone()</code> be available from <code>except006</code>.
*/
private static class Abra {
/**
* Will correctly instantiate <code>Abra.Cadabra</code> object.
*/
public static class Cadabra {
}
/**
* Will try to correctly instantiate <code>Abra.Cadabra</code>,
* not <code>Abra</code>.
*/
private Abra() {
}
}
/**
* Will try to incorrectly instantiate and object of this class.
*/
private interface Abra_Cadabra {
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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.
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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.
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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.
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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.
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @see #log
*/
private static int messages = 0;
private static final String className = "nsk.stress.except.except011.except011oops";
/**
* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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.
}
}

View File

@ -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");
}
}

View File

@ -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
* <code>Throwable</code> instance.
* <p>
* <p>The test tries to occupy all of memory available in the heap by
* allocating lots of new <code>Object()</code> instances. Instances of the
* type <code>Object</code> are the smallest objects, so they apparently should
* occupy most fine-grained fragments in the heap and leave no free space for
* new <code>Throwable</code> 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.
* <p>
* <p>Note, that memory occupation is terminated if memory allocation slows
* down crucially. This is a workaround intended to avoid the HotSpot bug:
* <br>&nbsp;&nbsp;
* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
* <p>
* <p>There is also a workaround involved to avoid the following bugs known
* for HotSpot and for classic VM:
* <br>&nbsp;&nbsp;
* #4239841 (P1/S5) 1.1: poor garbage collector performance
* <br>&nbsp;&nbsp;
* #4245060 (P4/S5) poor garbage collector performance
* <br>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.
* <p>
* <p>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 <code>log</code> for error messages, warnings and/or execution trace.
*
* @see #messages
*/
private static String log[] = new String[1000]; // up to 1000 messages
/**
* How many <code>messages</code> were submitted to the <code>log</code>.
*
* @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 <code>run(out)</code> (ignore <code>args[]</code>),
* 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 <code>Object</code> 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 <code>ClassFormatError</code>.
*/
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 <code>ThreadDeath</code> 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 <code>run(args,out)</code>, and return JCK-like exit status.
* (The stream <code>out</code> is assigned to <code>System.out</code> 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.
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 {
}

View File

@ -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=.

View File

@ -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);
}

View File

@ -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 <jni.h>
#include <stdlib.h>
#include "jnihelper.h"
// compare most java primitive value types
#define COMP(type) \
int type##comp(const void *s1, const void *s2)\
{\
type st1 = *((type *)s1);\
type st2 = *((type *)s2);\
if (st1 < st2)\
return -1;\
else if (st1 > st2)\
return 1;\
else\
return 0;\
}
// basic routine: provide critical sections and calculations
// enter array CS
// check isCopy for native referencing
// enter first string CS
// leave first string CS
// enter second string CS
// leave array CS
// enter second string CS
#define BODY(type) \
int hash = 0; int i; jboolean isCopy = JNI_FALSE; jchar *nativeStr; jsize size; type *nativeArray; \
size = (*env)->GetArrayLength(env, array); CE \
nativeArray = (type *)(*env)->GetPrimitiveArrayCritical(env, array, &isCopy); CE \
EnterCS(env); \
if (isCopy == JNI_TRUE) return 0;\
qsort(nativeArray, size, sizeof(type), *type##comp);\
\
size = (*env)->GetStringLength(env, str); CE \
nativeStr = (jchar *)(*env)->GetStringCritical(env, str, &isCopy); CE \
if (isCopy == JNI_TRUE) return 0;\
for (i = 0; i < size; ++i)\
hash += (int)nativeStr[i];\
\
(*env)->ReleasePrimitiveArrayCritical(env, array, nativeArray, 0); CE \
LeaveCS(env); \
(*env)->ReleaseStringCritical(env, str, nativeStr); CE \
\
hash = 0;\
size = (*env)->GetStringLength(env, str); CE \
nativeStr = (jchar *)(*env)->GetStringCritical(env, str, &isCopy); CE \
EnterCS(env); \
if (isCopy == JNI_TRUE) return 0;\
for (i = 0; i < size; ++i)\
hash += (int)nativeStr[i];\
LeaveCS(env); \
(*env)->ReleaseStringCritical(env, str, nativeStr); CE \
return hash;
static int CSEntered = 0;
static int CSLeft = 0;
void EnterCS(JNIEnv *env)
{
// unsafe but where are no better ideas
//++CSEntered;
//printf("CS Entered -> Entered: %d\n", CSEntered);
// jclass trace = 0; jmethodID method = 0;
// trace = (*env)->FindClass(env, "nsk/stress/jni/gclocker/Trace"); CE
// method = (*env)->GetStaticMethodID(env, trace, "EnterCS", "()V"); CE
// (*env)->CallStaticVoidMethod(env, trace, method); CE
}
void LeaveCS(JNIEnv *env)
{
// unsafe but where are no better ideas
//++CSLeft;
//printf("CS Left -> Completed: %d\tActive: %d\n", CSLeft, CSEntered - CSLeft);
// jclass trace = 0; jmethodID method = 0;
// trace = (*env)->FindClass(env, "nsk/stress/jni/gclocker/Trace"); CE
// method = (*env)->GetStaticMethodID(env, trace, "LeaveCS", "()V"); CE
// (*env)->CallStaticVoidMethod(env, trace, method); CE
}
COMP(jint)
COMP(jboolean)
COMP(jchar)
COMP(jshort)
COMP(jbyte)
COMP(jdouble)
COMP(jfloat)
COMP(jlong)
/*
* Class: JNIWorker
* Method: NativeCall
* Signature: ([ZLjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_nsk_stress_jni_gclocker_JNIWorker_NativeCall___3ZLjava_lang_String_2
(JNIEnv * env, jobject obj, jbooleanArray array, jstring str)
{
BODY(jboolean)
}
/*
* Class: JNIWorker
* Method: NativeCall
* Signature: ([BLjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_nsk_stress_jni_gclocker_JNIWorker_NativeCall___3BLjava_lang_String_2
(JNIEnv * env, jobject obj, jbyteArray array, jstring str)
{
BODY(jbyte)
}
/*
* Class: JNIWorker
* Method: NativeCall
* Signature: ([CLjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_nsk_stress_jni_gclocker_JNIWorker_NativeCall___3CLjava_lang_String_2
(JNIEnv *env, jobject obj, jcharArray array, jstring str)
{
BODY(jchar)
}
/*
* Class: JNIWorker
* Method: NativeCall
* Signature: ([SLjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_nsk_stress_jni_gclocker_JNIWorker_NativeCall___3SLjava_lang_String_2
(JNIEnv *env, jobject obj, jshortArray array, jstring str)
{
BODY(jshort)
}
/*
* Class: JNIWorker
* Method: NativeCall
* Signature: ([ILjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_nsk_stress_jni_gclocker_JNIWorker_NativeCall___3ILjava_lang_String_2
(JNIEnv *env, jobject obj, jintArray array, jstring str)
{
BODY(jint)
}
/*
* Class: JNIWorker
* Method: NativeCall
* Signature: ([JLjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_nsk_stress_jni_gclocker_JNIWorker_NativeCall___3JLjava_lang_String_2
(JNIEnv *env, jobject obj, jlongArray array, jstring str)
{
BODY(jlong)
}
/*
* Class: JNIWorker
* Method: NativeCall
* Signature: ([FLjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_nsk_stress_jni_gclocker_JNIWorker_NativeCall___3FLjava_lang_String_2
(JNIEnv *env, jobject obj, jfloatArray array, jstring str)
{
BODY(jfloat)
}
/*
* Class: JNIWorker
* Method: NativeCall
* Signature: ([DLjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_nsk_stress_jni_gclocker_JNIWorker_NativeCall___3DLjava_lang_String_2
(JNIEnv *env, jobject obj, jdoubleArray array, jstring str)
{
BODY(jdouble)
}

View File

@ -0,0 +1,33 @@
/*
* 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.
*/
// Asserts every exception as fatal one
#define CE {\
if ((*env)->ExceptionOccurred(env))\
{\
puts("Unexpected JNI exception. TEST FAIL."); \
(*env)->ExceptionDescribe(env); \
(*env)->ExceptionClear(env);\
(*env)->FatalError(env, "Unexpected JNI Exception. TEST FAIL."); \
}\
}

View File

@ -0,0 +1,492 @@
/*
* 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.
*/
/*
* jnistress001 is a class that sets up classes that do the work
* for the test.
*
* The Interrupter objects send interrupts to the JNIters.
* The GarbageGenerator objects generate garbage.
*
* sync[0] synchronizes the test cycles.
* sync[1] synchronizes access to exception counters.
* sync[2] synchronizes the cycle count update. It also insures that
* the interrupts do not interfere with the cycle count updates.
* This is because cycle count updates are used to define cycles.
*/
/*
* @test
* @key stress
*
* @summary converted from VM testbase nsk/stress/jni/jnistress001.
* VM testbase keywords: [stress, quick, feature_283, nonconcurrent]
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native
* nsk.stress.jni.jnistress001
* -numTHREADer 20
* -threadInterval 200
* -numInterrupter 2
* -interruptInterval 500
* -numGarbage 80
* -garbageInterval 5
* -numIteration 200
*/
package nsk.stress.jni;
import nsk.share.Consts;
import nsk.share.Debug;
import nsk.share.test.StressOptions;
public class jnistress001 extends Thread {
/* Maximum number of iterations. Ignored if <= 0L */
static long numIteration = 0L;
/* Timeout */
static long timeOut;
/* Number of test class objects */
static int numJNIter = 1;
/* Time between JNI stressing by the threads under test */
/* (in milliseconds) */
static int jniInterval = 10000;
/* Number of interrupting threads */
static int numInterrupter = 1;
/* Time between interrupts in milliseconds */
static int interruptInterval = 1000;
/* Number of garbage generating threads */
static int numGarbage = 1;
/* Time between garbage allocations in milliseconds */
static int garbageInterval = 1000;
// Size of string's array in native method
static int jniStringAllocSize = 1000;
// Print period for native method
static int printPeriod = 200;
private static StressOptions stressOptions;
public static void main(String[] argv) {
try {
int i = 0;
int nJNISync = 10;
jnistress001 dm = null;
boolean errArg = false;
stressOptions = new StressOptions(argv);
/* Process arguments */
while (!errArg && i < argv.length) {
/* Number of iterations. Ignored if <= 0. */
if (i < argv.length && argv[i].equals("-numIteration")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numIteration = Long.parseLong(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numTHREADer")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numJNIter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
if (numJNIter <= 0) errArg = true;
}
} else if (i < argv.length && argv[i].equals("-threadInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numInterrupter")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numInterrupter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-interruptInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
interruptInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numGarbage")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numGarbage = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-garbageInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
garbageInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-jniStringAllocSize")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniStringAllocSize = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-printperiod")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
printPeriod = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].startsWith("-stress")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
++i;
}
} else System.out.println("Argument #" + i++ + " is incorrect");
}
numIteration *= stressOptions.getIterationsFactor();
numJNIter *= stressOptions.getThreadsFactor();
numInterrupter *= stressOptions.getThreadsFactor();
numGarbage *= stressOptions.getThreadsFactor();
timeOut = stressOptions.getTime() * 1000;
sync = new Synchronizer[10];
for (i = 0; i < nJNISync; i++)
sync[i] = new Synchronizer();
dm = new jnistress001(numIteration, numJNIter, jniInterval,
numInterrupter, interruptInterval, numGarbage, garbageInterval);
dm.start();
try {
dm.join(timeOut);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
if (DEBUG) System.out.println("jnistress001::main(): halt!");
if (dm.isAlive()) {
System.out.println("TIME LIMIT EXCEEDED");
dm.halt();
if (DEBUG) System.out.println("jnistress001::main(): join!");
try {
dm.join(10000L);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
} else {
System.out.println("TESTER THREAD FINISHED");
}
if (DEBUG) System.out.println("jnistress001::main(): zzzz...");
if (!JNIter001.passed())
System.exit(Consts.TEST_FAILED);
} catch (Throwable e) {
Debug.Fail(e);
}
}
jnistress001(
long iters,
int nJNI,
int jniInterval,
int nInter,
int iruptInterval,
int nGarb,
int garbInterval
) {
int i = 0;
nCycles = iters;
/* Should have at least one of nCycles>0 */
if (nCycles <= 0) nCycles = Long.MAX_VALUE;
jniter = new JNIter001[nJNI];
interval = jniInterval;
irupt = new Interrupter[nInter];
garb = new GarbageGenerator[nGarb];
for (i = 0; i < nJNI; i++)
jniter[i] = new JNIter001(sync);
for (i = 0; i < nInter; i++) {
irupt[i] = new Interrupter(jniter, sync);
irupt[i].setInterval(iruptInterval);
}
for (i = 0; i < nGarb; i++) {
garb[i] = new GarbageGenerator();
garb[i].setInterval(garbInterval);
}
}
public void run() {
int i = 0;
long iCycle = 0L;
JNIter001.clearCount();
JNIter001.clearInterruptCount();
for (i = 0; i < jniter.length; i++)
jniter[i].start();
while (JNIter001.getCount() < jniter.length) {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
JNIter001.clearCount();
// JNIter001.clearInterruptCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < garb.length; i++)
garb[i].start();
for (i = 0; i < irupt.length; i++)
irupt[i].start();
if (DEBUG) System.out.println("Cycles=" + nCycles);
for (iCycle = 0; iCycle < nCycles && !done && JNIter001.passed(); iCycle++) {
System.out.print("Cycle: " + iCycle);
try {
sleep(interval);
} catch (InterruptedException e) {
}
synchronized (sync[1]) {
System.out.println(" Interrupt count=" +
JNIter001.getInterruptCount());
}
JNIter001.clearCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
int n = 0;
for (i = 0; i < jniter.length; i++)
if (jniter[i].finished()) n++;
if (n == jniter.length) break;
}
if (JNIter001.passed()) { /* Use of setpass was backwards */
System.out.println("JNI TEST PASSED");
} else {
System.out.println("JNI TEST FAILED");
}
for (i = 0; i < irupt.length; i++)
irupt[i].halt();
for (i = 0; i < garb.length; i++)
garb[i].halt();
for (i = 0; i < jniter.length; i++)
jniter[i].halt();
/* Flush any waiters */
if (DEBUG) System.out.println("jnistress001::run(): before sync[0]");
synchronized (sync[0]) {
sync[0].notifyAll();
}
if (DEBUG) System.out.println("jnistress001::run(): after sync[0]");
for (i = 0; i < irupt.length; i++) {
try {
irupt[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress001::run(): X");
for (i = 0; i < garb.length; i++) {
try {
garb[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress001::run(): Y");
System.out.println("jniter.length is " + jniter.length);
for (i = 0; i < jniter.length; i++) {
try {
if (jniter[i].isAlive()) {
jniter[i].join();
}
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress001::run(): Z");
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
long nCycles = 0;
JNIter001[] jniter;
static Synchronizer[] sync;
private int interval = 100;
Interrupter[] irupt;
GarbageGenerator[] garb;
private boolean done = false;
final private static boolean DEBUG = false;
}
class JNIter001 extends Thread {
// The native method for testing JNI UTF-8 calls
public native String jnistress(String threadName, int nstr, int printPeriod);
// The native method for testing JNI Unicode calls
public native String jnistress1(String threadName, int nstr, int printPeriod);
static {
System.loadLibrary("jnistress001");
}
public JNIter001(Synchronizer[] aSync) {
sync = aSync;
}
public void run() {
int iter = 0;
/* Synchronize start of work */
incCount();
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
}
}
while (!done && pass) {
try {
/* Synchronized the JNI stressing */
synchronized (sync[2]) {
incCount();
}
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter001.incInterruptCount();
}
}
}
synchronized (sync[0]) {
String s1 = jnistress(getName(),
jnistress001.jniStringAllocSize,
jnistress001.printPeriod);
String s2 = jnistress1(getName(),
jnistress001.jniStringAllocSize,
jnistress001.printPeriod);
if (!s1.equals(s2))
System.out.println("Wrong compare in thread " + getName());
}
if (DEBUG)
System.out.println("We have " + activeCount() +
" threads now.");
} catch (Exception e) {
synchronized (sync[1]) {
JNIter001.incInterruptCount();
}
}
iter++;
iter = iter % CASECOUNT;
}
if (DEBUG) System.out.println("JNITer::run(): done=" + done);
done = true;
if (DEBUG) System.out.println("JNITer::run(): pass=" + JNIter001.pass);
if (DEBUG) System.out.println("JNITer::run(): done");
}
private synchronized static void incCount() {
count++;
}
public static int getCount() {
return count;
}
public synchronized static void clearCount() {
count = 0;
}
private synchronized static void incInterruptCount() {
interruptCount++;
}
public static int getInterruptCount() {
return interruptCount;
}
public synchronized static void clearInterruptCount() {
interruptCount = 0;
}
public static void halt() {
done = true;
}
public boolean finished() {
return done;
}
public static boolean passed() {
return pass;
}
public static void setpass(boolean value) {
pass = value;
}
Synchronizer[] sync;
private static int count = 0;
private static int interruptCount = 0;
private static boolean done = false;
private static boolean pass = true;
final private static int CASECOUNT = 2;
final private static boolean DEBUG = false;
}

View File

@ -0,0 +1,582 @@
/*
* 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.
*/
/*
* jnistress002 is a class that sets up classes that do the work
* for the test.
*
* The Interrupter objects send interrupts to the JNIters.
* The GarbageGenerator objects generate garbage.
*
* sync[0] synchronizes the test cycles.
* sync[1] synchronizes access to exception counters.
* sync[2] synchronizes the cycle count update. It also insures that
* the interrupts do not interfere with the cycle count updates.
* This is because cycle count updates are used to define cycles.
*/
/*
* @test
* @key stress
*
* @summary converted from VM testbase nsk/stress/jni/jnistress002.
* VM testbase keywords: [stress, quick, feature_283, nonconcurrent]
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native
* nsk.stress.jni.jnistress002
* -numTHREADer 20
* -threadInterval 200
* -numInterrupter 2
* -interruptInterval 500
* -numGarbage 80
* -garbageInterval 5
* -numIteration 260
*/
package nsk.stress.jni;
import nsk.share.Consts;
import nsk.share.Debug;
import nsk.share.test.StressOptions;
import java.lang.reflect.Field;
import java.util.Random;
public class jnistress002 extends Thread {
/* Maximum number of iterations. Ignored if <= 0L */
static long numIteration = 0L;
/* Timeout */
static long timeOut;
/* Number of test class objects */
static int numJNIter = 1;
/* Time between JNI stressing by the threads under test */
/* (in milliseconds) */
static int jniInterval = 10000;
/* Number of interrupting threads */
static int numInterrupter = 1;
/* Time between interrupts in milliseconds */
static int interruptInterval = 100;
/* Number of garbage generating threads */
static int numGarbage = 1;
/* Time between garbage allocations in milliseconds */
static int garbageInterval = 100;
// The number of classes for creates via JNI
static int jniStringAllocSize = 10000;
private static StressOptions stressOptions;
public static void main(String[] argv) {
try {
int i = 0;
int nJNISync = 10;
jnistress002 dm = null;
boolean errArg = false;
stressOptions = new StressOptions(argv);
/* Process arguments */
while (!errArg && i < argv.length) {
/* Number of iterations. Ignored if <= 0. */
if (i < argv.length && argv[i].equals("-numIteration")) {
++i;
if (i < argv.length) {
try {
numIteration = Long.parseLong(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numTHREADer")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numJNIter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
if (numJNIter <= 0) errArg = true;
}
} else if (i < argv.length && argv[i].equals("-threadInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numInterrupter")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numInterrupter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-interruptInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
interruptInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numGarbage")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numGarbage = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-garbageInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
garbageInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-jniStringAllocSize")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniStringAllocSize = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].startsWith("-stress")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
++i;
}
} else System.out.println("Argument #" + i++ + " is incorrect");
}
numIteration *= stressOptions.getIterationsFactor();
numJNIter *= stressOptions.getThreadsFactor();
numInterrupter *= stressOptions.getThreadsFactor();
numGarbage *= stressOptions.getThreadsFactor();
timeOut = stressOptions.getTime() * 1000;
sync = new Synchronizer[10];
for (i = 0; i < nJNISync; i++)
sync[i] = new Synchronizer();
dm = new jnistress002(numIteration, numJNIter, jniInterval,
numInterrupter, interruptInterval, numGarbage, garbageInterval);
dm.start();
try {
dm.join(timeOut);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
if (DEBUG) System.out.println("jnistress002::main(): halt!");
if (dm.isAlive()) {
System.out.println("TIME LIMIT EXCEEDED");
dm.halt();
if (DEBUG) System.out.println("jnistress002::main(): join!");
try {
dm.join(10000L);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
} else {
System.out.println("TESTER THREAD FINISHED");
}
if (DEBUG) System.out.println("jnistress002::main(): zzzz...");
if (!JNIter002.passed())
System.exit(Consts.TEST_FAILED);
} catch (Throwable e) {
Debug.Fail(e);
}
}
jnistress002(
long iters,
int nJNI,
int jniInterval,
int nInter,
int iruptInterval,
int nGarb,
int garbInterval
) {
int i = 0;
nCycles = iters;
/* Should have at least one of nCycles>0 */
if (nCycles <= 0) nCycles = Long.MAX_VALUE;
jniter = new JNIter002[nJNI];
interval = jniInterval;
irupt = new Interrupter[nInter];
garb = new GarbageGenerator[nGarb];
for (i = 0; i < nJNI; i++)
jniter[i] = new JNIter002(sync);
for (i = 0; i < nInter; i++) {
irupt[i] = new Interrupter(jniter, sync);
irupt[i].setInterval(iruptInterval);
}
for (i = 0; i < nGarb; i++) {
garb[i] = new GarbageGenerator();
garb[i].setInterval(garbInterval);
}
// premtive special class loading
objectsJNI clStub = new objectsJNI(null, 0, 0, null, 0, 0);
}
public void run() {
try {
int i = 0;
long iCycle = 0L;
JNIter002.clearCount();
JNIter002.clearInterruptCount();
for (i = 0; i < jniter.length; i++)
jniter[i].start();
while (JNIter002.getCount() < jniter.length) {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
JNIter002.clearCount();
// JNIter002.clearInterruptCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < garb.length; i++)
garb[i].start();
for (i = 0; i < irupt.length - 1; i++)
irupt[i].start();
if (DEBUG) System.out.println("Cycles=" + nCycles);
for (iCycle = 0; iCycle < nCycles && !done && JNIter002.passed(); iCycle++) {
System.out.print("Cycle: " + iCycle);
try {
sleep(interval);
} catch (InterruptedException e) {
}
synchronized (sync[1]) {
System.out.println(" Interrupt count=" +
JNIter002.getInterruptCount());
}
JNIter002.clearCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
int n = 0;
for (i = 0; i < jniter.length; i++)
if (jniter[i].finished()) n++;
if (n == jniter.length) break;
}
if (JNIter002.passed()) {
System.out.println("JNI TEST PASSED");
} else {
System.out.println("JNI TEST FAILED");
}
for (i = 0; i < irupt.length; i++)
irupt[i].halt();
for (i = 0; i < garb.length; i++)
garb[i].halt();
for (i = 0; i < jniter.length; i++)
jniter[i].halt();
/* Flush any waiters */
if (DEBUG) System.out.println("jnistress002::run(): before sync[0]");
synchronized (sync[0]) {
sync[0].notifyAll();
}
if (DEBUG) System.out.println("jnistress002::run(): after sync[0]");
for (i = 0; i < irupt.length; i++) {
try {
irupt[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress002::run(): X");
for (i = 0; i < garb.length; i++) {
try {
garb[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress002::run(): Y");
System.out.println("jniter.length is " + jniter.length);
for (i = 0; i < jniter.length; i++) {
try {
if (jniter[i].isAlive()) {
jniter[i].join();
}
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress002::run(): Z");
} catch (Throwable e) {
Debug.Fail(e);
}
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
long nCycles = 0;
JNIter002[] jniter;
static Synchronizer[] sync;
private int interval = 100;
Interrupter[] irupt;
GarbageGenerator[] garb;
private boolean done = false;
final private static boolean DEBUG = false;
}
class objectsJNI {
public String instName;
public int i;
public long l;
public char[] c;
public float f;
public double d;
public objectsJNI(String name,
int intgr,
long lng,
char[] charr,
float flt,
double dbl
) {
instName = name;
i = intgr;
l = lng;
f = flt;
d = dbl;
c = charr;
}
public boolean equals(Object o) {
if (this.getClass() != o.getClass())
return false;
Field[] fields = o.getClass().getFields();
try {
for (int i = 0; i < fields.length; i++) {
if (fields[i].get(o) instanceof char[]) {
for (int j = 0; j < ((char[]) fields[i].get(this)).length; j++)
if (((char[]) fields[i].get(this))[j] !=
((char[]) fields[i].get(o))[j]) {
System.out.println(
"Char arrays have difference in " + j);
return false;
}
} else if (!fields[i].get(this).equals(fields[i].get(o))) {
System.out.println(
"The fields No. " + i + " are different");
return false;
}
}
} catch (Exception e) {
System.out.println("Error : " + e);
}
;
return true;
}
}
class JNIter002 extends Thread {
// The native method for testing JNI Object's calls
public native objectsJNI[] jniobjects(String s, int i, long l,
char[] c, float f, double d);
static {
System.loadLibrary("jnistress002");
}
static Random myRandom = new Random();
public JNIter002(Synchronizer[] aSync) {
sync = aSync;
}
public void run() {
try {
String s;
int i;
long l;
char[] c;
float f;
double d;
int iter = 0;
/* Synchronize start of work */
incCount();
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
}
}
while (!done && pass) {
try {
/* Synchronized the JNI stressing */
synchronized (sync[2]) {
incCount();
}
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter002.incInterruptCount();
}
}
}
synchronized (sync[0]) {
i = myRandom.nextInt(Integer.MAX_VALUE);
l = myRandom.nextLong();
f = myRandom.nextFloat();
d = myRandom.nextDouble();
s = getName();
c = s.toCharArray();
objectsJNI test = new objectsJNI(s, i, l, c, f, d);
Object[] testJNI = jniobjects(s, i, l, c, f, d);
for (int j = 0; j < testJNI.length; j++)
if (!testJNI[j].equals(test)) {
System.out.println("Objects are different");
fieldprint("JNI object", testJNI[j]);
fieldprint("Java object", test);
pass = false;
}
}
if (DEBUG) System.out.println("We have " + activeCount() +
" threads now.");
synchronized (this) {
try {
wait(1L);
} catch (InterruptedException e) {
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter002.incInterruptCount();
}
}
iter++;
iter = iter % CASECOUNT;
}
if (DEBUG) System.out.println("JNITer::run(): done=" + done);
done = true;
if (DEBUG) System.out.println("JNITer::run(): pass=" + JNIter002.pass);
if (DEBUG) System.out.println("JNIter002::run(): done");
} catch (Throwable e) {
Debug.Fail(e);
}
}
private synchronized static void incCount() {
count++;
}
public static int getCount() {
return count;
}
public synchronized static void clearCount() {
count = 0;
}
private synchronized static void incInterruptCount() {
interruptCount++;
}
public static int getInterruptCount() {
return interruptCount;
}
public synchronized static void clearInterruptCount() {
interruptCount = 0;
}
public static void halt() {
done = true;
}
public boolean finished() {
return done;
}
public static boolean passed() {
return pass;
}
Synchronizer[] sync;
private static int count = 0;
private static int interruptCount = 0;
private static boolean done = false;
private static boolean pass = true;
final private static int CASECOUNT = 2;
final private static boolean DEBUG = false;
static void fieldprint(String s, Object obj) {
Field[] fields = obj.getClass().getFields();
System.out.println(s);
try {
for (int i = 0; i < fields.length; i++) {
if (fields[i].get(obj) instanceof java.lang.String)
System.out.println(
fields[i] + " = \"" + fields[i].get(obj) + "\"");
else if (fields[i].get(obj) instanceof char[])
System.out.println(fields[i] + " = \"" +
new String((char[]) fields[i].get(obj)) + "\"");
else
System.out.println(
fields[i] + " = " + fields[i].get(obj));
}
} catch (Exception e) {
System.out.println("Error: " + e);
}
}
}

View File

@ -0,0 +1,514 @@
/*
* 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.
*/
/*
* jnistress003 is a class that sets up classes that do the work
* for the test.
*
* The Interrupter objects send interrupts to the JNIters.
* The GarbageGenerator objects generate garbage.
*
* sync[0] synchronizes the test cycles.
* sync[1] synchronizes access to exception counters.
* sync[2] synchronizes the cycle count update. It also insures that
* the interrupts do not interfere with the cycle count updates.
* This is because cycle count updates are used to define cycles.
*/
/*
* @test
* @key stress
*
* @summary converted from VM testbase nsk/stress/jni/jnistress003.
* VM testbase keywords: [stress, quick, feature_283, nonconcurrent]
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native
* nsk.stress.jni.jnistress003
* -numTHREADer 20
* -threadInterval 200
* -numInterrupter 2
* -interruptInterval 500
* -numGarbage 80
* -garbageInterval 5
* -numIteration 260
*/
package nsk.stress.jni;
import nsk.share.Consts;
import nsk.share.Debug;
import nsk.share.test.StressOptions;
import java.lang.reflect.Array;
public class jnistress003 extends Thread {
/* Maximum number of iterations. Ignored if <= 0L */
static long numIteration = 0L;
/* Timeout */
static long timeOut;
/* Number of test class objects */
static int numJNIter = 1;
/* Time between JNI stressing by the threads under test */
/* (in milliseconds) */
static int jniInterval = 10000;
/* Number of interrupting threads */
static int numInterrupter = 1;
/* Time between interrupts in milliseconds */
static int interruptInterval = 100;
/* Number of garbage generating threads */
static int numGarbage = 1;
/* Time between garbage allocations in milliseconds */
static int garbageInterval = 100;
// The size of arrays creates via JNI
static int SIZE = 5000;
// The MAX quantity of creates arrays
static int jniStringAllocSize = 100000;
private static StressOptions stressOptions;
public static void main(String[] argv) {
try {
int i = 0;
int nJNISync = 10;
jnistress003 dm = null;
boolean errArg = false;
stressOptions = new StressOptions(argv);
/* Process arguments */
while (!errArg && i < argv.length) {
/* Number of iterations. Ignored if <= 0. */
if (i < argv.length && argv[i].equals("-numIteration")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numIteration = Long.parseLong(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numTHREADer")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numJNIter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
if (numJNIter <= 0) errArg = true;
}
} else if (i < argv.length && argv[i].equals("-threadInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numInterrupter")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numInterrupter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-interruptInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
interruptInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numGarbage")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numGarbage = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-garbageInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
garbageInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-arraysize")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
SIZE = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-jniStringAllocSize")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniStringAllocSize = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].startsWith("-stress")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
++i;
}
} else System.out.println("Argument #" + i++ + " is incorrect");
}
numIteration *= stressOptions.getIterationsFactor();
numJNIter *= stressOptions.getThreadsFactor();
numInterrupter *= stressOptions.getThreadsFactor();
numGarbage *= stressOptions.getThreadsFactor();
timeOut = stressOptions.getTime() * 1000;
sync = new Synchronizer[10];
for (i = 0; i < nJNISync; i++)
sync[i] = new Synchronizer();
dm = new jnistress003(numIteration, numJNIter, jniInterval,
numInterrupter, interruptInterval,
numGarbage, garbageInterval);
dm.start();
try {
dm.join(timeOut);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
if (DEBUG) System.out.println("jnistress003::main(): halt!");
if (dm.isAlive()) {
System.out.println("TIME LIMIT EXCEEDED");
dm.halt();
if (DEBUG) System.out.println("jnistress003::main(): join!");
try {
dm.join(10000L);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
} else {
System.out.println("TESTER THREAD FINISHED");
}
if (DEBUG) System.out.println("jnistress003::main(): zzzz...");
if (!JNIter003.passed())
System.exit(Consts.TEST_FAILED);
} catch (Throwable e) {
Debug.Fail(e);
}
}
jnistress003(
long iters,
int nJNI,
int jniInterval,
int nInter,
int iruptInterval,
int nGarb,
int garbInterval
) {
int i = 0;
nCycles = iters;
/* Should have at least one of nCycles>0 */
if (nCycles <= 0) nCycles = Long.MAX_VALUE;
jniter = new JNIter003[nJNI];
interval = jniInterval;
irupt = new Interrupter[nInter];
garb = new GarbageGenerator[nGarb];
for (i = 0; i < nJNI; i++)
jniter[i] = new JNIter003(sync);
for (i = 0; i < nInter; i++) {
irupt[i] = new Interrupter(jniter, sync);
irupt[i].setInterval(iruptInterval);
}
for (i = 0; i < nGarb; i++) {
garb[i] = new GarbageGenerator();
garb[i].setInterval(garbInterval);
}
}
public void run() {
try {
int i = 0;
long iCycle = 0L;
JNIter003.clearCount();
JNIter003.clearInterruptCount();
for (i = 0; i < jniter.length; i++)
jniter[i].start();
while (!done && JNIter003.getCount() < jniter.length) {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
JNIter003.clearCount();
// JNIter003.clearInterruptCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < garb.length; i++)
garb[i].start();
for (i = 0; i < irupt.length; i++)
irupt[i].start();
if (DEBUG) System.out.println("Cycles=" + nCycles);
for (iCycle = 0; iCycle < nCycles && !done && JNIter003.passed(); iCycle++) {
System.out.print("Cycle: " + iCycle);
try {
sleep(interval);
} catch (InterruptedException e) {
}
synchronized (sync[1]) {
System.out.println(" Interrupt count=" +
JNIter003.getInterruptCount());
}
JNIter003.clearCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
int n = 0;
for (i = 0; i < jniter.length; i++)
if (jniter[i].finished()) n++;
if (n == jniter.length) break;
}
if (JNIter003.passed()) {
System.out.println("JNI TEST PASSED");
} else {
System.out.println("JNI TEST FAILED");
}
for (i = 0; i < irupt.length; i++)
irupt[i].halt();
for (i = 0; i < garb.length; i++)
garb[i].halt();
for (i = 0; i < jniter.length; i++)
jniter[i].halt();
/* Flush any waiters */
if (DEBUG) System.out.println("jnistress003::run(): before sync[0]");
synchronized (sync[0]) {
sync[0].notifyAll();
}
if (DEBUG) System.out.println("jnistress003::run(): after sync[0]");
for (i = 0; i < irupt.length; i++) {
try {
irupt[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress003::run(): X");
for (i = 0; i < garb.length; i++) {
try {
garb[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress003::run(): Y");
for (i = 0; i < jniter.length; i++) {
try {
if (jniter[i].isAlive()) {
jniter[i].join();
}
} catch (InterruptedException e) {
}
}
synchronized (sync[0]) {
sync[0].notifyAll();
}
if (DEBUG) System.out.println("jnistress003::run(): Z");
} catch (Throwable e) {
Debug.Fail(e);
}
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
long nCycles = 0;
JNIter003[] jniter;
static Synchronizer[] sync;
private int interval = 100;
Interrupter[] irupt;
GarbageGenerator[] garb;
private boolean done = false;
final private static boolean DEBUG = false;
}
class JNIter003 extends Thread {
// The native methods for testing JNI Arrays calls
public native Object[] jniInitArrays(int size);
public native boolean jniBodyChangeArray(Object[] orig,
Object[] clone, int jniStringAllocSize);
static {
System.loadLibrary("jnistress003");
}
public JNIter003(Synchronizer[] aSync) {
sync = aSync;
}
public void run() {
try {
Object[] mainArray;
Object[] clonedArray;
int i, j;
int iter = 0;
/* Synchronize start of work */
incCount();
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
}
}
while (!done && pass) {
try {
/* Synchronized the JNI stressing */
synchronized (sync[2]) {
incCount();
}
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter003.incInterruptCount();
}
}
}
// synchronized(sync[0]) {
try {
mainArray = jniInitArrays(jnistress003.SIZE);
clonedArray = (Object[]) mainArray.clone();
JNIter003.pass = jniBodyChangeArray(mainArray, clonedArray,
jnistress003.jniStringAllocSize);
for (i = 0; i < 8; i++)
compared &= Array.get(mainArray, i).equals(Array.get(clonedArray, i));
} catch (OutOfMemoryError e) {
System.out.println("Error: " + e);
}
// }
if (DEBUG)
System.out.println("We have " + activeCount() + " threads now.");
JNIter003.pass = JNIter003.pass && compared;
synchronized (this) {
try {
wait(1L);
} catch (InterruptedException e) {
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter003.incInterruptCount();
}
}
iter++;
iter = iter % CASECOUNT;
}
if (DEBUG) System.out.println("JNITer::run(): done=" + done);
done = true;
if (DEBUG) System.out.println("JNITer::run(): pass=" + JNIter003.pass);
if (DEBUG) System.out.println("JNIter003::run(): done");
} catch (Throwable e) {
Debug.Fail(e);
}
}
private synchronized static void incCount() {
count++;
}
public static int getCount() {
return count;
}
public synchronized static void clearCount() {
count = 0;
}
private synchronized static void incInterruptCount() {
interruptCount++;
}
public static int getInterruptCount() {
return interruptCount;
}
public synchronized static void clearInterruptCount() {
interruptCount = 0;
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
public static boolean passed() {
return pass;
}
Synchronizer[] sync;
private static int count = 0;
private static int interruptCount = 0;
private boolean done = false;
private static boolean pass = true;
private static boolean compared = true;
final private static int CASECOUNT = 2;
final private static boolean DEBUG = false;
}

View File

@ -0,0 +1,498 @@
/*
* 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.
*/
/*
* jnistress004 is a class that sets up classes that do the work
* for the test.
*
* The Interrupter objects send interrupts to the JNIters.
* The GarbageGenerator objects generate garbage.
*
* sync[0] synchronizes the test cycles.
* sync[1] synchronizes access to exception counters.
* sync[2] synchronizes the cycle count update. It also insures that
* the interrupts do not interfere with the cycle count updates.
* This is because cycle count updates are used to define cycles.
*/
/*
* @test
* @key stress
*
* @summary converted from VM testbase nsk/stress/jni/jnistress004.
* VM testbase keywords: [stress, quick, feature_283, nonconcurrent]
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native
* nsk.stress.jni.jnistress004
* -numTHREADer 20
* -threadInterval 200
* -numInterrupter 2
* -interruptInterval 500
* -numGarbage 80
* -garbageInterval 5
* -numIteration 260
*/
package nsk.stress.jni;
import nsk.share.Consts;
import nsk.share.Debug;
import nsk.share.test.StressOptions;
public class jnistress004 extends Thread {
/* Maximum number of iterations. Ignored if <= 0L */
static long numIteration = 2L;
/* Timeout */
static long timeOut;
/* Number of test class objects */
static int numJNIter = 100;
/* Time between JNI stressing by the threads under test */
/* (in milliseconds) */
static int jniInterval = 25;
/* Number of interrupting threads */
static int numInterrupter = 10;
/* Time between interrupts in milliseconds */
static int interruptInterval = 45;
/* Number of garbage generating threads */
static int numGarbage = 1;
/* Time between garbage allocations in milliseconds */
static int garbageInterval = 100;
// The MAX quantity of critical operations
static int jniStringAllocSize = 50000;
private static StressOptions stressOptions;
public static void main(String[] argv) {
try {
int i = 0;
int nJNISync = 10;
jnistress004 dm = null;
boolean errArg = false;
stressOptions = new StressOptions(argv);
/* Process arguments */
while (!errArg && i < argv.length) {
/* Number of iterations. Ignored if <= 0. */
if (i < argv.length && argv[i].equals("-numIteration")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numIteration = Long.parseLong(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numTHREADer")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numJNIter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
if (numJNIter <= 0) errArg = true;
}
} else if (i < argv.length && argv[i].equals("-threadInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numInterrupter")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numInterrupter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-interruptInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
interruptInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numGarbage")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numGarbage = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-garbageInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
garbageInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-jniStringAllocSize")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniStringAllocSize = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].startsWith("-stress")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
++i;
}
} else System.out.println("Argument #" + i++ + " is incorrect");
}
numIteration *= stressOptions.getIterationsFactor();
numJNIter *= stressOptions.getThreadsFactor();
numInterrupter *= stressOptions.getThreadsFactor();
numGarbage *= stressOptions.getThreadsFactor();
timeOut = stressOptions.getTime() * 1000;
sync = new Synchronizer[10];
for (i = 0; i < nJNISync; i++)
sync[i] = new Synchronizer();
dm = new jnistress004(numIteration, numJNIter, jniInterval,
numInterrupter, interruptInterval, numGarbage, garbageInterval);
dm.start();
try {
dm.join(timeOut);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
if (DEBUG) System.out.println("jnistress004::main(): halt!");
if (dm.isAlive()) {
System.out.println("TIME LIMIT EXCEEDED");
dm.halt();
if (DEBUG) System.out.println("jnistress004::main(): join!");
try {
dm.join(10000L);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
} else {
System.out.println("TESTER THREAD FINISHED");
}
if (DEBUG) System.out.println("jnistress004::main(): zzzz...");
if (!JNIter004.passed())
System.exit(Consts.TEST_FAILED);
} catch (Throwable e) {
Debug.Fail(e);
}
}
jnistress004(
long iters,
int nJNI,
int jniInterval,
int nInter,
int iruptInterval,
int nGarb,
int garbInterval
) {
int i = 0;
nCycles = iters;
/* Should have at least one of nCycles>0 */
if (nCycles <= 0) nCycles = Long.MAX_VALUE;
jniter = new JNIter004[nJNI];
interval = jniInterval;
irupt = new Interrupter[nInter];
garb = new GarbageGenerator[nGarb];
for (i = 0; i < nJNI; i++)
jniter[i] = new JNIter004(sync);
for (i = 0; i < nInter; i++) {
irupt[i] = new Interrupter(jniter, sync);
irupt[i].setInterval(iruptInterval);
}
for (i = 0; i < nGarb; i++) {
garb[i] = new GarbageGenerator();
garb[i].setInterval(garbInterval);
}
}
public void run() {
try {
int i = 0;
long iCycle = 0L;
JNIter004.clearCount();
JNIter004.clearInterruptCount();
for (i = 0; i < jniter.length; i++)
jniter[i].start();
while (JNIter004.getCount() < jniter.length) {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
JNIter004.clearCount();
// JNIter004.clearInterruptCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < garb.length; i++)
garb[i].start();
for (i = 0; i < irupt.length; i++)
irupt[i].start();
if (DEBUG) System.out.println("Cycles=" + nCycles);
for (iCycle = 0; iCycle < nCycles && !done && JNIter004.passed(); iCycle++) {
System.out.print("Cycle: " + iCycle);
try {
sleep(interval);
} catch (InterruptedException e) {
}
synchronized (sync[1]) {
System.out.println(" Interrupt count=" +
JNIter004.getInterruptCount());
}
JNIter004.clearCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
int n = 0;
for (i = 0; i < jniter.length; i++)
if (jniter[i].finished()) n++;
if (n == jniter.length) break;
}
if (JNIter004.passed())
System.out.println("JNI TEST PASSED");
else
System.out.println("JNI TEST FAILED");
for (i = 0; i < irupt.length; i++)
irupt[i].halt();
for (i = 0; i < garb.length; i++)
garb[i].halt();
for (i = 0; i < jniter.length; i++)
jniter[i].halt();
/* Flush any waiters */
if (DEBUG) System.out.println("jnistress004::run(): before sync[0]");
synchronized (sync[0]) {
sync[0].notifyAll();
}
if (DEBUG) System.out.println("jnistress004::run(): after sync[0]");
for (i = 0; i < irupt.length; i++) {
try {
irupt[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress004::run(): X");
for (i = 0; i < garb.length; i++) {
try {
garb[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress004::run(): Y");
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < jniter.length; i++) {
try {
if (jniter[i].isAlive()) {
jniter[i].join();
}
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress004::run(): Z");
} catch (Throwable e) {
Debug.Fail(e);
}
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
long nCycles = 0;
JNIter004[] jniter;
static Synchronizer[] sync;
private int interval = 100;
Interrupter[] irupt;
GarbageGenerator[] garb;
private boolean done = false;
final private static boolean DEBUG = false;
}
class JNIter004 extends Thread {
// The native methods for testing JNI critical calls
public native char[] CheckSum(String str);
public native boolean CheckCompare(String name, char[] sum, int upper);
static {
System.loadLibrary("jnistress004");
}
Runtime myRT = Runtime.getRuntime();
static int Count = 0;
public JNIter004(Synchronizer[] aSync) {
sync = aSync;
}
public void run() {
try {
char[] Sum;
int iter = 0;
/* Synchronize start of work */
incCount();
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
}
}
while (!done && pass) {
try {
/* Synchronized the JNI stressing */
synchronized (sync[2]) {
incCount();
}
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter004.incInterruptCount();
}
}
}
synchronized (sync[0]) {
try {
if (Count++ < jnistress004.jniStringAllocSize) {
System.out.println("JAVA: comparing " + (getName()) + " with " + CheckSum(getName()));
if (!CheckCompare(getName(), CheckSum(getName()), jnistress004.jniStringAllocSize))
pass = true;
}
} catch (OutOfMemoryError e) {
System.out.println("Error in Java code" + e);
}
}
if (DEBUG)
System.out.println(getName() + "\t\t" + myRT.freeMemory());
synchronized (this) {
try {
wait(1L);
} catch (InterruptedException e) {
throw new InterruptedException();
}
}
} catch (Exception e) {
synchronized (sync[1]) {
JNIter004.incInterruptCount();
}
}
iter++;
iter = iter % CASECOUNT;
}
if (DEBUG) System.out.println("JNITer::run(): done=" + done);
done = true;
if (DEBUG) System.out.println("JNITer::run(): pass=" + JNIter004.pass);
if (DEBUG) System.out.println("JNIter004::run(): done");
} catch (Throwable e) {
Debug.Fail(e);
}
}
private synchronized static void incCount() {
count++;
}
public static int getCount() {
return count;
}
public synchronized static void clearCount() {
count = 0;
}
private synchronized static void incInterruptCount() {
interruptCount++;
}
public static int getInterruptCount() {
return interruptCount;
}
public synchronized static void clearInterruptCount() {
interruptCount = 0;
}
public static void halt() {
done = true;
}
public boolean finished() {
return done;
}
public static boolean passed() {
return pass;
}
public static void setpass(boolean value) {
pass = value;
}
Synchronizer[] sync;
private static int count = 0;
private static int interruptCount = 0;
private static boolean done = false;
private static boolean pass = true;
final private static int CASECOUNT = 2;
final private static boolean DEBUG = false;
}

View File

@ -0,0 +1,506 @@
/*
* 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.
*/
/*
* jnistress005 is a class that sets up classes that do the work
* for the test.
*
* The Interrupter objects send interrupts to the JNIters.
* The GarbageGenerator objects generate garbage.
*
* sync[0] synchronizes the test cycles.
* sync[1] synchronizes access to exception counters.
* sync[2] synchronizes the cycle count update. It also insures that
* the interrupts do not interfere with the cycle count updates.
* This is because cycle count updates are used to define cycles.
*/
/*
* @test
* @key stress
*
* @summary converted from VM testbase nsk/stress/jni/jnistress005.
* VM testbase keywords: [stress, quick, feature_283, nonconcurrent]
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native
* nsk.stress.jni.jnistress005
* -numTHREADer 20
* -threadInterval 200
* -numInterrupter 2
* -interruptInterval 500
* -numGarbage 80
* -garbageInterval 5
* -numIteration 260
*/
package nsk.stress.jni;
import nsk.share.Consts;
import nsk.share.Debug;
import nsk.share.test.StressOptions;
public class jnistress005 extends Thread {
/* Maximum number of iterations. Ignored if <= 0L */
static long numIteration = 0L;
/* Timeout */
static long timeOut;
/* Number of test class objects */
static int numJNIter = 1;
/* Time between JNI stressing by the threads under test */
/* (in milliseconds) */
static int jniInterval = 10000;
/* Number of interrupting threads */
static int numInterrupter = 1;
/* Time between interrupts in milliseconds */
static int interruptInterval = 100;
/* Number of garbage generating threads */
static int numGarbage = 1;
/* Time between garbage allocations in milliseconds */
static int garbageInterval = 100;
// The MAX quantity of creates exceptions
static int jniStringAllocSize = 15000;
private static StressOptions stressOptions;
public static void main(String[] argv) {
try {
int i = 0;
int nJNISync = 10;
jnistress005 dm = null;
boolean errArg = false;
stressOptions = new StressOptions(argv);
/* Process arguments */
while (!errArg && i < argv.length) {
/* Number of iterations. Ignored if <= 0. */
if (i < argv.length && argv[i].equals("-numIteration")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numIteration = Long.parseLong(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numTHREADer")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numJNIter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
if (numJNIter <= 0) errArg = true;
}
} else if (i < argv.length && argv[i].equals("-threadInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numInterrupter")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numInterrupter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-interruptInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
interruptInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numGarbage")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numGarbage = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-garbageInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
garbageInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-jniStringAllocSize")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniStringAllocSize = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].startsWith("-stress")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
++i;
}
} else System.out.println("Argument #" + i++ + " is incorrect");
}
numIteration *= stressOptions.getIterationsFactor();
numJNIter *= stressOptions.getThreadsFactor();
numInterrupter *= stressOptions.getThreadsFactor();
numGarbage *= stressOptions.getThreadsFactor();
timeOut = stressOptions.getTime() * 1000;
sync = new Synchronizer[10];
for (i = 0; i < nJNISync; i++)
sync[i] = new Synchronizer();
dm = new jnistress005(numIteration, numJNIter, jniInterval,
numInterrupter, interruptInterval, numGarbage, garbageInterval);
dm.start();
try {
dm.join(timeOut);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
if (DEBUG) System.out.println("jnistress005::main(): halt!");
if (dm.isAlive()) {
System.out.println("TIME LIMIT EXCEEDED");
dm.halt();
if (DEBUG) System.out.println("jnistress005::main(): join!");
try {
dm.join(10000L);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
} else {
System.out.println("TESTER THREAD FINISHED");
}
if (DEBUG) System.out.println("jnistress005::main(): zzzz...");
if (!JNIter005.passed())
System.exit(Consts.TEST_FAILED);
} catch (Throwable e) {
Debug.Fail(e);
}
}
jnistress005(
long iters,
int nJNI,
int jniInterval,
int nInter,
int iruptInterval,
int nGarb,
int garbInterval
) {
int i = 0;
nCycles = iters;
/* Should have at least one of nCycles>0 */
if (nCycles <= 0) nCycles = Long.MAX_VALUE;
jniter = new JNIter005[nJNI];
interval = jniInterval;
irupt = new Interrupter[nInter];
garb = new GarbageGenerator[nGarb];
for (i = 0; i < nJNI; i++)
jniter[i] = new JNIter005(sync);
for (i = 0; i < nInter; i++) {
irupt[i] = new Interrupter(jniter, sync);
irupt[i].setInterval(iruptInterval);
}
for (i = 0; i < nGarb; i++) {
garb[i] = new GarbageGenerator();
garb[i].setInterval(garbInterval);
}
}
public void run() {
try {
int i = 0;
long iCycle = 0L;
// JNIter005.clearCount();
JNIter005.clearInterruptCount();
for (i = 0; i < jniter.length; i++)
jniter[i].start();
while (JNIter005.getCount() < jniter.length) {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
// JNIter005.clearCount();
// JNIter005.clearInterruptCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < garb.length; i++)
garb[i].start();
for (i = 0; i < irupt.length; i++)
irupt[i].start();
if (DEBUG) System.out.println("Cycles=" + nCycles);
for (iCycle = 0; iCycle < nCycles && !done && JNIter005.passed(); iCycle++) {
System.out.print("Cycle: " + iCycle);
try {
sleep(interval);
} catch (InterruptedException e) {
}
synchronized (sync[1]) {
System.out.println(
" Interrupt count=" + JNIter005.getInterruptCount() +
" Native interrupt count=" + JNIter005.CountException);
}
// JNIter005.clearCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
int n = 0;
for (i = 0; i < jniter.length; i++)
if (jniter[i].finished()) n++;
if (n == jniter.length) break;
}
if (JNIter005.passed())
System.out.println("JNI TEST PASSED");
else
System.out.println("JNI TEST FAILED");
for (i = 0; i < irupt.length; i++)
irupt[i].halt();
for (i = 0; i < garb.length; i++)
garb[i].halt();
for (i = 0; i < jniter.length; i++)
jniter[i].halt();
/* Flush any waiters */
if (DEBUG) System.out.println("jnistress005::run(): before sync[0]");
synchronized (sync[0]) {
sync[0].notifyAll();
}
if (DEBUG) System.out.println("jnistress005::run(): after sync[0]");
for (i = 0; i < irupt.length; i++) {
try {
irupt[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress005::run(): X");
for (i = 0; i < garb.length; i++) {
try {
garb[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress005::run(): Y");
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < jniter.length; i++) {
try {
if (jniter[i].isAlive()) {
jniter[i].join();
}
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress005::run(): Z");
} catch (Throwable e) {
Debug.Fail(e);
}
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
long nCycles = 0;
JNIter005[] jniter;
static Synchronizer[] sync;
private int interval = 100;
Interrupter[] irupt;
GarbageGenerator[] garb;
private boolean done = false;
final private static boolean DEBUG = false;
}
class JNIter005 extends Thread {
// The native methods for testing JNI exception calls
public native void except(Throwable tobj);
// public native int count();
static {
System.loadLibrary("jnistress005");
}
Exception nobj = new Exception();
static int CountException = 0;
static int counts = 0;
public JNIter005(Synchronizer[] aSync) {
sync = aSync;
}
public void run() {
try {
char[] Sum;
int iter = 0;
/* Synchronize start of work */
incCount();
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
}
}
while (!done && pass) {
try {
/* Synchronized the JNI stressing */
synchronized (sync[2]) {
incCount();
}
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter005.incInterruptCount();
}
}
}
synchronized (sync[0]) {
if (CountException < jnistress005.jniStringAllocSize) {
try {
except(nobj);
} catch (Exception e) {
if ((CountException % 1000) == 0)
System.out.println("JAVA: " + e);
System.out.println("Here");
System.out.println("counts " + counts +
" CountException " + CountException);
++CountException;
}
} else
// if (CountException==counts) halt();
if (CountException == jnistress005.jniStringAllocSize) halt();
}
if (DEBUG)
System.out.println("We have " + activeCount() + " threads now.");
synchronized (this) {
try {
wait(1L);
} catch (InterruptedException e) {
throw new InterruptedException();
}
}
} catch (Exception e) {
synchronized (sync[1]) {
JNIter005.incInterruptCount();
}
}
iter++;
iter = iter % CASECOUNT;
}
if (DEBUG) System.out.println("JNITer::run(): done=" + done);
done = true;
if (DEBUG) System.out.println("JNITer::run(): pass=" + JNIter005.pass);
if (DEBUG) System.out.println("JNIter005::run(): done");
} catch (Throwable e) {
Debug.Fail(e);
}
}
public synchronized static void incCount() {
count++;
}
public static int getCount() {
return count;
}
public synchronized static void clearCount() {
count = 0;
}
private synchronized static void incInterruptCount() {
interruptCount++;
}
public static int getInterruptCount() {
return interruptCount;
}
public synchronized static void clearInterruptCount() {
interruptCount = 0;
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
public static boolean passed() {
return pass;
}
public static void setpass(boolean value) {
pass = value;
}
Synchronizer[] sync;
private static int count = 0;
private static int interruptCount = 0;
private boolean done = false;
private static boolean pass = true;
final private static int CASECOUNT = 2;
final private static boolean DEBUG = false;
}

View File

@ -0,0 +1,502 @@
/*
* 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.
*/
/*
* jnistress006 is a class that sets up classes that do the work
* for the test.
*
* The Interrupter objects send interrupts to the JNIters.
* The GarbageGenerator objects generate garbage.
*
* sync[0] synchronizes the test cycles.
* sync[1] synchronizes access to exception counters.
* sync[2] synchronizes the cycle count update. It also insures that
* the interrupts do not interfere with the cycle count updates.
* This is because cycle count updates are used to define cycles.
*/
/*
* @test
* @key stress
*
* @summary converted from VM testbase nsk/stress/jni/jnistress006.
* VM testbase keywords: [stress, quick, feature_283, nonconcurrent]
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native
* nsk.stress.jni.jnistress006
* -numTHREADer 20
* -threadInterval 200
* -numInterrupter 2
* -interruptInterval 500
* -numGarbage 80
* -garbageInterval 5
* -numIteration 260
*/
package nsk.stress.jni;
import nsk.share.Consts;
import nsk.share.Debug;
import nsk.share.test.StressOptions;
public class jnistress006 extends Thread {
/* Maximum number of iterations. Ignored if <= 0L */
static long numIteration = 0L;
/* Timeout */
static long timeOut;
/* Number of test class objects */
static int numJNIter = 1;
/* Time between JNI stressing by the threads under test */
/* (in milliseconds) */
static int jniInterval = 10000;
/* Number of interrupting threads */
static int numInterrupter = 1;
/* Time between interrupts in milliseconds */
static int interruptInterval = 100;
/* Number of garbage generating threads */
static int numGarbage = 1;
/* Time between garbage allocations in milliseconds */
static int garbageInterval = 100;
// The MAX quantity of creates global refs
static int jniStringAllocSize = 30000;
private static StressOptions stressOptions;
public static void main(String[] argv) {
try {
int i = 0;
int nJNISync = 10;
jnistress006 dm = null;
boolean errArg = false;
stressOptions = new StressOptions(argv);
/* Process arguments */
while (!errArg && i < argv.length) {
/* Number of iterations. Ignored if <= 0. */
if (i < argv.length && argv[i].equals("-numIteration")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numIteration = Long.parseLong(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numTHREADer")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numJNIter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
if (numJNIter <= 0) errArg = true;
}
} else if (i < argv.length && argv[i].equals("-threadInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numInterrupter")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numInterrupter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-interruptInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
interruptInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numGarbage")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numGarbage = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-garbageInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
garbageInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-jniStringAllocSize")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniStringAllocSize = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].startsWith("-stress")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
++i;
}
} else System.out.println("Argument #" + i++ + " is incorrect");
}
numIteration *= stressOptions.getIterationsFactor();
numJNIter *= stressOptions.getThreadsFactor();
numInterrupter *= stressOptions.getThreadsFactor();
numGarbage *= stressOptions.getThreadsFactor();
timeOut = stressOptions.getTime() * 1000;
sync = new Synchronizer[10];
for (i = 0; i < nJNISync; i++)
sync[i] = new Synchronizer();
dm = new jnistress006(numIteration, numJNIter, jniInterval,
numInterrupter, interruptInterval, numGarbage, garbageInterval);
dm.start();
try {
dm.join(timeOut);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
if (DEBUG) System.out.println("jnistress006::main(): halt!");
if (dm.isAlive()) {
System.out.println("TIME LIMIT EXCEEDED");
dm.halt();
if (DEBUG) System.out.println("jnistress006::main(): join!");
try {
dm.join(10000L);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
} else {
System.out.println("TESTER THREAD FINISHED");
}
if (DEBUG) System.out.println("jnistress006::main(): zzzz...");
if (!JNIter006.passed())
System.exit(Consts.TEST_FAILED);
} catch (Throwable e) {
Debug.Fail(e);
}
}
jnistress006(
long iters,
int nJNI,
int jniInterval,
int nInter,
int iruptInterval,
int nGarb,
int garbInterval
) {
int i = 0;
nCycles = iters;
/* Should have at least one of nCycles>0 */
if (nCycles <= 0) nCycles = Long.MAX_VALUE;
jniter = new JNIter006[nJNI];
interval = jniInterval;
irupt = new Interrupter[nInter];
garb = new GarbageGenerator[nGarb];
for (i = 0; i < nJNI; i++)
jniter[i] = new JNIter006(sync);
for (i = 0; i < nInter; i++) {
irupt[i] = new Interrupter(jniter, sync);
irupt[i].setInterval(iruptInterval);
}
for (i = 0; i < nGarb; i++) {
garb[i] = new GarbageGenerator();
garb[i].setInterval(garbInterval);
}
}
public void run() {
try {
int i = 0;
long iCycle = 0L;
JNIter006.clearCount();
JNIter006.clearInterruptCount();
for (i = 0; i < jniter.length; i++)
jniter[i].start();
while (JNIter006.getCount() < jniter.length) {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
JNIter006.clearCount();
// JNIter006.clearInterruptCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < garb.length; i++)
garb[i].start();
for (i = 0; i < irupt.length; i++)
irupt[i].start();
if (DEBUG) System.out.println("Cycles=" + nCycles);
for (iCycle = 0; iCycle < nCycles && !done && JNIter006.passed(); iCycle++) {
System.out.print("Cycle: " + iCycle);
try {
sleep(interval);
} catch (InterruptedException e) {
}
synchronized (sync[1]) {
System.out.println(" Interrupt count=" +
JNIter006.getInterruptCount());
}
JNIter006.clearCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
int n = 0;
for (i = 0; i < jniter.length; i++)
if (jniter[i].finished()) n++;
if (n == jniter.length) break;
}
if (JNIter006.passed())
System.out.println("JNI TEST PASSED");
else
System.out.println("JNI TEST FAILED");
for (i = 0; i < irupt.length; i++)
irupt[i].halt();
for (i = 0; i < garb.length; i++)
garb[i].halt();
for (i = 0; i < jniter.length; i++)
jniter[i].halt();
/* Flush any waiters */
if (DEBUG) System.out.println("jnistress006::run(): before sync[0]");
synchronized (sync[0]) {
sync[0].notifyAll();
}
if (DEBUG) System.out.println("jnistress006::run(): after sync[0]");
for (i = 0; i < irupt.length; i++) {
try {
irupt[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress006::run(): X");
for (i = 0; i < garb.length; i++) {
try {
garb[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress006::run(): Y");
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < jniter.length; i++) {
try {
if (jniter[i].isAlive()) {
jniter[i].join();
}
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress006::run(): Z");
} catch (Throwable e) {
Debug.Fail(e);
}
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
long nCycles = 0;
JNIter006[] jniter;
static Synchronizer[] sync;
private int interval = 100;
Interrupter[] irupt;
GarbageGenerator[] garb;
private boolean done = false;
final private static boolean DEBUG = false;
}
class JNIter006 extends Thread {
// The native methods for testing JNI exception calls
public native boolean refs(Object tobj, int jniStringAllocSize);
static {
System.loadLibrary("jnistress006");
}
Referenced tobj = new Referenced();
static int CountRefs;
public JNIter006(Synchronizer[] aSync) {
sync = aSync;
}
public void run() {
try {
int iter = 0;
/* Synchronize start of work */
incCount();
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
}
}
while (!done && pass) {
try {
/* Synchronized the JNI stressing */
synchronized (sync[2]) {
incCount();
}
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter006.incInterruptCount();
}
}
}
synchronized (sync[0]) {
try {
tobj.set_i(123456);
pass = refs(tobj, jnistress006.jniStringAllocSize);
} catch (Exception e) {
System.out.println("Error: " + e);
}
}
if (DEBUG)
System.out.println("We have " + activeCount() + " threads now.");
synchronized (this) {
try {
wait(1L);
} catch (InterruptedException e) {
throw new InterruptedException();
}
}
} catch (Exception e) {
synchronized (sync[1]) {
JNIter006.incInterruptCount();
}
}
iter++;
iter = iter % CASECOUNT;
}
if (DEBUG) System.out.println("JNITer::run(): done=" + done);
done = true;
if (DEBUG) System.out.println("JNITer::run(): pass=" + JNIter006.pass);
if (DEBUG) System.out.println("JNIter006::run(): done");
} catch (Throwable e) {
Debug.Fail(e);
}
}
private synchronized static void incCount() {
count++;
}
public static int getCount() {
return count;
}
public synchronized static void clearCount() {
count = 0;
}
private synchronized static void incInterruptCount() {
interruptCount++;
}
public static int getInterruptCount() {
return interruptCount;
}
public synchronized static void clearInterruptCount() {
interruptCount = 0;
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
public static boolean passed() {
return pass;
}
Synchronizer[] sync;
private static int count = 0;
private static int interruptCount = 0;
private static boolean done = false;
private static boolean pass = true;
final private static int CASECOUNT = 2;
final private static boolean DEBUG = false;
}
class Referenced {
private static int i;
public static void set_i(int value) {
i = value;
}
public static int get_i() {
return i;
}
}

View File

@ -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.
*/
/*
* jnistress007 is a class that sets up classes that do the work
* for the test.
*
* The Interrupter objects send interrupts to the JNIters.
* The GarbageGenerator objects generate garbage.
*
* sync[0] synchronizes the test cycles.
* sync[1] synchronizes access to exception counters.
* sync[2] synchronizes the cycle count update. It also insures that
* the interrupts do not interfere with the cycle count updates.
* This is because cycle count updates are used to define cycles.
*/
/*
* @test
* @key stress
*
* @summary converted from VM testbase nsk/stress/jni/jnistress007.
* VM testbase keywords: [stress, quick, feature_283, nonconcurrent]
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native
* nsk.stress.jni.jnistress007
* -numTHREADer 10
* -threadInterval 20
* -numInterrupter 2
* -interruptInterval 50
* -numGarbage 80
* -garbageInterval 5
* -numIteration 130
*/
package nsk.stress.jni;
import nsk.share.Consts;
import nsk.share.Debug;
import nsk.share.test.StressOptions;
public class jnistress007 extends Thread {
/* Maximum number of iterations. Ignored if <= 0L */
static long numIteration = 0L;
/* Timeout */
static long timeOut;
/* Number of test class objects */
static int numJNIter = 1;
/* Time between JNI stressing by the threads under test */
/* (in milliseconds) */
static int jniInterval = 10000;
/* Number of interrupting threads */
static int numInterrupter = 1;
/* Time between interrupts in milliseconds */
static int interruptInterval = 1000;
/* Number of garbage generating threads */
static int numGarbage = 1;
/* Time between garbage allocations in milliseconds */
static int garbageInterval = 1000;
// The MAX quantity of monitor's call
static int jniStringAllocSize = 300;
private static StressOptions stressOptions;
public static void main(String[] argv) {
try {
int i = 0;
int nJNISync = 10;
jnistress007 dm = null;
boolean errArg = false;
stressOptions = new StressOptions(argv);
/* Process arguments */
while (!errArg && i < argv.length) {
/* Number of iterations. Ignored if <= 0. */
if (i < argv.length && argv[i].equals("-numIteration")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numIteration = Long.parseLong(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numTHREADer")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numJNIter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
if (numJNIter <= 0) errArg = true;
}
} else if (i < argv.length && argv[i].equals("-threadInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numInterrupter")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numInterrupter = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-interruptInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
interruptInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-numGarbage")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
numGarbage = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-garbageInterval")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
garbageInterval = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].equals("-jniStringAllocSize")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
try {
jniStringAllocSize = Integer.parseInt(argv[i++]);
} catch (NumberFormatException e) {
errArg = true;
}
}
} else if (i < argv.length && argv[i].startsWith("-stress")) {
++i;
if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {
++i;
}
} else System.out.println("Argument #" + i++ + " is incorrect");
}
numIteration *= stressOptions.getIterationsFactor();
numJNIter *= stressOptions.getThreadsFactor();
numInterrupter *= stressOptions.getThreadsFactor();
numGarbage *= stressOptions.getThreadsFactor();
timeOut = stressOptions.getTime() * 1000;
sync = new Synchronizer[10];
for (i = 0; i < nJNISync; i++)
sync[i] = new Synchronizer();
dm = new jnistress007(numIteration, numJNIter, jniInterval,
numInterrupter, interruptInterval, numGarbage, garbageInterval);
dm.start();
try {
dm.join(timeOut);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
if (DEBUG) System.out.println("jnistress007::main(): halt!");
if (dm.isAlive()) {
System.out.println("TIME LIMIT EXCEEDED");
dm.halt();
if (DEBUG) System.out.println("jnistress007::main(): join!");
try {
dm.join(10000L);
} catch (InterruptedException e) {
System.out.println("TESTER THREAD WAS INTERRUPTED");
System.exit(Consts.TEST_FAILED);
}
} else {
System.out.println("TESTER THREAD FINISHED");
}
if (DEBUG) System.out.println("jnistress007::main(): zzzz...");
if (JNIter007.passed())
System.exit(Consts.TEST_FAILED);
} catch (Throwable e) {
Debug.Fail(e);
}
}
jnistress007(
long iters,
int nJNI,
int jniInterval,
int nInter,
int iruptInterval,
int nGarb,
int garbInterval
) {
int i = 0;
nCycles = iters;
/* Should have at least one of nCycles>0 */
if (nCycles <= 0) nCycles = Long.MAX_VALUE;
jniter = new JNIter007[nJNI];
interval = jniInterval;
irupt = new Interrupter[nInter];
garb = new GarbageGenerator[nGarb];
for (i = 0; i < nJNI; i++)
jniter[i] = new JNIter007(sync);
for (i = 0; i < nInter; i++) {
irupt[i] = new Interrupter(jniter, sync);
irupt[i].setInterval(iruptInterval);
}
for (i = 0; i < nGarb; i++) {
garb[i] = new GarbageGenerator();
garb[i].setInterval(garbInterval);
}
}
public void run() {
try {
int i = 0;
long iCycle = 0L;
JNIter007.clearCount();
JNIter007.clearInterruptCount();
for (i = 0; i < jniter.length; i++)
jniter[i].start();
while (JNIter007.getCount() < jniter.length) {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
JNIter007.clearCount();
// JNIter007.clearInterruptCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < garb.length; i++)
garb[i].start();
for (i = 0; i < irupt.length; i++)
irupt[i].start();
if (DEBUG) System.out.println("Cycles=" + nCycles);
for (iCycle = 0; iCycle < nCycles && !done && !JNIter007.passed(); iCycle++) {
System.out.print("Cycle: " + iCycle);
try {
sleep(interval);
} catch (InterruptedException e) {
}
synchronized (sync[1]) {
System.out.println("\tInterrupt count=" +
JNIter007.getInterruptCount());
}
JNIter007.clearCount();
synchronized (sync[0]) {
sync[0].notifyAll();
}
int n = 0;
for (i = 0; i < jniter.length; i++)
if (jniter[i].finished()) n++;
if (n == jniter.length) break;
}
for (i = 0; i < irupt.length; i++)
irupt[i].halt();
for (i = 0; i < garb.length; i++)
garb[i].halt();
for (i = 0; i < jniter.length; i++)
jniter[i].halt();
/* Flush any waiters */
if (DEBUG) System.out.println("jnistress007::run(): before sync[0]");
synchronized (sync[0]) {
sync[0].notifyAll();
}
if (DEBUG) System.out.println("jnistress007::run(): after sync[0]");
for (i = 0; i < irupt.length; i++) {
try {
irupt[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress007::run(): X");
for (i = 0; i < garb.length; i++) {
try {
garb[i].join();
} catch (InterruptedException e) {
}
}
if (DEBUG) System.out.println("jnistress007::run(): Y");
synchronized (sync[0]) {
sync[0].notifyAll();
}
for (i = 0; i < jniter.length; i++) {
try {
jniter[i].join();
} catch (InterruptedException e) {
}
}
if (JNIter007.passed()) {
System.out.println("JNI TEST PASSED");
} else {
System.out.println("JNI TEST FAILED");
}
if (DEBUG) System.out.println("jnistress007::run(): Z");
} catch (Throwable e) {
Debug.Fail(e);
}
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
long nCycles = 0;
JNIter007[] jniter;
static Synchronizer[] sync;
private int interval = 100;
Interrupter[] irupt;
GarbageGenerator[] garb;
private boolean done = false;
final private static boolean DEBUG = false;
}
class JNIter007 extends Thread {
// The native methods for testing JNI monitors calls
public native void incCount(String name);
static {
System.loadLibrary("jnistress007");
}
public static int nativeCount, javaCount = 0;
public JNIter007(Synchronizer[] aSync) {
sync = aSync;
}
public void run() {
try {
int iter = 0;
/* Synchronize start of work */
incCount();
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
}
}
while (!done && !pass) {
try {
/* Synchronized the JNI stressing */
synchronized (sync[2]) {
incCount();
}
synchronized (sync[0]) {
try {
sync[0].wait();
} catch (InterruptedException e) {
synchronized (sync[1]) {
JNIter007.incInterruptCount();
}
}
}
synchronized (sync[0]) {
try {
if ((javaCount < jnistress007.jniStringAllocSize) &&
(nativeCount < jnistress007.jniStringAllocSize)) {
javaCount++;
incCount(getName());
if ((javaCount % 1000) == 0)
System.out.println("Count in java " +
getName() + " " + javaCount);
} else if (javaCount == nativeCount) {
done = true;
} else {
System.out.println("Native: " + nativeCount +
"\t" + "Java: " + javaCount);
pass = true;
}
} catch (Exception e) {
System.out.println("Error: " + e);
}
}
if (DEBUG)
System.out.println("We have " + activeCount() + " threads now.");
synchronized (this) {
try {
wait(1L);
} catch (InterruptedException e) {
throw new InterruptedException();
}
}
} catch (Exception e) {
synchronized (sync[1]) {
JNIter007.incInterruptCount();
}
}
iter++;
iter = iter % CASECOUNT;
}
if (DEBUG) System.out.println("JNITer::run(): done=" + done);
done = true;
if (DEBUG) System.out.println("JNITer::run(): pass=" + JNIter007.pass);
if (DEBUG) System.out.println("JNIter::run(): done");
} catch (Throwable e) {
Debug.Fail(e);
}
}
private synchronized static void incCount() {
count++;
}
public static int getCount() {
return count;
}
public synchronized static void clearCount() {
count = 0;
}
private synchronized static void incInterruptCount() {
interruptCount++;
}
public static int getInterruptCount() {
return interruptCount;
}
public synchronized static void clearInterruptCount() {
interruptCount = 0;
}
public void halt() {
done = true;
}
public boolean finished() {
return done;
}
public static boolean passed() {
return pass;
}
Synchronizer[] sync;
private static int count = 0;
private static int interruptCount = 0;
private boolean done = false;
private static boolean pass = false;
final private static int CASECOUNT = 2;
final private static boolean DEBUG = false;
}

View File

@ -0,0 +1,239 @@
/*
* 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 <jni.h>
#include <stdio.h>
/* Changed from strings.h to string.h for Windows. */
#include <string.h>
#include <stdlib.h>
#include "jnihelper.h"
#define DIGESTLENGTH 16
typedef struct {
const char **str;
char **checkstr;
} CHAR_ARRAY;
typedef struct {
const jchar **str;
char **checkstr;
int *size;
} JCHAR_ARRAY;
JNIEXPORT jstring JNICALL
Java_nsk_stress_jni_JNIter001_jnistress (JNIEnv *env, jobject jobj, jstring jstr,
jint nstr, jint printperiod) {
int i,j;
size_t k;
static CHAR_ARRAY *element;
unsigned char digest[DIGESTLENGTH];
static int allocs=0;
static size_t strsize=0;
static unsigned int compared=1;
const char *clsName = "nsk/stress/jni/JNIter001";
const char *name="setpass";
const char *sig="(Z)V";
const char *halt="halt";
const char *haltSig="()V";
jstring tmpstr;
jclass clazz;
jmethodID methodID;
(*env)->MonitorEnter(env, jobj); CE
if (!allocs) {
element = (CHAR_ARRAY *)malloc(sizeof(CHAR_ARRAY));
element->str = (const char **)malloc(nstr*sizeof(const char *));
element->checkstr = (char **)malloc(nstr*sizeof(char *));
for (j=0;j<nstr;j++)
element->checkstr[j] = (char *)malloc(DIGESTLENGTH*sizeof(char));
}
for(j=0;j<DIGESTLENGTH;j++) {
digest[j]=0;
}
element->str[allocs] = (*env)->GetStringUTFChars(env,jstr,0); CE
if (strlen(element->str[allocs]) !=
(size_t) (*env)->GetStringUTFLength(env, jstr))
printf("Length is wrong in string No. %d\n",allocs);
else
strsize += strlen(element->str[allocs])+1;
for (k = 0; k < strlen(element->str[allocs]); k++) {
digest[k % DIGESTLENGTH] += element->str[allocs][k];
}
memcpy(element->checkstr[allocs],digest,DIGESTLENGTH);
allocs++;
if (allocs%printperiod==0) {
printf("Check string for thread %s is ", element->str[allocs-1]);
for (j=0;j<DIGESTLENGTH;j++)
printf("%02x", digest[j]);
printf("\n");
}
if (allocs==nstr) {
printf("JNI UTF8 strings memory=%zd\n", strsize);
tmpstr=(*env)->NewStringUTF(env,element->str[allocs-1]); CE
for (j=0; j<nstr; j++) {
for(i=0;i<DIGESTLENGTH;i++) {
digest[i]=0;
}
for (k=0; k < strlen(element->str[j]); k++) {
digest[k % DIGESTLENGTH] += element->str[j][k];
}
if (memcmp(digest,element->checkstr[j],DIGESTLENGTH)==0) {
(*env)->ReleaseStringUTFChars(env,jstr,element->str[j]); CE
element->str[j] = NULL;
element->checkstr[j] = NULL;
}
else {
compared=0;
printf("The element No. %d has been corrupted %s vs %s\n",j, element->str[j],element->checkstr[j]);
printf("Digest string is %s [", element->str[j]);
for (i=0;i<DIGESTLENGTH;i++)
printf("ch[%d]=%02x", i, digest[i]);
printf("Digest end\n");
}
}
allocs=0;
strsize = 0;
for (j=0;j<nstr;j++)
free(element->checkstr[j]);
free(element->checkstr);
free((void *)(element->str));
free(element);
clazz=(*env)->FindClass(env, clsName); CE
if (!compared) {
methodID=(*env)->GetStaticMethodID(env, clazz, name, sig); CE
(*env)->CallStaticVoidMethod(env, clazz, methodID, JNI_FALSE); CE
}
//methodID=(*env)->GetStaticMethodID(env, clazz, halt, haltSig); CE
//(*env)->CallStaticVoidMethod(env, clazz, methodID); CE
return(tmpstr);
}
(*env)->MonitorExit(env, jobj); CE
return ((*env)->NewStringUTF(env,element->str[allocs-1]));
}
JNIEXPORT jstring JNICALL
Java_nsk_stress_jni_JNIter001_jnistress1(JNIEnv *env, jobject jobj, jstring jstr,
jint nstr, jint printperiod) {
int i,j;
static JCHAR_ARRAY *javachars;
unsigned char digest[DIGESTLENGTH];
static int index=0;
static long len=0;
static unsigned int equal=1;
char *elem;
const char *clsName = "nsk/stress/jni/JNIter001";
const char *name="setpass";
const char *sig="(Z)V";
const char *halt="halt";
const char *haltSig="()V";
jstring tmpstr;
jclass clazz;
jmethodID methodID;
(*env)->MonitorEnter(env, jobj); CE
if (!index) {
javachars = (JCHAR_ARRAY *)malloc(sizeof(JCHAR_ARRAY));
javachars->str = (const jchar **)malloc(nstr*sizeof(const jchar *));
javachars->checkstr = (char **)malloc(nstr*sizeof(char *));
javachars->size = (int *)malloc(nstr*sizeof(int));
for (j=0;j<nstr;j++)
javachars->checkstr[j] = (char *)malloc(DIGESTLENGTH*sizeof(char));
}
for(j=0;j<DIGESTLENGTH;j++) {
digest[j]=0;
}
javachars->str[index] = (*env)->GetStringChars(env,jstr,0); CE
javachars->size[index] = (*env)->GetStringUTFLength(env, jstr); CE
len += javachars->size[index];
elem = (char*) malloc(javachars->size[index]*sizeof(char));
for (j=0; j < javachars->size[index]; j++) {
elem[j] = (char) javachars->str[index][j];
}
//memcpy(digest, elem, javachars->size[index]);
for(j=0;j<javachars->size[index]; j++) {
digest[j % DIGESTLENGTH]+=elem[j];
}
memcpy(javachars->checkstr[index++],digest,DIGESTLENGTH);
if (index%printperiod==0) {
printf("Check string sum for thread %s is ",elem);
for (j=0;j<DIGESTLENGTH;j++)
printf("%02x", digest[j]);
printf("\n");
}
free(elem);
if (index==nstr) {
printf("JNI Unicode strings memory=%ld\n",len);
tmpstr=(*env)->NewString(env,javachars->str[index-1],javachars->size[index-1]); CE
for (j=0; j<nstr; j++) {
elem = (char*) malloc(javachars->size[j]*sizeof(char));
for (i=0; i < javachars->size[j]; i++) {
elem[i] = (char) javachars->str[j][i];
}
//memcpy(digest, elem, javachars->size[j]);
for(i=0;i<DIGESTLENGTH;i++) {
digest[i]=0;
}
for(i=0;i<javachars->size[j]; i++) {
digest[i % DIGESTLENGTH]+=elem[i];
}
free(elem);
if (memcmp(digest,javachars->checkstr[j],javachars->size[j])==0) {
(*env)->ReleaseStringChars(env,jstr,javachars->str[j]); CE
javachars->str[j] = NULL;
javachars->checkstr[j] = NULL;
javachars->size[j] = 0;
}
else {
equal=0;
printf("The Unicode element No. %d has been corrupted\n",j);
for(i=0;i<DIGESTLENGTH;i++) {
printf("digest[%d]=%02x checkstr[%d]=%02x\n",i,digest[i],i,javachars->checkstr[j][i]);
}
}
}
index=0;
len = 0;
for (j=0;j<nstr;j++)
free(javachars->checkstr[j]);
free(javachars->checkstr);
free((void *)(javachars->str));
free(javachars->size);
free(javachars);
clazz=(*env)->FindClass(env, clsName); CE
if (!equal) {
methodID=(*env)->GetStaticMethodID(env, clazz, name, sig); CE
(*env)->CallStaticVoidMethod(env, clazz, methodID, JNI_FALSE); CE
}
//methodID=(*env)->GetStaticMethodID(env, clazz, halt, haltSig); CE
//(*env)->CallStaticVoidMethod(env, clazz, methodID); CE
return(tmpstr);
}
(*env)->MonitorExit(env, jobj); CE
return((*env)->NewString(env,javachars->str[index-1],javachars->size[index-1]));
}

View File

@ -0,0 +1,102 @@
/*
* 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 <jni.h>
#include <stdio.h>
#include "jnihelper.h"
jobject NewObjectWrapper(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list ap;
jobject tmp;
va_start(ap,methodID);
tmp=(*env)->NewObjectV(env, clazz, methodID, ap);
va_end(ap);
return(tmp);
}
JNIEXPORT jobjectArray JNICALL
Java_nsk_stress_jni_JNIter002_jniobjects (JNIEnv *env, jobject jobj, jstring jstr, jint intgr,
jlong lng, jcharArray jChArr, jfloat flt, jdouble dbl) {
static int classCount = 0;
jobjectArray obj;
jobject element;
jclass clazz, clazzUp;
jmethodID methodID;
const char *classname="nsk/stress/jni/objectsJNI";
const char *name="<init>";
const char *sig="(Ljava/lang/String;IJ[CFD)V";
const char *upperClassName="nsk/stress/jni/jnistress002";
const char *fieldName="jniStringAllocSize";
const char *fieldSig="I";
const char *setpass="halt";
const char *setpassSig="()V";
jvalue paramArr [6];
(*env)->MonitorEnter(env, jobj); CE
++classCount;
(*env)->MonitorExit(env, jobj); CE
paramArr[0].l=jstr;
paramArr[1].i=intgr;
paramArr[2].j=lng;
paramArr[3].l=jChArr;
paramArr[4].f=flt;
paramArr[5].d=dbl;
clazz=(*env)->FindClass(env,classname); CE
obj=(*env)->NewObjectArray(env,(jsize)3,clazz,
(*env)->AllocObject(env, clazz)); CE
if (obj==NULL) {
fprintf(stderr,"Can not construct the object Array for %s\n", classname);
return(NULL);
}
methodID=(*env)->GetMethodID(env,clazz,name,sig); CE
if (methodID==NULL) {
fprintf(stderr,"Can not get the ID of <init> for %s\n", classname);
return(NULL);
}
element=(*env)->NewObject(env,clazz,methodID,
jstr, intgr, lng, jChArr, flt, dbl); CE
(*env)->SetObjectArrayElement(env,obj,0,element); CE
element=(*env)->NewObjectA(env,clazz,methodID,paramArr); CE
(*env)->SetObjectArrayElement(env,obj,1,element); CE
element= NewObjectWrapper(env, clazz, methodID,
jstr, intgr, lng, jChArr, flt, dbl); CE
(*env)->SetObjectArrayElement(env,obj,2,element); CE
clazzUp=(*env)->FindClass(env, upperClassName); CE
if (classCount == (*env)->GetStaticIntField(env, clazzUp,
(*env)->GetStaticFieldID(env,clazzUp,fieldName,fieldSig))) {
classname="nsk/stress/jni/JNIter002";
clazz=(*env)->FindClass(env, classname); CE
methodID=(*env)->GetStaticMethodID(env,clazz, setpass, setpassSig); CE
(*env)->CallStaticVoidMethod(env, clazz, methodID); CE
}
CE
return obj;
}

View File

@ -0,0 +1,260 @@
/*
* 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 <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include "jnihelper.h"
#define BOOL 0
#define BYTE 1
#define CHAR 2
#define SHORT 3
#define INT 4
#define LONG 5
#define FLOAT 6
#define DOUBLE 7
JNIEXPORT jobjectArray JNICALL
Java_nsk_stress_jni_JNIter003_jniInitArrays (JNIEnv *env, jobject jobj, jint size) {
jobject *arrayArray;
jboolean *boolBuf;
jbyte *byteBuf;
jchar *charBuf;
jshort *shortBuf;
jint *intBuf;
jlong *longBuf;
jfloat *floatBuf;
jdouble *doubleBuf;
jobjectArray objectsArray;
int i;
int SIZE=size;
const char *classname="java/lang/Object";
jclass clazz = (*env)->FindClass(env,classname); CE
objectsArray = (*env)->NewObjectArray(env,8,clazz,(*env)->AllocObject(env,clazz));
arrayArray=(jobject *)malloc(8*sizeof(jobject)); CE
arrayArray[BOOL]=(*env)->NewBooleanArray(env,SIZE); CE
arrayArray[BYTE]=(*env)->NewByteArray(env, SIZE); CE
arrayArray[CHAR]=(*env)->NewCharArray(env, SIZE); CE
arrayArray[SHORT]=(*env)->NewShortArray(env, SIZE); CE
arrayArray[INT]=(*env)->NewIntArray(env, SIZE); CE
arrayArray[LONG]=(*env)->NewLongArray(env, SIZE); CE
arrayArray[FLOAT]=(*env)->NewFloatArray(env, SIZE); CE
arrayArray[DOUBLE]=(*env)->NewDoubleArray(env, SIZE); CE
for(i=0;i<8;i++)
{(*env)->SetObjectArrayElement(env,objectsArray,i,arrayArray[i]); CE }
boolBuf=(jboolean *)malloc(SIZE*sizeof(jboolean));
byteBuf=(jbyte *)malloc(SIZE*sizeof(jbyte));
charBuf=(jchar *)malloc(SIZE*sizeof(jchar));
shortBuf=(jshort *)malloc(SIZE*sizeof(jshort));
intBuf=(jint *)malloc(SIZE*sizeof(jint));
longBuf=(jlong *)malloc(SIZE*sizeof(jlong));
floatBuf=(jfloat *)malloc(SIZE*sizeof(jfloat));
doubleBuf=(jdouble *)malloc(SIZE*sizeof(jdouble));
for (i=0;i<SIZE;i++) {
if (i%2==0) boolBuf[i]=JNI_TRUE;
else boolBuf[i]=JNI_FALSE;
/*
byteBuf[i]=(jbyte)random();
charBuf[i]=(jchar)random();
shortBuf[i]=(jshort)random();
intBuf[i]=(jint)random();
longBuf[i]=(jlong)random();
floatBuf[i]=(jfloat)((random()));
doubleBuf[i]=(jdouble)((random()));
*/
byteBuf[i]=(jbyte)109;
charBuf[i]=(jchar)214;
shortBuf[i]=(jshort)9223;
intBuf[i]=(jint)872634;
longBuf[i]=(jlong)276458276;
floatBuf[i]=(jfloat)235.4576284;
doubleBuf[i]=(jdouble)98275.716253567;
}
(*env)->SetBooleanArrayRegion(env,arrayArray[BOOL],0,i,boolBuf); CE
(*env)->SetByteArrayRegion(env,arrayArray[BYTE],0,i,byteBuf); CE
(*env)->SetCharArrayRegion(env,arrayArray[CHAR],0,i,charBuf); CE
(*env)->SetShortArrayRegion(env,arrayArray[SHORT],0,i,shortBuf); CE
(*env)->SetIntArrayRegion(env,arrayArray[INT],0,i,intBuf); CE
(*env)->SetLongArrayRegion(env,arrayArray[LONG],0,i,longBuf); CE
(*env)->SetFloatArrayRegion(env,arrayArray[FLOAT],0,i,floatBuf); CE
(*env)->SetDoubleArrayRegion(env,arrayArray[DOUBLE],0,i,doubleBuf); CE
free(doubleBuf);
free(floatBuf);
free(longBuf);
free(intBuf);
free(shortBuf);
free(byteBuf);
free(charBuf);
free(boolBuf);
free(arrayArray);
return objectsArray;
}
JNIEXPORT jboolean JNICALL
Java_nsk_stress_jni_JNIter003_jniBodyChangeArray (JNIEnv *env, jobject jobj,
jobjectArray orig, jobjectArray clone, jint limit) {
#define SWAP(param1, param2) tmparr=param2; param2=param1; param1=tmparr;
#define SIZE(type) (*env)->GetArrayLength(env,arrayClone[type])
static volatile long count=0;
jobject *arrayOrig, *arrayClone;
jboolean *boolOrig, *boolClone;
jbyte *byteOrig, *byteClone;
jchar *charOrig, *charClone;
jshort *shortOrig, *shortClone;
jint *intOrig, *intClone;
jlong *longOrig, *longClone;
jfloat *floatOrig, *floatClone;
jdouble *doubleOrig, *doubleClone;
int i;
if ((orig==NULL) || (clone==NULL)) {
fprintf(stderr,"JNI received a NULL array from Java\n");
return JNI_FALSE;
}
if (count == limit) {
jclass clazz;
const char *classname = "nsk/stress/jni/JNIter003";
const char *setdone = "halt";
const char *setdonesig = "()V";
jmethodID jmethod;
fprintf(stderr, "Count and limit are: %ld\t%d cons.\n", count, limit);
clazz=(*env)->FindClass(env, classname); CE
jmethod=(*env)->GetMethodID(env, clazz, setdone, setdonesig); CE
(*env)->CallVoidMethod(env, jobj, jmethod); CE
return JNI_TRUE;
}
(*env)->MonitorEnter(env, jobj); CE
++count;
(*env)->MonitorExit(env, jobj); CE
arrayOrig=(jobject *)malloc(8*sizeof(jobject));
arrayClone=(jobject *)malloc(8*sizeof(jobject));
for(i=0;i<8;i++) {
arrayOrig[i]=(*env)->GetObjectArrayElement(env,orig,i); CE
arrayClone[i]=(*env)->GetObjectArrayElement(env,clone,i); CE
}
/* Take the elements from Java arrays into native buffers */
/* Use Get<Type>ArrayElements */
boolOrig = (*env)->GetBooleanArrayElements(env,arrayOrig[BOOL],0); CE
byteOrig = (*env)->GetByteArrayElements(env,arrayOrig[BYTE],0); CE
charOrig = (*env)->GetCharArrayElements(env,arrayOrig[CHAR],0); CE
shortOrig = (*env)->GetShortArrayElements(env,arrayOrig[SHORT],0); CE
intOrig = (*env)->GetIntArrayElements(env,arrayOrig[INT],0); CE
longOrig = (*env)->GetLongArrayElements(env,arrayOrig[LONG],0); CE
floatOrig = (*env)->GetFloatArrayElements(env,arrayOrig[FLOAT],0); CE
doubleOrig = (*env)->GetDoubleArrayElements(env,arrayOrig[DOUBLE],0); CE
/* Alloc some memory for cloned arrays buffers */
boolClone=(jboolean *)malloc(SIZE(BOOL)*sizeof(jboolean));
byteClone=(jbyte *)malloc(SIZE(BYTE)*sizeof(jbyte));
charClone=(jchar *)malloc(SIZE(CHAR)*sizeof(jchar));
shortClone=(jshort *)malloc(SIZE(SHORT)*sizeof(jshort));
intClone=(jint *)malloc(SIZE(INT)*sizeof(jint));
longClone=(jlong *)malloc(SIZE(LONG)*sizeof(jlong));
floatClone=(jfloat *)malloc(SIZE(FLOAT)*sizeof(jfloat));
doubleClone=(jdouble *)malloc(SIZE(DOUBLE)*sizeof(jdouble));
/* Take the elements from cloned Java arrays into native buffers */
/* Use Get<Type>ArrayRegion */
(*env)->GetBooleanArrayRegion(env,arrayClone[BOOL],0,SIZE(BOOL),boolClone); CE
(*env)->GetByteArrayRegion(env,arrayClone[BYTE],0,SIZE(BYTE),byteClone); CE
(*env)->GetCharArrayRegion(env,arrayClone[CHAR],0,SIZE(CHAR),charClone); CE
(*env)->GetShortArrayRegion(env,arrayClone[SHORT],0,SIZE(SHORT),shortClone); CE
(*env)->GetIntArrayRegion(env,arrayClone[INT],0,SIZE(INT),intClone); CE
(*env)->GetLongArrayRegion(env,arrayClone[LONG],0,SIZE(LONG),longClone); CE
(*env)->GetFloatArrayRegion(env,arrayClone[FLOAT],0,SIZE(FLOAT),floatClone); CE
(*env)->GetDoubleArrayRegion(env,arrayClone[DOUBLE],0,SIZE(DOUBLE),doubleClone); CE
/* In this code section I should make some changes for elements into both */
/* (original and cloned) arrays and than copied new values back to Java */
/*
Can't change the pointer into the Java structure. It's illegal JNI.
SWAP(boolOrig,boolClone)
SWAP(byteOrig,byteClone)
SWAP(charOrig,charClone)
SWAP(shortOrig,shortClone)
SWAP(intOrig,intClone)
SWAP(longOrig,longClone)
SWAP(floatOrig,floatClone)
SWAP(doubleOrig,doubleClone)
*/
/* Coping new values of elements back to Java and releasing native buffers */
/* Use Set<Type>ArrayRegion */
/*
Use Orig pointers to get the original effect of the test.
(*env)->SetBooleanArrayRegion(env,arrayClone[BOOL],0,SIZE(BOOL),boolClone);
(*env)->SetByteArrayRegion(env,arrayClone[BYTE],0,SIZE(BYTE),byteClone);
(*env)->SetCharArrayRegion(env,arrayClone[CHAR],0,SIZE(CHAR),charClone);
(*env)->SetShortArrayRegion(env,arrayClone[SHORT],0,SIZE(SHORT),shortClone);
(*env)->SetIntArrayRegion(env,arrayClone[INT],0,SIZE(INT),intClone);
(*env)->SetLongArrayRegion(env,arrayClone[LONG],0,SIZE(LONG),longClone);
(*env)->SetFloatArrayRegion(env,arrayClone[FLOAT],0,SIZE(FLOAT),floatClone);
(*env)->SetDoubleArrayRegion(env,arrayClone[DOUBLE],0,SIZE(DOUBLE),doubleClone);
*/
(*env)->SetBooleanArrayRegion(env,arrayClone[BOOL],0,SIZE(BOOL),boolOrig); CE
(*env)->SetByteArrayRegion(env,arrayClone[BYTE],0,SIZE(BYTE),byteOrig); CE
(*env)->SetCharArrayRegion(env,arrayClone[CHAR],0,SIZE(CHAR),charOrig); CE
(*env)->SetShortArrayRegion(env,arrayClone[SHORT],0,SIZE(SHORT),shortOrig); CE
(*env)->SetIntArrayRegion(env,arrayClone[INT],0,SIZE(INT),intOrig); CE
(*env)->SetLongArrayRegion(env,arrayClone[LONG],0,SIZE(LONG),longOrig); CE
(*env)->SetFloatArrayRegion(env,arrayClone[FLOAT],0,SIZE(FLOAT),floatOrig); CE
(*env)->SetDoubleArrayRegion(env,arrayClone[DOUBLE],0,SIZE(DOUBLE),doubleOrig); CE
/* Use Release<Type>ArrayElements */
(*env)->ReleaseDoubleArrayElements(env,arrayOrig[DOUBLE],doubleOrig,0); CE
(*env)->ReleaseFloatArrayElements(env,arrayOrig[FLOAT],floatOrig,0); CE
(*env)->ReleaseLongArrayElements(env,arrayOrig[LONG],longOrig,0); CE
(*env)->ReleaseIntArrayElements(env,arrayOrig[INT],intOrig,0); CE
(*env)->ReleaseShortArrayElements(env,arrayOrig[SHORT],shortOrig,0); CE
(*env)->ReleaseCharArrayElements(env,arrayOrig[CHAR],charOrig,0); CE
(*env)->ReleaseByteArrayElements(env,arrayOrig[BYTE],byteOrig,0); CE
(*env)->ReleaseBooleanArrayElements(env,arrayOrig[BOOL],boolOrig,0); CE
free(arrayOrig);
free(doubleClone);
free(floatClone);
free(longClone);
free(intClone);
free(shortClone);
free(byteClone);
free(charClone);
free(boolClone);
free(arrayClone);
return JNI_TRUE;
}

View File

@ -0,0 +1,168 @@
/*
* 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 <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jnihelper.h"
#define DIGESTLENGTH 16
JNIEXPORT jcharArray JNICALL
Java_nsk_stress_jni_JNIter004_CheckSum (JNIEnv *env, jobject jobj, jstring jstr) {
unsigned char digest[DIGESTLENGTH];
jchar *tmp;
static jint upper = 0;
jcharArray jArr;
int i;
const jchar *critstr;
char *str;
jint len=(*env)->GetStringUTFLength(env,jstr); CE
for(i=0;i<DIGESTLENGTH;i++) {
digest[i]=0;
}
str=(char *)malloc(len*sizeof(char));
/* const char *threadName=(*env)->GetStringUTFChars(env, jstr, 0); */
(*env)->MonitorEnter(env, jobj); CE
if (upper==0) tmp=(jchar *)malloc(DIGESTLENGTH*sizeof(char));
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
critstr=(*env)->GetStringCritical(env, jstr, 0); CE
for(i=0;i<len;i++)
str[i] = (char) critstr[i];
(*env)->ReleaseStringCritical(env,jstr,critstr); CE
for(i=0;i<len;i++) {
digest[i % DIGESTLENGTH]+=str[i];
}
free(str);
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
memcpy(tmp,digest,DIGESTLENGTH);
jArr=(*env)->NewCharArray(env,DIGESTLENGTH/sizeof(jchar)); CE
len=(*env)->GetArrayLength(env,jArr); CE
(*env)->SetCharArrayRegion(env,jArr,0,len,tmp); CE
/* ++upper; */
(*env)->MonitorExit(env, jobj); CE
return jArr;
}
JNIEXPORT jboolean JNICALL
Java_nsk_stress_jni_JNIter004_CheckCompare (JNIEnv *env, jobject jobj, jstring jstr,
jcharArray cArr, jint limit) {
unsigned char digest[DIGESTLENGTH];
jchar *tmp;
/* jcharArray jArr; */
const jchar *critstr;
jint strlen;
char *str;
jboolean ret=JNI_TRUE;
int i;
static jint upper = 0;
jint len;
jchar *ch;
for(i=0;i<DIGESTLENGTH;i++) {
digest[i]=0;
}
strlen = (*env)->GetStringUTFLength(env,jstr); CE
str = (char *)malloc(strlen*sizeof(char));
len =(*env)->GetArrayLength(env,cArr); CE
(*env)->MonitorEnter(env, jobj); CE
if (upper>limit) {
(*env)->MonitorExit(env, jobj); CE
return JNI_FALSE;
}
tmp=(jchar *)malloc(DIGESTLENGTH*sizeof(char));
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
critstr=(*env)->GetStringCritical(env, jstr, 0); CE
for(i=0;i<strlen;i++)
str[i] = (char) critstr[i];
(*env)->ReleaseStringCritical(env,jstr,critstr); CE
for(i=0;i<strlen; i++) {
digest[i % DIGESTLENGTH]+=str[i % DIGESTLENGTH];
}
free(str);
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
memcpy(tmp,digest,DIGESTLENGTH);
/* jArr=(*env)->NewCharArray(env,DIGESTLENGTH/sizeof(jchar)); */
/* len=(*env)->GetArrayLength(env,jArr); */
/* (*env)->SetCharArrayRegion(env,jArr,0,len,tmp); */
/* ++upper; */
/* (*env)->MonitorExit(env, jobj); */
/* Compare */
/* (*env)->MonitorEnter(env, jobj); */
ch=(jchar *)(*env)->GetPrimitiveArrayCritical(env,cArr,0); CE
printf("Comparing: ");
for(i=0;i<len;i++)
if(ch[i]!=tmp[i]) {
printf("Error in %d\n",i);
printf("ch[%d]=%02x tmp[%d]=%02x\n",i,ch[i],i,tmp[i]);
ret=JNI_FALSE;
}
else {
printf("ch[%d]=%02x tmp[%d]=%02x\n",i,ch[i],i,tmp[i]);
}
printf("\n");
(*env)->ReleasePrimitiveArrayCritical(env,cArr,ch,0); CE
++upper;
if (!(upper % 500))
fprintf(stderr,"There are %d elements now.\n", upper);
if (upper==limit) {
jclass clazz;
jmethodID methodID;
char *name="halt";
char *sig="()V";
clazz=(*env)->GetObjectClass(env, jobj); CE
methodID=(*env)->GetStaticMethodID(env, clazz, name, sig); CE
(*env)->CallStaticVoidMethod(env, clazz, methodID); CE
free(tmp);
ret=JNI_TRUE;
}
(*env)->MonitorExit(env, jobj); CE
return ret;
}

View File

@ -0,0 +1,111 @@
/*
* 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 <jni.h>
#include <stdio.h>
#include <stdlib.h>
#define CHECK_EXCEPTION { if ((*env)->ExceptionOccurred(env)) { fprintf(stderr, "Unexpected exception:\n"); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); exit(97); } }
JNIEXPORT void JNICALL
Java_nsk_stress_jni_JNIter005_except (JNIEnv *env, jobject jobj, jthrowable tobj) {
jclass clazz;
static int Exceptcalls=0;
const char *name;
const char *mess;
jmethodID jmethod;
const char *iter = "nsk/stress/jni/JNIter005";
// const char *inc = "nsk/stress/jni/jnistress005/incCount";
const char *incSig = "()V";
const char *fldName = "counts";
const char *fldSig = "I";
/* incClazz = (*env)->FindClass(env, iter); */
/* CHECK_EXCEPTION */
/* jmethod=(*env)->GetStaticMethodID(env, incClazz, inc, incSig); */
/* CHECK_EXCEPTION */
/* (*env)->CallStaticVoidMethod(env, incClazz, jmethod); */
/* CHECK_EXCEPTION */
/* jfld = (*env)->GetFieldID(env, incClazz, fldName, fldSig); */
/* printf("JNI: Count is %d\n", (*env)->GetIntField(env, jobj, jfld)); */
/* CHECK_EXCEPTION */
(*env)->MonitorEnter(env, jobj);
CHECK_EXCEPTION
if (!(*env)->Throw(env, tobj)) {
if((*env)->ExceptionOccurred(env))
if (Exceptcalls%1000==0)
fprintf(stderr, "NATIVE: Throw has been catched in native\n");
(*env)->ExceptionClear(env);
++Exceptcalls;
} else fprintf(stderr, "Throw failed\n");
(*env)->MonitorExit(env, jobj);
CHECK_EXCEPTION
switch (Exceptcalls%23) {
case 0: name="java/lang/ArithmeticException"; break;
case 1: name="java/lang/ArrayIndexOutOfBoundsException"; break;
case 2: name="java/lang/ArrayStoreException"; break;
case 3: name="java/lang/ClassCastException"; break;
case 4: name="java/lang/ClassNotFoundException"; break;
case 5: name="java/lang/CloneNotSupportedException"; break;
case 6: name="java/lang/IllegalAccessException"; break;
case 7: name="java/lang/IllegalArgumentException"; break;
case 8: name="java/lang/IllegalMonitorStateException"; break;
case 9: name="java/lang/IllegalStateException"; break;
case 10: name="java/lang/IllegalThreadStateException"; break;
case 11: name="java/lang/IndexOutOfBoundsException"; break;
case 12: name="java/lang/InstantiationException"; break;
case 13: name="java/lang/InterruptedException"; break;
case 14: name="java/lang/NegativeArraySizeException"; break;
case 15: name="java/lang/NoSuchFieldException"; break;
case 16: name="java/lang/NoSuchMethodException"; break;
case 17: name="java/lang/NullPointerException"; break;
case 18: name="java/lang/NumberFormatException"; break;
case 19: name="java/lang/RuntimeException"; break;
case 20: name="java/lang/SecurityException"; break;
case 21: name="java/lang/StringIndexOutOfBoundsException"; break;
case 22: name="java/lang/UnsupportedOperationException"; break;
default: name="java/lang/Exception";
}
mess=name;
CHECK_EXCEPTION
clazz = (*env)->FindClass(env, name);
CHECK_EXCEPTION
if ((*env)->ThrowNew(env, clazz, mess)) {
const char *pass = "setpass";
const char *passSig = "(Z)V";
jclass incClazz;
fprintf(stderr, "ThrowNew failed\n");
CHECK_EXCEPTION;
incClazz = (*env)->FindClass(env, iter);
CHECK_EXCEPTION;
jmethod=(*env)->GetStaticMethodID(env, incClazz, pass, passSig);
CHECK_EXCEPTION
(*env)->CallStaticVoidMethod(env, incClazz, jmethod, JNI_FALSE);
CHECK_EXCEPTION
}
/* printf("JNI: count %d\n", Exceptcalls); */
}

View File

@ -0,0 +1,83 @@
/*
* 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 <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include "jnihelper.h"
JNIEXPORT jboolean JNICALL
Java_nsk_stress_jni_JNIter006_refs (JNIEnv *env, jobject jobj, jobject tobj, jint LIMIT) {
static jobject *globRefsArray = 0;
static int upper = 0;
jclass clazz;
jmethodID jmethod;
jboolean res=JNI_FALSE;
const char *classname = "nsk/stress/jni/JNIter006";
const char *getmethodname="get_i";
const char *setmethodname="set_i";
const char *getsig="()I";
const char *setsig="(I)V";
const char *setdone = "halt";
const char *setdonesig = "()V";
int i = 0;
if (upper >= LIMIT) return JNI_TRUE;
if (upper==0)
globRefsArray=(jobject*)(malloc(LIMIT*sizeof(jobject)));
globRefsArray[upper]=(*env)->NewGlobalRef(env, tobj); CE
if ((*env)->IsSameObject(env, tobj, globRefsArray[upper])) {
(*env)->DeleteLocalRef(env, tobj); CE
clazz=(*env)->GetObjectClass(env, globRefsArray[upper]); CE
}
else {
fprintf(stderr,"Objects are different\n");
(*env)->MonitorExit(env, jobj); CE
return res;
}
jmethod=(*env)->GetStaticMethodID(env, clazz, setmethodname, setsig); CE
(*env)->CallStaticVoidMethod(env, clazz, jmethod, (jint)upper); CE
(*env)->MonitorEnter(env, jobj); CE
++upper;
res=JNI_TRUE;
(*env)->MonitorExit(env, jobj); CE
/* If upper == LIMIT than flush ref's array and set */
/* 'done' flag in JNIter006 class to JNI_TRUE */
if (upper == LIMIT) {
fprintf(stderr,"\n\tTotal memory allocated: %zd bytes\n",
LIMIT*sizeof(jobject));
clazz=(*env)->FindClass(env, classname); CE
jmethod=(*env)->GetMethodID(env, clazz, setdone, setdonesig); CE
(*env)->CallVoidMethod(env, jobj, jmethod); CE
for (i=0;i<LIMIT;i++) {
(*env)->DeleteGlobalRef(env, globRefsArray[i]); CE
}
free(globRefsArray);
}
return res;
}

View File

@ -0,0 +1,44 @@
/*
* 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 <jni.h>
#include <stdio.h>
#include "jnihelper.h"
JNIEXPORT void JNICALL
Java_nsk_stress_jni_JNIter007_incCount (JNIEnv *env, jobject jobj, jstring name) {
jclass clazz;
jfieldID fld;
jint value;
const char *str = (*env)->GetStringUTFChars(env, name, 0); CE
if ((*env)->MonitorEnter(env, jobj))
printf("Error in monitor lock\n");
clazz = (*env)->GetObjectClass(env, jobj); CE
fld = (*env)->GetStaticFieldID(env, clazz, "nativeCount", "I"); CE
value = (*env)->GetStaticIntField(env, clazz, fld); CE
(*env)->SetStaticIntField(env, clazz, fld, (jint)(++value)); CE
(*env)->MonitorExit(env, jobj); CE
if (value%1000 == 0 )
printf("in %s Count after %u\n", str, value);
}

View File

@ -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=.

View File

@ -0,0 +1,544 @@
/*
* 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/network001.
* VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]
* VM testbase readme:
* DESCRIPTION
* This test transfers huge amount of data between server and client
* TCP/IP sockets, and checks if those data are transfered correctly.
* Both sockets are attached to local host name, or to the loopback
* "localhost" (having IP address 127.0.0.1).
* 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.
* COMMENTS
* Note, that HotSpot 1.3beta-H fails to start this test due to the bug:
* #4245704 (P1/S1) Fails to launch with: jre/bin/net.dll ...
*
* @run main/othervm nsk.stress.network.network001
*/
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 server and client
* TCP/IP sockets, and checks if those data are transfered correctly.
* Both sockets are attached to local host name, or to the loopback
* ``localhost'' (having IP address 127.0.0.1).
* <p>
* <p>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.
* <p>
* <p>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 <code>System.out</code>.
*/
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 <code>address</code>
* 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 <code>address</code>
* and <code>port</code>.
*/
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 ``<tt>null</tt>'' 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 <code>parcel[]</code> array using the given
* <code>random</code> numbers generator. Client and Server
* threads should use identical <code>random</code> 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 <code>size</code> bytes from the <code>istream</code>
* if possible, or throw <code>TestFailure</code> if unexpected end of
* <code>istream</code> 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 <code>istream</code> 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 <code>this</code> 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 <code>this</code> and the
* <code>other</code> 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 <code>purpose</code> 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.
* <p>
* <p>Command-line parameters provided with <code>args[]</code> may
* prompt the local host IP address or domain name. Execute:
* <br>&nbsp;&nbsp;
* <code>java network001 [<i>IP-address</i> | <i>host_name</i> |
* localhost ]</code>
* <br>where parameters are:
* <br>&nbsp;&nbsp;
* <code><i>IP-address</i></code> - local hots's address, or 127.0.0.1
* <br>&nbsp;&nbsp;
* <code><i>host_name</i></code> - local host's domain name, or the
* keyword ``<code>localhost</code>''
* <br>&nbsp;&nbsp;
* <code>localhost</code> - placeholder for the IP-address 127.0.0.1
* <br>By default, the test uses the Internet address available via
* the method <code>InetAddress.getLocalHost()</code>
*/
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 <code>run(args[],out)</code> 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.
}
}

View File

@ -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 ``<code>localhost</code>''
* (having IP address <code>127.0.0.1</code>).
* <p>
* <p>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.
* <p>
* <p>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 <code>run(args[],out)</code> actually
* performing the test. After <code>run(args[],out)</code> 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 <code>network002</code> instance reporting to the given
* <code>out</code> stream, and invoke the method <code>run(args)</code>
* 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 <code>args[]</code> 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.
* <p>
* <p>There should be 1 or 2 command-line parameters:
* <br>&nbsp;&nbsp;
* <code>java network002 <i>java_command</i> <i>waittime</i>
* [<i>IP-address</i> | <i>host_name</i> | localhost ]</code>
* <br>where parameters are:
* <br>&nbsp;&nbsp;
* <code><i>java_command</i></code> - how to start java,
* e.g.: ``<code>c:\jdk1.3\bin\java -classic</code>''
* <br>&nbsp;&nbsp;
* <code>waittime</code> - timeout for TCP/IP sockets in minutes
* <br>&nbsp;&nbsp;
* <code><i>IP-address</i></code> - local hots's address, or 127.0.0.1
* <br>&nbsp;&nbsp;
* <code><i>host_name</i></code> - local host's domain name, or the
* keyword ``<code>localhost</code>''
* <br>&nbsp;&nbsp;
* <code>localhost</code> - placeholder for the IP-address 127.0.0.1
* <p>
* <p>Usually, <code><i>java_command</i></code> should point to the same
* Java machine just executing this test. However, every compatible Java 2
* implementation is appropriate.
* <p>
* <p>If optional parameter is ommited, the test invokes the method
* <code>InetAddress.getLocalHost()</code> 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 <code>out</code> 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 ``<code><i>x.y.u.z</i></code>'',
* or ``<code>127.0.0.1</code>'' 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 <code>address</code>
* 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 <code>null</code> 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:
* <br>&nbsp;&nbsp;
* <code>java network002$Client <i>IP-address</i> <i>port</i></code>
* <br>where:
* <br>&nbsp;&nbsp;
* <code><i>IP-address</i></code> - local host's address,
* or <code>127.0.0.1</code>
* <br>&nbsp;&nbsp;
* <code><i>port</i></code> - 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 <code>out</code> and <code>err</code>
* streams of client VM.
*/
private static class IORedirector extends Thread {
/**
* Source stream.
*/
InputStream in;
/**
* Destination stream.
*/
OutputStream out;
/**
* Redirect <code>in</code> to <code>out</code>.
*/
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 <code>null</code>, 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
* <code>int</code> number equal to size of the parcel minus 1. I.e.: if
* number of data bytes in the parcel's contents is <code>N</code>, then
* the first 4 bytes encode the number <code>N-1</code>. 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 ``<tt>null</tt>'' 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 <code>parcel[]</code> array using the given
* <code>random</code> numbers generator. Client and Server
* threads should use identical <code>random</code> 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 <code>size</code> bytes from the <code>istream</code>
* if possible, or throw <code>TestFailure</code> if unexpected end of
* <code>istream</code> 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 <code>istream</code> 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 <code>this</code> 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 <code>this</code> and the
* <code>other</code> 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 <code>purpose</code> of the test failure.
*/
public TestFailure(String purpose) {
super(purpose);
}
}
}

View File

@ -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).
* <p>
* <p>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.
* <p>
* <p>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 <code>System.out</code>.
*/
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 <code>MAX_CONNECTIONS</code> 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 <code>address</code>
* 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 <code>DATA_PARCELS</code> 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 <code>address</code>
* and <code>port</code>.
*/
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 <code>DATA_PARCELS</code> 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 ``<tt>null</tt>'' 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 <code>parcel[]</code> array using the given
* <code>random</code> numbers generator. Client and Server
* threads should use identical <code>random</code> 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 <code>size</code> bytes from the <code>istream</code>
* if possible, or throw <code>TestFailure</code> if unexpected end of
* <code>istream</code> 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 <code>istream</code> 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 <code>this</code> 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 <code>this</code> and the
* <code>other</code> 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 <code>purpose</code> 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.
* <p>
* <p>Command-line parameters provided with <code>args[]</code> may
* prompt the local host IP address or domain name. Execute:
* <br>&nbsp;&nbsp;
* <code>java network003 [<i>IP-address</i> | <i>host_name</i> |
* localhost ]</code>
* <br>where parameters are:
* <br>&nbsp;&nbsp;
* <code><i>IP-address</i></code> - local hots's address, or 127.0.0.1
* <br>&nbsp;&nbsp;
* <code><i>host_name</i></code> - local host's domain name, or the
* keyword ``<code>localhost</code>''
* <br>&nbsp;&nbsp;
* <code>localhost</code> - placeholder for the IP-address 127.0.0.1
* <br>By default, the test uses the Internet address available via
* the method <code>InetAddress.getLocalHost()</code>
*/
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 <code>run(args[],out)</code> 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.
}
}

View File

@ -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 ``<code>localhost</code>''
* (having IP address <code>127.0.0.1</code>).
* <p>
* <p>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.
* <p>
* <p>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 <code>MAX_CONNECTIONS</code> 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 <code>run(args[],out)</code> actually
* performing the test. After <code>run(args[],out)</code> 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 <code>args[]</code> 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.
* <p>
* <p>There should be 1 or 2 command-line parameters:
* <br>&nbsp;&nbsp;
* <code>java network004 <i>java_command</i>
* [<i>IP-address</i> | <i>host_name</i> | localhost ]</code>
* <br>where parameters are:
* <br>&nbsp;&nbsp;
* <code><i>java_command</i></code> - how to start java,
* e.g.: ``<code>c:\jdk1.3\bin\java -classic</code>''
* <br>&nbsp;&nbsp;
* <code>waittime</code> - timeout for TCP/IP sockets in minutes
* <br>&nbsp;&nbsp;
* <code><i>IP-address</i></code> - local hots's address, or 127.0.0.1
* <br>&nbsp;&nbsp;
* <code><i>host_name</i></code> - local host's domain name, or the
* keyword ``<code>localhost</code>''
* <br>&nbsp;&nbsp;
* <code>localhost</code> - placeholder for the IP-address 127.0.0.1
* <p>
* <p>Usually, <code><i>java_command</i></code> should point to the same
* Java machine just executing this test. However, every compatible Java 2
* implementation is appropriate.
* <p>
* <p>If optional parameter is ommited, the test invokes the method
* <code>InetAddress.getLocalHost()</code> 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 ``<code><i>x.y.u.z</i></code>'',
* or ``<code>127.0.0.1</code>'' 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 <code>address</code>
* 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 <code>null</code> 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 <code>address</code>
* and <code>port</code>.
*/
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 <code>DATA_PARCELS</code> 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 <code>stdin</code>.
* 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:
* <br>&nbsp;&nbsp; actual_number_of_sockets
* <br>&nbsp;&nbsp; address_1 port_1
* <br>&nbsp;&nbsp; address_2 port_2
* <br>&nbsp;&nbsp; . . .
* <br>&nbsp;&nbsp; address_N port_N
* <br>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 <code>out</code> and <code>err</code>
* streams of client VM.
*/
private static class IORedirector extends Thread {
/**
* Source stream.
*/
InputStream in;
/**
* Destination stream.
*/
OutputStream out;
/**
* Redirect <code>in</code> to <code>out</code>.
*/
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 <code>null</code>, 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
* <code>int</code> number equal to size of the parcel minus 1. I.e.: if
* number of data bytes in the parcel's contents is <code>N</code>, then
* the first 4 bytes encode the number <code>N-1</code>. 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 ``<tt>null</tt>'' 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 <code>parcel[]</code> array using the given
* <code>random</code> numbers generator. Client and Server
* threads should use identical <code>random</code> 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 <code>size</code> bytes from the <code>istream</code>
* if possible, or throw <code>TestFailure</code> if unexpected end of
* <code>istream</code> 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 <code>istream</code> 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 <code>this</code> 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 <code>this</code> and the
* <code>other</code> 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 <code>purpose</code> of the test failure.
*/
public TestFailure(String purpose) {
super(purpose);
}
}
}

View File

@ -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).
* <p>
* <p>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.
* <p>
* <p>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 <code>System.out</code>.
*/
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 <code>MAX_CONNECTIONS</code> 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 <code>address</code>
* 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 <code>DATA_PARCELS</code> 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 ``<tt>null</tt>'' 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 <code>parcel[]</code> array using the given
* <code>random</code> numbers generator. Client and Server
* threads should use identical <code>random</code> 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 <code>size</code> bytes from the <code>istream</code>
* if possible, or throw <code>TestFailure</code> if unexpected end of
* <code>istream</code> 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 <code>istream</code> 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 <code>this</code> 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 <code>this</code> and the
* <code>other</code> 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 <code>purpose</code> 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.
* <p>
* <p>Command-line parameters provided with <code>args[]</code> may
* prompt the local host IP address or domain name. Execute:
* <br>&nbsp;&nbsp;
* <code>java network005 [<i>IP-address</i> | <i>host_name</i> |
* localhost ]</code>
* <br>where parameters are:
* <br>&nbsp;&nbsp;
* <code><i>IP-address</i></code> - local hots's address, or 127.0.0.1
* <br>&nbsp;&nbsp;
* <code><i>host_name</i></code> - local host's domain name, or the
* keyword ``<code>localhost</code>''
* <br>&nbsp;&nbsp;
* <code>localhost</code> - placeholder for the IP-address 127.0.0.1
* <br>By default, the test uses the Internet address available via
* the method <code>InetAddress.getLocalHost()</code>
*/
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 <code>run(args[],out)</code> 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.
}
}

View File

@ -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
* ``<code>localhost</code>'' (having IP address <code>127.0.0.1</code>).
* <p>
* <p>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.
* <p>
* <p>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 <code>MAX_CONNECTIONS</code> 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 <code>run(args[],out)</code> actually
* performing the test. After <code>run(args[],out)</code> 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 <code>args[]</code> 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.
* <p>
* <p>There should be 2 or 3 command-line parameters:
* <br>&nbsp;&nbsp;
* <code>java network006 <i>java_command</i>
* [<i>IP-address</i> | <i>host_name</i> | localhost ]</code>
* <br>where parameters are:
* <br>&nbsp;&nbsp;
* <code><i>java_command</i></code> - how to start java,
* e.g.: ``<code>c:\jdk1.3\bin\java -classic</code>''
* <br>&nbsp;&nbsp;
* <code>waittime</code> - timeout for TCP/IP sockets in minutes
* <br>&nbsp;&nbsp;
* <code><i>IP-address</i></code> - local hots's address, or 127.0.0.1
* <br>&nbsp;&nbsp;
* <code><i>host_name</i></code> - local host's domain name, or the
* keyword ``<code>localhost</code>''
* <br>&nbsp;&nbsp;
* <code>localhost</code> - placeholder for the IP-address 127.0.0.1
* <p>
* <p>Usually, <code><i>java_command</i></code> should point to the same
* Java machine just executing this test. However, every compatible Java 2
* implementation is appropriate.
* <p>
* <p>If optional parameter is ommited, the test invokes the method
* <code>InetAddress.getLocalHost()</code> 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 <code>address</code>
* 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 <code>null</code> 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 <code>address</code>
* and <code>port</code>.
*/
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 <code>DATA_PARCELS</code> 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 <code>args[]</code>, like:
* <pre>
* java network006$Client connections_to_try address port
* </pre>
*/
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 <code>out</code> and <code>err</code>
* streams of client VM.
*/
private static class IORedirector extends Thread {
/**
* Source stream.
*/
InputStream in;
/**
* Destination stream.
*/
OutputStream out;
/**
* Redirect <code>in</code> to <code>out</code>.
*/
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 <code>null</code>, 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
* <code>int</code> number equal to size of the parcel minus 1. I.e.: if
* number of data bytes in the parcel's contents is <code>N</code>, then
* the first 4 bytes encode the number <code>N-1</code>. 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 ``<tt>null</tt>'' 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 <code>parcel[]</code> array using the given
* <code>random</code> numbers generator. Client and Server
* threads should use identical <code>random</code> 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 <code>size</code> bytes from the <code>istream</code>
* if possible, or throw <code>TestFailure</code> if unexpected end of
* <code>istream</code> 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 <code>istream</code> 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 <code>this</code> 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 <code>this</code> and the
* <code>other</code> 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 <code>purpose</code> of the test failure.
*/
public TestFailure(String purpose) {
super(purpose);
}
}
}

View File

@ -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=.

View File

@ -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 <b>A</b><sup>.</sup><b>A</b> for
* a square matrix <b>A</b> of the type <code>double[][]</code>.
* Elements of the matrix <b>A</b> are initiated with random numbers,
* so that optimizing compiler could not eliminate any essential portion
* of calculations.
* <p>
* <p>That product <b>A</b><sup>.</sup><b>A</b> is calculated twice: in
* a single thread, and in <i>N</i> separate threads, where <i>N</i>x<i>N</i>
* is the size of square matrix <b>A</b>. When executing in <i>N</i> threads,
* each thread calculate distinct row of the resulting matrix. The test checks
* if the resulting product <b>A</b><sup>.</sup><b>A</b> is the same when
* calculated in single thread and in <i>N</i> threads.
* <p>
* <p>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 <i>N</i>-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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* 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 (<code>TOLERANCE</code>
* is assigned to 10 now).
*/
public static final double TOLERANCE = 100; // 10;
/**
* Re-assign this value to <code>true</code> for better
* diagnostics.
*/
private static boolean verbose = false;
private static PrintStream out = null;
/**
* Print error-message to the <code>out<code>.
*/
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 <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric001 [-verbose] [-performance] [-CPU:<i>number</i>]
* <i>matrixSize</i> [<i>threads</i>]</code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code><i>number</i></code> -
* number of CPU installed on the computer just executing the test
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix to be tested
* <br>&nbsp;&nbsp;<code><i>threads</i></code> -
* for multi-thread calculation
* (default: <code><i>matrixSize</i></code>)
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> for square matrix <code>A</code>.
*/
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 <code>value[][]</code> of <code>this</code> 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 <code>this</code> 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;
}
}
}
}
}

View File

@ -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 <b>A</b><sup>.</sup><b>A</b> for
* a square matrix <b>A</b> of the type <code>float[][]</code>.
* Elements of the matrix <b>A</b> are initiated with random numbers,
* so that optimizing compiler could not eliminate any essential portion
* of calculations.
* <p>
* <p>That product <b>A</b><sup>.</sup><b>A</b> is calculated twice: in
* a single thread, and in <i>N</i> separate threads, where <i>N</i>x<i>N</i>
* is the size of square matrix <b>A</b>. When executing in <i>N</i> threads,
* each thread calculate distinct row of the resulting matrix. The test checks
* if the resulting product <b>A</b><sup>.</sup><b>A</b> is the same when
* calculated in single thread and in <i>N</i> threads.
* <p>
* <p>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 <i>N</i>-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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* 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 (<code>TOLERANCE</code>
* is assigned to 10 now).
*/
public static final double TOLERANCE = 100; // 10;
/**
* Re-assign this value to <code>true</code> for better
* diagnostics.
*/
private static boolean verbose = false;
private static PrintStream out = null;
/**
* Print error-message to the <code>out<code>.
*/
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 <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric002 [-verbose] [-performance] [-CPU:<i>number</i>]
* <i>matrixSize</i> [<i>threads</i>]</code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code><i>number</i></code> -
* number of CPU installed on the computer just executing the test
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix to be tested
* <br>&nbsp;&nbsp;<code><i>threads</i></code> -
* for multi-thread calculation
* (default: <code><i>matrixSize</i></code>)
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> for square matrix <code>A</code>.
*/
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 <code>value[][]</code> of <code>this</code> 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 <code>this</code> 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 <code>run()</code> sets this flag on is actually
* finishes to execute.
*/
boolean threadExecuted = false;
}
}
}

View File

@ -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 <b>A</b><sup>.</sup><b>A</b> for
* a square matrix <b>A</b> of the type <code>long[][]</code>.
* Elements of the matrix <b>A</b> are initiated with random numbers,
* so that optimizing compiler could not eliminate any essential portion
* of calculations.
* <p>
* <p>That product <b>A</b><sup>.</sup><b>A</b> is calculated twice: in
* a single thread, and in <i>N</i> separate threads, where <i>N</i>x<i>N</i>
* is the size of square matrix <b>A</b>. When executing in <i>N</i> threads,
* each thread calculate distinct row of the resulting matrix. The test checks
* if the resulting product <b>A</b><sup>.</sup><b>A</b> is the same when
* calculated in single thread and in <i>N</i> threads.
* <p>
* <p>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 <i>N</i>-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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* 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 (<code>TOLERANCE</code>
* is assigned to 10 now).
*/
public static final double TOLERANCE = 100; // 10;
/**
* Re-assign this value to <code>true</code> for better
* diagnostics.
*/
private static boolean verbose = false;
private static PrintStream out = null;
/**
* Print error-message to the <code>out<code>.
*/
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 <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric003 [-verbose] [-performance] [-CPU:<i>number</i>]
* <i>matrixSize</i> [<i>threads</i>]</code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code><i>number</i></code> -
* number of CPU installed on the computer just executing the test
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix to be tested
* <br>&nbsp;&nbsp;<code><i>threads</i></code> -
* for multi-thread calculation
* (default: <code><i>matrixSize</i></code>)
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> for square matrix <code>A</code>.
*/
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 <code>value[][]</code> of <code>this</code> 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 <code>this</code> 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;
}
}
}
}
}

View File

@ -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 <b>A</b><sup>.</sup><b>A</b> for
* a square matrix <b>A</b> of the type <code>int[][]</code>.
* Elements of the matrix <b>A</b> are initiated with random numbers,
* so that optimizing compiler could not eliminate any essential portion
* of calculations.
* <p>
* <p>That product <b>A</b><sup>.</sup><b>A</b> is calculated twice: in
* a single thread, and in <i>N</i> separate threads, where <i>N</i>x<i>N</i>
* is the size of square matrix <b>A</b>. When executing in <i>N</i> threads,
* each thread calculate distinct row of the resulting matrix. The test checks
* if the resulting product <b>A</b><sup>.</sup><b>A</b> is the same when
* calculated in single thread and in <i>N</i> threads.
* <p>
* <p>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 <i>N</i>-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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* 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 (<code>TOLERANCE</code>
* is assigned to 10 now).
*/
public static final double TOLERANCE = 100; // 10;
/**
* Re-assign this value to <code>true</code> for better
* diagnostics.
*/
private static boolean verbose = false;
private static PrintStream out = null;
/**
* Print error-message to the <code>out<code>.
*/
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 <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric004 [-verbose] [-performance] [-CPU:<i>number</i>]
* <i>matrixSize</i> [<i>threads</i>]</code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code><i>number</i></code> -
* number of CPU installed on the computer just executing the test
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix to be tested
* <br>&nbsp;&nbsp;<code><i>threads</i></code> -
* for multi-thread calculation
* (default: <code><i>matrixSize</i></code>)
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> for square matrix <code>A</code>.
*/
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 <code>value[][]</code> of <code>this</code> 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 <code>this</code> 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;
}
}
}
}
}

View File

@ -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; 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;
* }
* In this test, N=300, so that A is 300x300 matrix; and multiplication
* A[line][k]*A[k][column] is executed 300**3=27 millions times in each
* 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.
* COMMENTS
* See the bug-report:
* #4242172 (P3/S5) 2.0: poor performance in matrix calculations
*
* @run main/othervm nsk.stress.numeric.numeric005.numeric005 300 3
*/
package nsk.stress.numeric.numeric005;
import java.io.PrintStream;
/**
* This test calculates the product <code>A<sup>.</sup>A</code> for
* a square matrix <code>A</code> of the type <code>double[][]</code>.
* Elements of the matrix <code>A</code> are initiated with random numbers,
* so that optimizing compiler could not eliminate any essential portion
* of calculations.
* <p>
* <p>Calculation of the product <code>A<sup>.</sup>A</code> is iterated three
* times, and result of the 1<sup>st</sup> iteration is compared to result of
* the 3<sup>rd</sup> iteration. HotSpot 1.0 and 1.3 seem to fail to adjust
* itself for better performance in 1<sup>st</sup> iteration, while 3<sup>rd</sup>
* iteration usually runs much faster. So, 1<sup>st</sup> iteration is probably
* executed by HotSpot interpreter, and HotSpot compiler is probably involved to
* execute the 3<sup>rd</sup> iteration. The test just tries to check if HotSpot
* compiler produces the same results as the HotSpot interpreter.
* <p>
* <p>By the way, the test checks JVM performance. The test is treated failed
* due to poor performance, if 1<sup>st</sup> iteration is essentially slower
* than the 3<sup>rd</sup> iteration. The calculations algorithm is encoded
* as compact ``canonical'' 3-levels cycle like:
* <pre>
* for (int line=0; line&lt;N; line++)
* for (int column=0; column&lt;N; column++) {
* double sum = 0;
* for (int k=0; k&lt;N; k++)
* sum += A[line][k] * A[k][column];
* AA[line][column] = sum;
* }
* </pre>
* <p>
* In this test, <code>N</code>=300, so that <code>A</code> is 300x300 matrix;
* and multiplication <code>A[line][k]*A[k][column]</code> is executed
* 300<sup>3</sup>=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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* #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 (<code>TOLERANCE</code>
* is assigned to 10 now).
*/
public static final double TOLERANCE = 100; // 10;
/**
* Re-assign this value to <code>true</code> 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 <code>System.out</code>
*/
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 <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void print(Object x) {
if (verbose)
out.print(x);
}
/**
* Print line to execution trace, if mode is <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void println(Object x) {
print(x + "\n");
}
/**
* Re-invoke <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric005 [-verbose] [-performance] <i>matrixSize</i>
* <i>iterations</i></code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix <code>A</code>
* <br>&nbsp;&nbsp;<code><i>iterations</i></code> -
* compute <code>A*A</code> several times
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> for the given square matrix <code>A</code>.
*/
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 <code>size</code>
* 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;
}
}

View File

@ -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; 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;
* }
* In this test, N=300, so that A is 300x300 matrix; and multiplication
* A[line][k]*A[k][column] is executed 300**3=27 millions times in each
* 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.
* COMMENTS
* See the bug-report:
* #4242172 (P3/S5) 2.0: poor performance in matrix calculations
* @run main/othervm nsk.stress.numeric.numeric006.numeric006 300 3
*/
package nsk.stress.numeric.numeric006;
import java.io.PrintStream;
/**
* This test calculates the product <code>A<sup>.</sup>A</code> for
* a square matrix <code>A</code> of the type <code>float[][]</code>.
* Elements of the matrix <code>A</code> are initiated with random numbers,
* so that optimizing compiler could not eliminate any essential portion
* of calculations.
* <p>
* <p>Calculation of the product <code>A<sup>.</sup>A</code> is iterated three
* times, and result of the 1<sup>st</sup> iteration is compared to result of
* the 3<sup>rd</sup> iteration. HotSpot 1.0 and 1.3 seem to fail to adjust
* itself for better performance in 1<sup>st</sup> iteration, while 3<sup>rd</sup>
* iteration usually runs much faster. So, 1<sup>st</sup> iteration is probably
* executed by HotSpot interpreter, and HotSpot compiler is probably involved to
* execute the 3<sup>rd</sup> iteration. The test just tries to check if HotSpot
* compiler produces the same results as the HotSpot interpreter.
* <p>
* <p>By the way, the test checks JVM performance. The test is treated failed
* due to poor performance, if 1<sup>st</sup> iteration is essentially slower
* than the 3<sup>rd</sup> iteration. The calculations algorithm is encoded
* as compact ``canonical'' 3-levels cycle like:
* <pre>
* for (int line=0; line&lt;N; line++)
* for (int column=0; column&lt;N; column++) {
* float sum = 0;
* for (int k=0; k&lt;N; k++)
* sum += A[line][k] * A[k][column];
* AA[line][column] = sum;
* }
* </pre>
* <p>
* In this test, <code>N</code>=300, so that <code>A</code> is 300x300 matrix;
* and multiplication <code>A[line][k]*A[k][column]</code> is executed
* 300<sup>3</sup>=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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* #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 (<code>TOLERANCE</code>
* is assigned to 10 now).
*/
public static final double TOLERANCE = 100; // 10;
/**
* Re-assign this value to <code>true</code> 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 <code>System.out</code>
*/
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 <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void print(Object x) {
if (verbose)
out.print(x);
}
/**
* Print line to execution trace, if mode is <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void println(Object x) {
print(x + "\n");
}
/**
* Re-invoke <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric006 [-verbose] [-performance] <i>matrixSize</i>
* <i>iterations</i></code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix <code>A</code>
* <br>&nbsp;&nbsp;<code><i>iterations</i></code> -
* compute <code>A*A</code> several times
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> for the given square matrix <code>A</code>.
*/
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 <code>size</code>
* 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;
}
}

View File

@ -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; 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;
* }
* In this test, N=300, so that A is 300x300 matrix; and multiplication
* A[line][k]*A[k][column] is executed 300**3=27 millions times in each
* 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.
* COMMENTS
* See the bug-report:
* #4242172 (P3/S5) 2.0: poor performance in matrix calculations
* @run main/othervm nsk.stress.numeric.numeric007.numeric007 300 3
*/
package nsk.stress.numeric.numeric007;
import java.io.PrintStream;
/**
* This test calculates the product <code>A<sup>.</sup>A</code> for
* a square matrix <code>A</code> of the type <code>long[][]</code>.
* Elements of the matrix <code>A</code> are initiated with random numbers,
* so that optimizing compiler could not eliminate any essential portion
* of calculations.
* <p>
* <p>Calculation of the product <code>A<sup>.</sup>A</code> is iterated three
* times, and result of the 1<sup>st</sup> iteration is compared to result of
* the 3<sup>rd</sup> iteration. HotSpot 1.0 and 1.3 seem to fail to adjust
* itself for better performance in 1<sup>st</sup> iteration, while 3<sup>rd</sup>
* iteration usually runs much faster. So, 1<sup>st</sup> iteration is probably
* executed by HotSpot interpreter, and HotSpot compiler is probably involved to
* execute the 3<sup>rd</sup> iteration. The test just tries to check if HotSpot
* compiler produces the same results as the HotSpot interpreter.
* <p>
* <p>By the way, the test checks JVM performance. The test is treated failed
* due to poor performance, if 1<sup>st</sup> iteration is essentially slower
* than the 3<sup>rd</sup> iteration. The calculations algorithm is encoded
* as compact ``canonical'' 3-levels cycle like:
* <pre>
* for (int line=0; line&lt;N; line++)
* for (int column=0; column&lt;N; column++) {
* long sum = 0;
* for (int k=0; k&lt;N; k++)
* sum += A[line][k] * A[k][column];
* AA[line][column] = sum;
* }
* </pre>
* <p>
* In this test, <code>N</code>=300, so that <code>A</code> is 300x300 matrix;
* and multiplication <code>A[line][k]*A[k][column]</code> is executed
* 300<sup>3</sup>=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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* #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 (<code>TOLERANCE</code>
* is assigned to 10 now).
*/
public static final double TOLERANCE = 100; // 10;
/**
* Re-assign this value to <code>true</code> 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 <code>System.out</code>
*/
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 <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void print(Object x) {
if (verbose)
out.print(x);
}
/**
* Print line to execution trace, if mode is <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void println(Object x) {
print(x + "\n");
}
/**
* Re-invoke <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric007 [-verbose] [-performance] <i>matrixSize</i>
* <i>iterations</i></code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix <code>A</code>
* <br>&nbsp;&nbsp;<code><i>iterations</i></code> -
* compute <code>A*A</code> several times
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> for the given square matrix <code>A</code>.
*/
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 <code>size</code>
* 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;
}
}

View File

@ -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; 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;
* }
* In this test, N=300, so that A is 300x300 matrix; and multiplication
* A[line][k]*A[k][column] is executed 300**3=27 millions times in each
* 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.
* COMMENTS
* See the bug-report:
* #4242172 (P3/S5) 2.0: poor performance in matrix calculations
* @run main/othervm nsk.stress.numeric.numeric008.numeric008 300 3
*/
package nsk.stress.numeric.numeric008;
import java.io.PrintStream;
/**
* This test calculates the product <code>A<sup>.</sup>A</code> for
* a square matrix <code>A</code> of the type <code>int[][]</code>.
* Elements of the matrix <code>A</code> are initiated with random numbers,
* so that optimizing compiler could not eliminate any essential portion
* of calculations.
* <p>
* <p>Calculation of the product <code>A<sup>.</sup>A</code> is iterated three
* times, and result of the 1<sup>st</sup> iteration is compared to result of
* the 3<sup>rd</sup> iteration. HotSpot 1.0 and 1.3 seem to fail to adjust
* itself for better performance in 1<sup>st</sup> iteration, while 3<sup>rd</sup>
* iteration usually runs much faster. So, 1<sup>st</sup> iteration is probably
* executed by HotSpot interpreter, and HotSpot compiler is probably involved to
* execute the 3<sup>rd</sup> iteration. The test just tries to check if HotSpot
* compiler produces the same results as the HotSpot interpreter.
* <p>
* <p>By the way, the test checks JVM performance. The test is treated failed
* due to poor performance, if 1<sup>st</sup> iteration is essentially slower
* than the 3<sup>rd</sup> iteration. The calculations algorithm is encoded
* as compact ``canonical'' 3-levels cycle like:
* <pre>
* for (int line=0; line&lt;N; line++)
* for (int column=0; column&lt;N; column++) {
* int sum = 0;
* for (int k=0; k&lt;N; k++)
* sum += A[line][k] * A[k][column];
* AA[line][column] = sum;
* }
* </pre>
* <p>
* In this test, <code>N</code>=300, so that <code>A</code> is 300x300 matrix;
* and multiplication <code>A[line][k]*A[k][column]</code> is executed
* 300<sup>3</sup>=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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* #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 (<code>TOLERANCE</code>
* is assigned to 10 now).
*/
public static final double TOLERANCE = 100; // 10;
/**
* Re-assign this value to <code>true</code> 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 <code>System.out</code>
*/
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 <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void print(Object x) {
if (verbose)
out.print(x);
}
/**
* Print line to execution trace, if mode is <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void println(Object x) {
print(x + "\n");
}
/**
* Re-invoke <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric008 [-verbose] [-performance] <i>matrixSize</i>
* <i>iterations</i></code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix <code>A</code>
* <br>&nbsp;&nbsp;<code><i>iterations</i></code> -
* compute <code>A*A</code> several times
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> for the given square matrix <code>A</code>.
*/
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 <code>size</code>
* 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;
}
}

View File

@ -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; 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;
* }
* In this test, N=200, so that A is 200x200 matrix; and multiplication
* A[line][k]*A[k][column] is executed 200**3=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.
* COMMENTS
* See the bug-report:
* #4242172 (P3/S5) 2.0: poor performance in matrix calculations
*
* @run main/othervm nsk.stress.numeric.numeric009.numeric009 200 2
*/
package nsk.stress.numeric.numeric009;
import java.io.PrintStream;
/**
* This test calculates the product <code>A<sup>.</sup>A</code> for a square
* matrix <code>A</code>, and checks if such product is calculated correctly.
* Elements of the matrix <code>A</code> are initiated with integer numbers,
* so that <code>A<sup>.</sup>A</code> must be the same if calculated with
* <code>double</code>, <code>float</code>, <code>long</code>, or
* <code>int</code> precision. The test just checks, if <code>double</code>,
* <code>float</code>, <code>long</code>, and <code>int</code> variants of
* the product calculation result in the same <code>A<sup>.</sup>A</code>
* matrix.
* <p>
* <p>Calculation of the product <code>A<sup>.</sup>A</code> is iterated two
* times, because HotSpot releases 1.0 and 1.3 seem to do not adjust JVM for
* better performance in 1<sup>st</sup> iteration, while 2<sup>nd</sup>
* iteration usually runs much faster. I guess, that the 1<sup>st</sup> iteration
* is probably executed by HotSpot interpreter, and HotSpot compiler is probably
* involved to execute the 2<sup>nd</sup> iteration. So, the test apparently
* checks accuracy of <code>A<sup>.</sup>A</code> calculation in both compilation
* and interpretation modes.
* <p>
* <p>By the way, the test checks JVM performance. The test is treated failed
* due to poor performance, if 1<sup>st</sup> iteration is essentially slower
* than the 2<sup>nd</sup> iteration. The calculations algorithm is encoded
* as compact ``canonical'' 3-levels cycle like:
* <pre>
* for (int line=0; line&lt;N; line++)
* for (int column=0; column&lt;N; column++) {
* float sum = 0;
* for (int k=0; k&lt;N; k++)
* sum += A[line][k] * A[k][column];
* AA[line][column] = sum;
* }
* </pre>
* <p>
* In this test, <code>N</code>=200, so that <code>A</code> is 200x200 matrix;
* and multiplication <code>A[line][k]*A[k][column]</code> is executed
* 200<sup>3</sup>=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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* #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 (<code>tolerance</code> is assigned to 10 now).
*/
public static double tolerance = 100; // 10;
/**
* Re-assign this value to <code>true</code> 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 <code>System.out</code>
*/
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 <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void print(Object x) {
if (verbose)
out.print(x);
}
/**
* Print line to execution trace, if mode is <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void println(Object x) {
print(x + "\n");
}
/**
* Re-invoke <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric009 [-verbose] [-performance]
* [-tolerance:<i>percents</i>]
* <i>matrixSize</i> <i>iterations</i></code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword alowing to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword turning on performance testing
* <br>&nbsp;&nbsp;<code>-tolerance</code> -
* setup tolerance of performance checking
* <br>&nbsp;&nbsp;<code><i>percents</i></code> -
* 1<sup>st</sup> iteration is allowed to be
* <code><i>percents</i></code>% slower
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix <code>A</code>
* <br>&nbsp;&nbsp;<code><i>iterations</i></code> -
* how many times to execute the test for stronger checking
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> with <code>int</code>, <code>long</code>,
* <code>float</code>, and <code>double</code> 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 <code>A*A</code> for the given square matrix <code>A</code>.
*/
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 <code>A*A</code> for the given square matrix <code>A</code>.
*/
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 <code>A*A</code> for the given square matrix <code>A</code>.
*/
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 <code>A*A</code> for the given square matrix <code>A</code>.
*/
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 <code>size</code>
* 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 <code>long</code> elements,
* and initiate them with the same values as in the given matrix
* <code>intA</code>.
*/
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 <code>double</code> elements,
* and initiate them with the same values as in the given matrix
* <code>intA</code>.
*/
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 <code>float</code> elements,
* and initiate them with the same values as in the given matrix
* <code>intA</code>.
*/
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;
}
}

View File

@ -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; 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;
* }
* In this test, N=200, so that A is 200x200 matrix; and multiplication
* A[line][k]*A[k][column] is executed 200**3=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.
* 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
* Note, that despite HotSpot works faster in milti-thread calculations,
* it still remains essentially slower than classic VM with JIT on.
*
* @run main/othervm nsk.stress.numeric.numeric010.numeric010 200 200
*/
package nsk.stress.numeric.numeric010;
import java.io.PrintStream;
/**
* This test calculates the product <code>A<sup>.</sup>A</code> for a square
* matrix <code>A</code>, and checks if such product is calculated correctly.
* Elements of the matrix <code>A</code> are initiated with integer numbers,
* so that <code>A<sup>.</sup>A</code> must be the same if calculated with
* <code>double</code>, <code>float</code>, <code>long</code>, or
* <code>int</code> precision. The test just checks, if <code>double</code>,
* <code>float</code>, <code>long</code>, and <code>int</code> variants of
* the product calculation result in the same <code>A<sup>.</sup>A</code>
* matrix.
* <p>
* <p>The product <code>A<sup>.</sup>A</code> is calculated twice: in a single
* thread, and in <code>N</code> separate threads, where <code>NxN</code> is
* the size of square matrix <code>A</code>. When executing in <code>N</code>
* 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
* <code>N</code>-threads calculation. So, the test apparently checks accuracy
* of <code>A<sup>.</sup>A</code> calculation in both compilation and
* interpretation modes.
* <p>
* <p>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 <code>N</code>-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:
* <pre>
* for (int line=0; line&lt;N; line++)
* for (int column=0; column&lt;N; column++) {
* float sum = 0;
* for (int k=0; k&lt;N; k++)
* sum += A[line][k] * A[k][column];
* AA[line][column] = sum;
* }
* </pre>
* <p>
* In this test, <code>N</code>=200, so that <code>A</code> is 200x200 matrix;
* and multiplication <code>A[line][k]*A[k][column]</code> is executed
* 200<sup>3</sup>=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.
* <p>
* <p>See the bug-report:
* <br>&nbsp;&nbsp;
* 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 (<code>tolerance</code> is
* assigned to 10 now).
*/
public static double tolerance = 100; // 10;
/**
* Re-assign this value to <code>true</code> 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 <code>System.out</code>
*/
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 <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void print(Object x) {
if (verbose)
out.print(x);
}
/**
* Print line to execution trace, if mode is <code>verbose</code>.
*
* @see #verbose
* @see #out
*/
private static void println(Object x) {
print(x + "\n");
}
/**
* Re-invoke <code>run(args,out)</code> 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 <code>args[]</code> and run
* the test.
* <p>
* <p>Command-line parameters are:
* <br>&nbsp;&nbsp;
* <code>java numeric010 [-verbose] [-performance]
* [-tolerance:<i>percents</i>] [-CPU:<i>number</i>]
* <i>matrixSize</i> [<i>threads</i>]</code>
* <p>
* <p>Here:
* <br>&nbsp;&nbsp;<code>-verbose</code> -
* keyword, which alows to print execution trace
* <br>&nbsp;&nbsp;<code>-performance</code> -
* keyword, which alows performance testing
* <br>&nbsp;&nbsp;<code>-tolerance</code> -
* setup tolerance of performance checking
* <br>&nbsp;&nbsp;<code><i>percents</i></code> -
* 1-thread calculation is allowed to be
* <code><i>percents</i></code>% slower
* <br>&nbsp;&nbsp;<code><i>number</i></code> -
* number of CPU installed on the computer just executing the test
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
* number of rows (and columns) in square matrix to be tested
* <br>&nbsp;&nbsp;<code><i>threads</i></code> -
* for multi-thread calculation
* (default: <code><i>matrixSize</i></code>)
*
* @param args strings array containing command-line parameters
* @param out the test log, usually <code>System.out</code>
*/
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 <code>A*A</code> with <code>int</code>, <code>long</code>,
* <code>float</code>, and <code>double</code> 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 <code>A*A</code> for <code>int</code> matrix <code>A</code>.
*/
private static class IntegerMatrix {
volatile int value[][];
/**
* Number of lines and columns in <code>this</code> 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 <code>this</code> matrix with <code>A*A</code>.
*
* @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 <code>this</code> 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 <code>A*A</code> for <code>long</code> matrix <code>A</code>.
*/
private static class LongMatrix {
volatile long value[][];
/**
* Number of lines and columns in <code>this</code> 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 <code>this</code> matrix with <code>A*A</code>.
*
* @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 <code>this</code> 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 <code>A*A</code> for <code>float</code> matrix <code>A</code>.
*/
private static class FloatMatrix {
volatile float value[][];
/**
* Number of lines and columns in <code>this</code> 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 <code>this</code> matrix with <code>A*A</code>.
*
* @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 <code>this</code> 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 <code>A*A</code> for <code>float</code> matrix <code>A</code>.
*/
private static class DoubleMatrix {
volatile double value[][];
/**
* Number of lines and columns in <code>this</code> 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 <code>this</code> matrix with <code>A*A</code>.
*
* @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 <code>this</code> 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;
}
}
}
}
}

View File

@ -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=.

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 <stdlib.h>
#include "jni_tools.h"
#ifndef _IS_NSK_STRACE_DEFINED_
#define _IS_NSK_STRACE_DEFINED_
#define JNI_VERSION JNI_VERSION_1_1
#define EXCEPTION_CLEAR (*env)->ExceptionClear(env)
#define EXCEPTION_OCCURRED (*env)->ExceptionOccurred(env)
// Check for pending exception of the specified type
// If it's present, then clear it
#define EXCEPTION_CHECK(exceptionClass, recurDepth) \
if (EXCEPTION_OCCURRED != NULL) { \
jobject exception = EXCEPTION_OCCURRED; \
if (NSK_CPP_STUB3(IsInstanceOf, env, exception, \
exceptionClass) == JNI_TRUE) { \
EXCEPTION_CLEAR; \
NSK_DISPLAY1("StackOverflowError occurred at depth %d\n", recurDepth); \
} \
}
#define FIND_CLASS(_class, _className)\
if (!NSK_JNI_VERIFY(env, (_class = \
NSK_CPP_STUB2(FindClass, env, _className)) != NULL))\
exit(1)
#define GET_OBJECT_CLASS(_class, _obj)\
if (!NSK_JNI_VERIFY(env, (_class = \
NSK_CPP_STUB2(GetObjectClass, env, _obj)) != NULL))\
exit(1)
#define GET_FIELD_ID(_fieldID, _class, _fieldName, _fieldSig)\
if (!NSK_JNI_VERIFY(env, (_fieldID = \
NSK_CPP_STUB4(GetFieldID, env, _class,\
_fieldName, _fieldSig)) != NULL))\
exit(1)
#define GET_STATIC_FIELD_ID(_fieldID, _class, _fieldName, _fieldSig)\
if (!NSK_JNI_VERIFY(env, (_fieldID = \
NSK_CPP_STUB4(GetStaticFieldID, env, _class,\
_fieldName, _fieldSig)) != NULL))\
exit(1)
#define GET_STATIC_BOOL_FIELD(_value, _class, _fieldName)\
GET_STATIC_FIELD_ID(field, _class, _fieldName, "Z");\
_value = NSK_CPP_STUB3(GetStaticBooleanField, env, _class, field)
#define GET_STATIC_INT_FIELD(_value, _class, _fieldName)\
GET_STATIC_FIELD_ID(field, _class, _fieldName, "I");\
_value = NSK_CPP_STUB3(GetStaticIntField, env, _class, field)
#define GET_STATIC_OBJ_FIELD(_value, _class, _fieldName, _fieldSig)\
GET_STATIC_FIELD_ID(field, _class, _fieldName, _fieldSig);\
_value = NSK_CPP_STUB3(GetStaticObjectField, env, _class, \
field)
#define GET_INT_FIELD(_value, _obj, _class, _fieldName)\
GET_FIELD_ID(field, _class, _fieldName, "I");\
_value = NSK_CPP_STUB3(GetIntField, env, _obj, field)
#define SET_INT_FIELD(_obj, _class, _fieldName, _newValue)\
GET_FIELD_ID(field, _class, _fieldName, "I");\
NSK_CPP_STUB4(SetIntField, env, _obj, field, _newValue)
#define SET_STATIC_INT_FIELD(_class, _fieldName, _newValue)\
GET_STATIC_FIELD_ID(field, _class, _fieldName, "I");\
NSK_CPP_STUB4(SetStaticIntField, env, _class, field, _newValue)
#define GET_OBJ_FIELD(_value, _obj, _class, _fieldName, _fieldSig)\
GET_FIELD_ID(field, _class, _fieldName, _fieldSig);\
_value = NSK_CPP_STUB3(GetObjectField, env, _obj, field)
#define GET_STATIC_METHOD_ID(_methodID, _class, _methodName, _sig)\
if (!NSK_JNI_VERIFY(env, (_methodID = \
NSK_CPP_STUB4(GetStaticMethodID, env, _class,\
_methodName, _sig)) != NULL))\
exit(1)
#define GET_METHOD_ID(_methodID, _class, _methodName, _sig)\
if (!NSK_JNI_VERIFY(env, (_methodID = \
NSK_CPP_STUB4(GetMethodID, env, _class,\
_methodName, _sig)) != NULL))\
exit(1)
#define CALL_STATIC_VOID_NOPARAM(_class, _methodName)\
GET_STATIC_METHOD_ID(method, _class, _methodName, "()V");\
if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB3(CallStaticVoidMethod, env,\
_class, method)))\
exit(1)
#define CALL_STATIC_VOID(_class, _methodName, _sig, _param)\
GET_STATIC_METHOD_ID(method, _class, _methodName, _sig);\
if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB4(CallStaticVoidMethod, env,\
_class, method, _param)))\
exit(1)
#define CALL_VOID_NOPARAM(_obj, _class, _methodName)\
GET_METHOD_ID(method, _class, _methodName, "()V");\
if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB3(CallVoidMethod, env, _obj,\
method)))\
exit(1)
#define CALL_VOID(_obj, _class, _methodName, _sig, _param)\
GET_METHOD_ID(method, _class, _methodName, _sig);\
if (!NSK_JNI_VERIFY_VOID(env, NSK_CPP_STUB4(CallVoidMethod, env, _obj,\
method, _param)))\
exit(1)
#define MONITOR_ENTER(x) \
NSK_JNI_VERIFY(env, NSK_CPP_STUB2(MonitorEnter, env, x) == 0)
#define MONITOR_EXIT(x) \
NSK_JNI_VERIFY(env, NSK_CPP_STUB2(MonitorExit, env, x) == 0)
#endif /* _IS_NSK_STRACE_DEFINED_ */

View File

@ -0,0 +1,304 @@
/*
* 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/strace001.
* VM testbase keywords: [stress, quick, strace]
* VM testbase readme:
* DESCRIPTION
* The test checks up java.lang.Thread.getStackTrace() method for many threads,
* that recursively invoke a pure java method in running mode ("alive" stack).
* The test fails if:
* - amount of stack trace elements is more than depth of recursion plus
* four elements corresponding to invocations of Thread.run(), Thread.wait(),
* Thread.exit(), Thread.yield() and ThreadGroup.remove() methods;
* - there is at least one element corresponding to invocation of unexpected
* method.
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm nsk.stress.strace.strace001
*/
package nsk.stress.strace;
import nsk.share.ArgumentParser;
import nsk.share.Failure;
import nsk.share.Log;
import java.io.PrintStream;
/**
* The test check up <code>java.lang.Thread.getStackTrace()</code> method for many threads,
* that recursively invoke a pure java method in running mode ("alive" stack).
* <p>
* <p>The test creates <code>THRD_COUNT</code> instances of <code>strace001Thread</code>
* 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 <code>EXPECTED_METHODS</code> array.</p>
* <p>These checking are performed <code>REPEAT_COUNT</code> times.</p>
*/
public class strace001 {
static final int DEPTH = 200;
static final int THRD_COUNT = 100;
static final int REPEAT_COUNT = 10;
static final String[] EXPECTED_METHODS = {
"java.lang.System.arraycopy",
"java.lang.Object.wait",
"java.lang.Thread.exit",
"java.lang.Thread.yield",
"java.lang.ThreadGroup.remove",
"java.lang.ThreadGroup.threadTerminated",
"nsk.stress.strace.strace001Thread.run",
"nsk.stress.strace.strace001Thread.recursiveMethod"
};
static volatile boolean isLocked = false;
static PrintStream out;
static long waitTime = 2;
static Object waitStart = new Object();
static strace001Thread[] threads;
static StackTraceElement[][] snapshots = new StackTraceElement[THRD_COUNT][];
static Log log;
public static void main(String[] args) {
out = System.out;
int exitCode = run(args);
System.exit(exitCode + 95);
}
volatile int achivedCount = 0;
public static int run(String[] args) {
ArgumentParser argHandler = new ArgumentParser(args);
log = new Log(out, argHandler);
waitTime = argHandler.getWaitTime() * 60000;
strace001 test = new strace001();
boolean res = true;
for (int j = 0; j < REPEAT_COUNT; j++) {
test.startThreads();
if (!test.makeSnapshot(j + 1)) res = false;
display("waiting for threads finished\n");
test.finishThreads();
}
if (!res) {
complain("***>>>Test failed<<<***");
return 2;
}
return 0;
}
void startThreads() {
threads = new strace001Thread[THRD_COUNT];
achivedCount = 0;
String tmp_name;
for (int i = 0; i < THRD_COUNT; i++) {
tmp_name = "strace001Thread" + Integer.toString(i);
threads[i] = new strace001Thread(this, tmp_name);
}
for (int i = 0; i < THRD_COUNT; i++) {
threads[i].start();
}
waitFor("all threads started ...");
synchronized (waitStart) {
isLocked = true;
waitStart.notifyAll();
}
try {
Thread.yield();
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
void waitFor(String msg) {
if (msg.length() > 0)
display("waiting for " + msg);
while (achivedCount < THRD_COUNT) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
achivedCount = 0;
}
boolean makeSnapshot(int repeat_number) {
for (int i = 0; i < threads.length; i++) {
snapshots[i] = threads[i].getStackTrace();
}
return checkTraces(repeat_number);
}
boolean checkTraces(int repeat_number) {
StackTraceElement[] elements;
boolean res = true;
display(">>> snapshot " + repeat_number);
int expectedCount = DEPTH + 1;
for (int i = 0; i < threads.length; i++) {
elements = snapshots[i];
if (elements == null)
continue;
if (elements.length == 0)
continue;
if (elements.length > 3) {
display("\tchecking " + threads[i].getName()
+ "(trace elements: " + elements.length + ")");
}
if (elements.length > expectedCount) {
complain(threads[i].getName() + ">Contains more then " +
+expectedCount + " elements");
}
for (int j = 0; j < elements.length; j++) {
if (!checkElement(elements[j])) {
complain(threads[i].getName() + ">Unexpected method name: "
+ elements[j].getMethodName());
complain("\tat " + j + " position");
if (elements[j].isNativeMethod()) {
complain("\tline number: (native method)");
complain("\tclass name: " + elements[j].getClassName());
} else {
complain("\tline number: " + elements[j].getLineNumber());
complain("\tclass name: " + elements[j].getClassName());
complain("\tfile name: " + elements[j].getFileName());
}
res = false;
}
}
}
return res;
}
boolean checkElement(StackTraceElement element) {
String name = element.getClassName() + "." + element.getMethodName();
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
if (EXPECTED_METHODS[i].compareTo(name) == 0)
return true;
}
return false;
}
void finishThreads() {
try {
for (int i = 0; i < threads.length; i++) {
if (threads[i].isAlive())
threads[i].join(waitTime / THRD_COUNT);
}
} catch (InterruptedException e) {
complain("" + e);
}
isLocked = false;
}
static void display(String message) {
log.display(message);
}
static void complain(String message) {
log.complain(message);
}
}
class strace001Thread extends Thread {
private int currentDepth = 0;
strace001 test;
strace001Thread(strace001 test, String name) {
this.test = test;
setName(name);
}
public void run() {
try {
recursiveMethod();
} catch (Throwable throwable) {
System.err.println("# ERROR: " + getName() + ": " + throwable);
System.exit(1);
}
}
void recursiveMethod() {
currentDepth++;
if (currentDepth == 1) {
synchronized (test) {
test.achivedCount++;
}
int alltime = 0;
while (!strace001.isLocked) {
synchronized (test) {
try {
test.wait(1);
alltime++;
} catch (InterruptedException e) {
strace001.complain("" + e);
}
if (alltime > strace001.waitTime) {
throw new Failure("out of wait time");
}
}
}
}
if (strace001.DEPTH - currentDepth > 0) {
yield();
recursiveMethod();
}
currentDepth--;
}
}

View File

@ -0,0 +1,313 @@
/*
* 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/strace002.
* VM testbase keywords: [stress, quick, strace]
* VM testbase readme:
* DESCRIPTION
* The test checks up java.lang.Thread.getAllStackTraces() method for many
* threads, that recursively invoke a pure java method in running mode
* ("alive" stack).
* The test fails if:
* - amount of stack trace elements is more than depth of recursion plus
* four elements corresponding to invocations of Thread.run(), Thread.wait(),
* Thread.exit(), Thread.yield() and ThreadGroup.remove() methods;
* - there is at least one element corresponding to invocation of unexpected
* method.
* This test is almost the same as nsk.stress.strace.strace001 except for
* checking is performed for java.lang.Thread.getAllStackTraces() method.
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm nsk.stress.strace.strace002
*/
package nsk.stress.strace;
import nsk.share.ArgumentParser;
import nsk.share.Failure;
import nsk.share.Log;
import java.io.PrintStream;
import java.util.Map;
/**
* The test check up <code>java.lang.Thread.getAllStackTraces()</code> method for many
* threads, that recursively invoke a pure java method in running mode ("alive" stack).
* <p>
* <p>The test creates <code>THRD_COUNT</code> instances of <code>strace002Thread</code>
* 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 <code>EXPECTED_METHODS</code> array.</p>
* <p>These checking are performed <code>REPEAT_COUNT</code> times.</p>
*/
public class strace002 {
static final int DEPTH = 200;
static final int THRD_COUNT = 100;
static final int REPEAT_COUNT = 10;
static final String[] EXPECTED_METHODS = {
"java.lang.System.arraycopy",
"java.lang.Object.wait",
"java.lang.Thread.exit",
"java.lang.Thread.yield",
"java.lang.ThreadGroup.remove",
"java.lang.ThreadGroup.threadTerminated",
"nsk.stress.strace.strace002Thread.run",
"nsk.stress.strace.strace002Thread.recursiveMethod"
};
static volatile boolean isLocked = false;
static PrintStream out;
static long waitTime = 2;
static Object waitStart = new Object();
static strace002Thread[] threads;
static StackTraceElement[][] snapshots = new StackTraceElement[THRD_COUNT][];
static Log log;
public static void main(String[] args) {
out = System.out;
int exitCode = run(args);
System.exit(exitCode + 95);
}
volatile int achivedCount = 0;
public static int run(String[] args) {
ArgumentParser argHandler = new ArgumentParser(args);
log = new Log(out, argHandler);
waitTime = argHandler.getWaitTime() * 60000;
strace002 test = new strace002();
boolean res = true;
for (int j = 0; j < REPEAT_COUNT; j++) {
test.startThreads();
if (!test.makeSnapshot(j + 1)) res = false;
display("waiting for threads finished\n");
test.finishThreads();
}
if (!res) {
complain("***>>>Test failed<<<***");
return 2;
}
return 0;
}
void startThreads() {
threads = new strace002Thread[THRD_COUNT];
achivedCount = 0;
String tmp_name;
for (int i = 0; i < THRD_COUNT; i++) {
tmp_name = "strace002Thread" + Integer.toString(i);
threads[i] = new strace002Thread(this, tmp_name);
}
for (int i = 0; i < THRD_COUNT; i++) {
threads[i].start();
}
waitFor("all threads started ...");
synchronized (waitStart) {
isLocked = true;
waitStart.notifyAll();
}
try {
Thread.yield();
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
void waitFor(String msg) {
if (msg.length() > 0)
display("waiting for " + msg);
while (achivedCount < THRD_COUNT) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
achivedCount = 0;
}
boolean makeSnapshot(int repeat_number) {
Map traces = Thread.getAllStackTraces();
for (int i = 0; i < threads.length; i++) {
snapshots[i] = (StackTraceElement[]) traces.get(threads[i]);
}
return checkTraces(repeat_number);
}
boolean checkTraces(int repeat_number) {
StackTraceElement[] elements;
boolean res = true;
display(">>> snapshot " + repeat_number);
int expectedCount = DEPTH + 1;
for (int i = 0; i < threads.length; i++) {
elements = snapshots[i];
if (elements == null)
continue;
if (elements.length == 0)
continue;
if (elements.length > 3) {
display("\tchecking " + threads[i].getName()
+ "(trace elements: " + elements.length + ")");
}
if (elements.length > expectedCount) {
complain(threads[i].getName() + ">Contains more then " +
+expectedCount + " elements");
}
for (int j = 0; j < elements.length; j++) {
if (!checkElement(elements[j])) {
complain(threads[i].getName() + ">Unexpected method name: "
+ elements[j].getMethodName());
complain("\tat " + j + " position");
if (elements[j].isNativeMethod()) {
complain("\tline number: (native method)");
complain("\tclass name: " + elements[j].getClassName());
} else {
complain("\tline number: " + elements[j].getLineNumber());
complain("\tclass name: " + elements[j].getClassName());
complain("\tfile name: " + elements[j].getFileName());
}
res = false;
}
}
}
return res;
}
boolean checkElement(StackTraceElement element) {
String name = element.getClassName() + "." + element.getMethodName();
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
if (EXPECTED_METHODS[i].compareTo(name) == 0)
return true;
}
return false;
}
void finishThreads() {
try {
for (int i = 0; i < threads.length; i++) {
if (threads[i].isAlive())
threads[i].join(waitTime / THRD_COUNT);
}
} catch (InterruptedException e) {
complain("" + e);
}
isLocked = false;
}
static void display(String message) {
log.display(message);
}
static void complain(String message) {
log.complain(message);
}
}
class strace002Thread extends Thread {
private int currentDepth = 0;
strace002 test;
strace002Thread(strace002 test, String name) {
this.test = test;
setName(name);
}
public void run() {
try {
recursiveMethod();
} catch (Throwable throwable) {
System.err.println("# ERROR: " + getName() + ": " + throwable);
System.exit(1);
}
}
void recursiveMethod() {
currentDepth++;
if (currentDepth == 1) {
synchronized (test) {
test.achivedCount++;
}
int alltime = 0;
while (!test.isLocked) {
synchronized (test) {
try {
test.wait(1);
alltime++;
} catch (InterruptedException e) {
strace002.complain("" + e);
}
if (alltime > strace002.waitTime) {
throw new Failure("out of wait time");
}
}
}
}
if (strace002.DEPTH - currentDepth > 0) {
yield();
recursiveMethod();
}
currentDepth--;
}
}

View File

@ -0,0 +1,94 @@
/*
* 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 <stdio.h>
#include "nsk_strace.h"
#ifdef __cplusplus
extern "C" {
#endif
static const char *Stest_cn="nsk/stress/strace/strace003";
static const char *Slongparam="(J)V";
JNIEXPORT void JNICALL
Java_nsk_stress_strace_strace003Thread_recursiveMethod(JNIEnv *env, jobject obj)
{
jfieldID field;
jmethodID method;
jint currDepth;
jclass testClass, threadClass, objClass;
jint maxDepth;
jboolean isLocked;
jint achivedCount;
jobject testField, waitStart;
FIND_CLASS(testClass, Stest_cn);
FIND_CLASS(objClass, "java/lang/Object");
GET_OBJECT_CLASS(threadClass, obj);
/* currDepth++ */
GET_INT_FIELD(currDepth, obj, threadClass, "currentDepth");
currDepth++;
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
if (currDepth == 1)
{
GET_OBJ_FIELD(testField, obj, threadClass, "test",
"Lnsk/stress/strace/strace003;");
GET_STATIC_OBJ_FIELD(waitStart, testClass, "waitStart",
"Ljava/lang/Object;");
MONITOR_ENTER(testField);
GET_INT_FIELD(achivedCount, testField, testClass, "achivedCount");
achivedCount++;
SET_INT_FIELD(testField, testClass, "achivedCount", achivedCount);
MONITOR_EXIT(testField);
GET_STATIC_BOOL_FIELD(isLocked, testClass, "isLocked");
while (isLocked != JNI_TRUE)
{
MONITOR_ENTER(waitStart);
CALL_VOID(waitStart, objClass, "wait", Slongparam, 1LL);
MONITOR_EXIT(waitStart);
GET_STATIC_BOOL_FIELD(isLocked, testClass, "isLocked");
}
}
GET_STATIC_INT_FIELD(maxDepth, testClass, "DEPTH");
if (maxDepth - currDepth > 0)
{
CALL_STATIC_VOID_NOPARAM(threadClass, "yield");
CALL_VOID_NOPARAM(obj, threadClass, "recursiveMethod");
}
currDepth--;
GET_OBJECT_CLASS(threadClass, obj);
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,327 @@
/*
* 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/strace003.
* VM testbase keywords: [stress, strace]
* VM testbase readme:
* DESCRIPTION
* The test checks up java.lang.Thread.getStackTrace() method for many threads,
* that recursively invoke a native method in running mode ("alive" stack).
* The test fails if:
* - amount of stack trace elements is more than depth of recursion plus
* four elements corresponding to invocations of Thread.run(), Thread.wait(),
* Thread.exit(), Thread.yield() and ThreadGroup.remove() methods;
* - there is at least one element corresponding to invocation of unexpected
* method.
* This test is almost the same as nsk.stress.strace.strace001 except for
* the recursive method is a native one.
* COMMENTS
* Below assertion is revealed on engineer's build. It is needed to check
* on a promoted build.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Started at: Fri Apr 25 15:47:13 NSK 2003
* waiting for all threads started ...
* >>> snapshot 1
* checking strace003Thread0(trace elements: 2)
* checking strace003Thread1(trace elements: 2)
* checking strace003Thread2(trace elements: 3)
* checking strace003Thread3(trace elements: 2)
* checking strace003Thread4(trace elements: 2)
* checking strace003Thread5(trace elements: 2)
* checking strace003Thread6(trace elements: 3)
* checking strace003Thread7(trace elements: 2)
* # To suppress the following error report, specify this argument
* # after -XX: or in .hotspotrc: SuppressErrorAt=/jniHandles.hpp:157
* #
* # HotSpot Virtual Machine Error, assertion failure
* # Please report this error at
* # http://java.sun.com/cgi-bin/bugreport.cgi
* #
* # Java VM: Java HotSpot(TM) Client VM (1.4.1-internal-debug mixed mode)
* #
* # assert(result != ((oop)::badJNIHandleVal), "Pointing to zapped jni handle area")
* #
* # Error ID: src/share/vm/runtime/jniHandles.hpp, 157 [ Patched ]
* #
* # Problematic Thread: prio=5 tid=0x001b99e8 nid=0xbf runnable
* #
* Heap at VM Abort:
* Heap
* def new generation total 2112K, used 300K [0xf1800000, 0xf1a20000, 0xf1f10000)
* eden space 2048K, 14% used [0xf1800000, 0xf184b358, 0xf1a00000)
* from space 64K, 0% used [0xf1a00000, 0xf1a00000, 0xf1a10000)
* to space 64K, 0% used [0xf1a10000, 0xf1a10000, 0xf1a20000)
* tenured generation total 1408K, used 0K [0xf1f10000, 0xf2070000, 0xf5800000)
* the space 1408K, 0% used [0xf1f10000, 0xf1f10000, 0xf1f10200, 0xf2070000)
* compacting perm gen total 4096K, used 1024K [0xf5800000, 0xf5c00000, 0xf9800000)
* the space 4096K, 25% used [0xf5800000, 0xf5900240, 0xf5900400, 0xf5c00000)
* Dumping core....
* Abort
* Finished at: Fri Apr 25 15:48:10 NSK 2003
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native nsk.stress.strace.strace003
*/
package nsk.stress.strace;
import nsk.share.ArgumentParser;
import nsk.share.Log;
import java.io.PrintStream;
/**
* The test check up <code>java.lang.Thread.getStackTrace()</code> method for many threads,
* that recursively invoke a native method in running mode ("alive" stack).
* <p>
* <p>The test creates <code>THRD_COUNT</code> instances of <code>strace003Thread</code>
* 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 <code>EXPECTED_METHODS</code> array.</p>
* <p>These checking are performed <code>REPEAT_COUNT</code> times.</p>
*/
public class strace003 {
static final int DEPTH = 100;
static final int THRD_COUNT = 100;
static final int REPEAT_COUNT = 10;
static final String[] EXPECTED_METHODS = {
"java.lang.System.arraycopy",
"java.lang.Object.wait",
"java.lang.Thread.exit",
"java.lang.Thread.yield",
"java.lang.ThreadGroup.remove",
"java.lang.ThreadGroup.threadTerminated",
"nsk.stress.strace.strace003Thread.run",
"nsk.stress.strace.strace003Thread.recursiveMethod"
};
static volatile boolean isLocked = false;
static PrintStream out;
static long waitTime = 2;
static Object waitStart = new Object();
static strace003Thread[] threads;
static StackTraceElement[][] snapshots = new StackTraceElement[THRD_COUNT][];
static Log log;
volatile int achivedCount = 0;
public static void main(String[] args) {
out = System.out;
int exitCode = run(args);
System.exit(exitCode + 95);
}
public static int run(String[] args) {
ArgumentParser argHandler = new ArgumentParser(args);
log = new Log(out, argHandler);
waitTime = argHandler.getWaitTime() * 60000;
strace003 test = new strace003();
boolean res = true;
for (int j = 0; j < REPEAT_COUNT; j++) {
test.startThreads();
if (!test.makeSnapshot(j + 1)) res = false;
display("waiting for threads finished\n");
test.finishThreads();
}
if (!res) {
complain("***>>>Test failed<<<***");
return 2;
}
return 0;
}
void startThreads() {
threads = new strace003Thread[THRD_COUNT];
achivedCount = 0;
String tmp_name;
for (int i = 0; i < THRD_COUNT; i++) {
tmp_name = "strace003Thread" + Integer.toString(i);
threads[i] = new strace003Thread(this, tmp_name);
}
for (int i = 0; i < THRD_COUNT; i++) {
threads[i].start();
}
waitFor("all threads started ...");
synchronized (waitStart) {
isLocked = true;
waitStart.notifyAll();
}
try {
Thread.yield();
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
void waitFor(String msg) {
if (msg.length() > 0)
display("waiting for " + msg);
while (achivedCount < THRD_COUNT) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
achivedCount = 0;
}
boolean makeSnapshot(int repeat_number) {
for (int i = 0; i < threads.length; i++) {
snapshots[i] = threads[i].getStackTrace();
}
return checkTraces(repeat_number);
}
boolean checkTraces(int repeat_number) {
StackTraceElement[] elements;
boolean res = true;
display(">>> snapshot " + repeat_number);
int expectedCount = DEPTH + 1;
for (int i = 0; i < threads.length; i++) {
elements = snapshots[i];
if (elements == null)
continue;
if (elements.length == 0)
continue;
if (elements.length > 0) {
display("\tchecking " + threads[i].getName()
+ "(trace elements: " + elements.length + ")");
}
if (elements.length > expectedCount) {
complain(threads[i].getName() + ">Contains more then " +
+expectedCount + " elements");
}
for (int j = 0; j < elements.length; j++) {
if (!checkElement(elements[j])) {
complain(threads[i].getName() + ">Unexpected method name: "
+ elements[j].getMethodName());
complain("\tat " + j + " position");
if (elements[j].isNativeMethod()) {
complain("\tline number: (native method)");
complain("\tclass name: " + elements[j].getClassName());
} else {
complain("\tline number: " + elements[j].getLineNumber());
complain("\tclass name: " + elements[j].getClassName());
complain("\tfile name: " + elements[j].getFileName());
}
res = false;
}
}
}
return res;
}
boolean checkElement(StackTraceElement element) {
String name = element.getClassName() + "." + element.getMethodName();
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
if (EXPECTED_METHODS[i].compareTo(name) == 0)
return true;
}
return false;
}
void finishThreads() {
try {
for (int i = 0; i < threads.length; i++) {
if (threads[i].isAlive())
threads[i].join(waitTime / THRD_COUNT);
}
} catch (InterruptedException e) {
complain("" + e);
}
isLocked = false;
}
static void display(String message) {
log.display(message);
}
static void complain(String message) {
log.complain(message);
}
}
class strace003Thread extends Thread {
private int currentDepth = 0;
strace003 test;
static {
try {
System.loadLibrary("strace003");
} catch (UnsatisfiedLinkError e) {
System.err.println("Could not load strace003 library");
System.err.println("java.library.path:"
+ System.getProperty("java.library.path"));
throw e;
}
}
strace003Thread(strace003 test, String name) {
this.test = test;
setName(name);
}
public void run() {
recursiveMethod();
}
native void recursiveMethod();
}

View File

@ -0,0 +1,94 @@
/*
* 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 <stdio.h>
#include "nsk_strace.h"
#ifdef __cplusplus
extern "C" {
#endif
static const char *Stest_cn="nsk/stress/strace/strace004";
static const char *Slongparam="(J)V";
JNIEXPORT void JNICALL
Java_nsk_stress_strace_strace004Thread_recursiveMethod(JNIEnv *env, jobject obj)
{
jfieldID field;
jmethodID method;
jint currDepth;
jclass testClass, threadClass, objClass;
jint maxDepth;
jboolean isLocked;
jint achivedCount;
jobject testField, waitStart;
FIND_CLASS(testClass, Stest_cn);
FIND_CLASS(objClass, "java/lang/Object");
GET_OBJECT_CLASS(threadClass, obj);
/* currDepth++ */
GET_INT_FIELD(currDepth, obj, threadClass, "currentDepth");
currDepth++;
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
if (currDepth == 1)
{
GET_OBJ_FIELD(testField, obj, threadClass, "test",
"Lnsk/stress/strace/strace004;");
GET_STATIC_OBJ_FIELD(waitStart, testClass, "waitStart",
"Ljava/lang/Object;");
MONITOR_ENTER(testField);
GET_INT_FIELD(achivedCount, testField, testClass, "achivedCount");
achivedCount++;
SET_INT_FIELD(testField, testClass, "achivedCount", achivedCount);
MONITOR_EXIT(testField);
GET_STATIC_BOOL_FIELD(isLocked, testClass, "isLocked");
while (isLocked != JNI_TRUE)
{
MONITOR_ENTER(waitStart);
CALL_VOID(waitStart, objClass, "wait", Slongparam, 1LL);
MONITOR_EXIT(waitStart);
GET_STATIC_BOOL_FIELD(isLocked, testClass, "isLocked");
}
}
GET_STATIC_INT_FIELD(maxDepth, testClass, "DEPTH");
if (maxDepth - currDepth > 0)
{
CALL_STATIC_VOID_NOPARAM(threadClass, "yield");
CALL_VOID_NOPARAM(obj, threadClass, "recursiveMethod");
}
currDepth--;
GET_OBJECT_CLASS(threadClass, obj);
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,321 @@
/*
* 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/strace004.
* VM testbase keywords: [stress, strace]
* VM testbase readme:
* DESCRIPTION
* The test checks up java.lang.Thread.getAllStackTraces() method for many
* threads, that recursively invoke a native method in running mode
* ("alive" stack).
* The test fails if:
* - amount of stack trace elements is more than depth of recursion plus
* four elements corresponding to invocations of Thread.run(), Thread.wait(),
* Thread.exit(), Thread.yield() and ThreadGroup.remove() methods;
* - there is at least one element corresponding to invocation of unexpected
* method.
* This test is almost the same as nsk.stress.strace.strace003 except for
* checking is performed for java.lang.Thread.getAllStackTraces() method.
* COMMENTS
* java.lang.Thread.getAllStackTraces() is too slow method. So it is not successed
* to catch an alive thread during execution of this method for the first snapshot
* and it is needed to check on a promoted build due to the below assertion.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* waiting for all threads started ...
* >>> snapshot 1
* waiting for threads finished
* # To suppress the following error report, specify this argument
* # after -XX: or in .hotspotrc: SuppressErrorAt=/jniHandles.hpp:157
* #
* # HotSpot Virtual Machine Error, assertion failure
* # Please report this error at
* # http://java.sun.com/cgi-bin/bugreport.cgi
* #
* # Java VM: Java HotSpot(TM) Client VM (1.4.1-internal-debug mixed mode)
* #
* # assert(result != ((oop)::badJNIHandleVal), "Pointing to zapped jni handle area")
* #
* # Error ID: src/share/vm/runtime/jniHandles.hpp, 157 [ Patched ]
* #
* # Problematic Thread: prio=5 tid=0x001976e0 nid=0x96 runnable
* #
* Heap at VM Abort:
* Heap
* def new generation total 2112K, used 455K [0xf1800000, 0xf1a20000, 0xf1f10000)
* eden space 2048K, 22% used [0xf1800000, 0xf1871f60, 0xf1a00000)
* from space 64K, 0% used [0xf1a00000, 0xf1a00000, 0xf1a10000)
* to space 64K, 0% used [0xf1a10000, 0xf1a10000, 0xf1a20000)
* tenured generation total 1408K, used 0K [0xf1f10000, 0xf2070000, 0xf5800000)
* the space 1408K, 0% used [0xf1f10000, 0xf1f10000, 0xf1f10200, 0xf2070000)
* compacting perm gen total 4096K, used 1025K [0xf5800000, 0xf5c00000, 0xf9800000)
* the space 4096K, 25% used [0xf5800000, 0xf5900660, 0xf5900800, 0xf5c00000)
* Dumping core....
* Abort
* Finished at: Fri Apr 25 18:01:37 NSK 2003
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native nsk.stress.strace.strace004
*/
package nsk.stress.strace;
import nsk.share.ArgumentParser;
import nsk.share.Log;
import java.io.PrintStream;
import java.util.Map;
/**
* The test check up <code>java.lang.Thread.getAllStackTraces()</code> method for many
* threads, that recursively invoke a native method in running mode ("alive" stack).
* <p>
* <p>The test creates <code>THRD_COUNT</code> instances of <code>strace004Thread</code>
* 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 <code>EXPECTED_METHODS</code> array.</p>
* <p>These checking are performed <code>REPEAT_COUNT</code> times.</p>
*/
public class strace004 {
static final int DEPTH = 100;
static final int THRD_COUNT = 100;
static final int REPEAT_COUNT = 10;
static final String[] EXPECTED_METHODS = {
"java.lang.System.arraycopy",
"java.lang.Object.wait",
"java.lang.Thread.exit",
"java.lang.Thread.yield",
"java.lang.ThreadGroup.remove",
"java.lang.ThreadGroup.threadTerminated",
"nsk.stress.strace.strace004Thread.run",
"nsk.stress.strace.strace004Thread.recursiveMethod"
};
static volatile boolean isLocked = false;
static PrintStream out;
static long waitTime = 2;
static Object waitStart = new Object();
static strace004Thread[] threads;
static StackTraceElement[][] snapshots = new StackTraceElement[THRD_COUNT][];
static Log log;
volatile int achivedCount = 0;
public static void main(String[] args) {
out = System.out;
int exitCode = run(args);
System.exit(exitCode + 95);
}
public static int run(String[] args) {
ArgumentParser argHandler = new ArgumentParser(args);
log = new Log(out, argHandler);
waitTime = argHandler.getWaitTime() * 60000;
strace004 test = new strace004();
boolean res = true;
for (int j = 0; j < REPEAT_COUNT; j++) {
test.startThreads();
if (!test.makeSnapshot(j + 1)) res = false;
display("waiting for threads finished\n");
test.finishThreads();
}
if (!res) {
complain("***>>>Test failed<<<***");
return 2;
}
return 0;
}
void startThreads() {
threads = new strace004Thread[THRD_COUNT];
achivedCount = 0;
String tmp_name;
for (int i = 0; i < THRD_COUNT; i++) {
tmp_name = "strace004Thread" + Integer.toString(i);
threads[i] = new strace004Thread(this, tmp_name);
}
for (int i = 0; i < THRD_COUNT; i++) {
threads[i].start();
}
waitFor("all threads started ...");
synchronized (waitStart) {
isLocked = true;
waitStart.notifyAll();
}
try {
Thread.yield();
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
void waitFor(String msg) {
if (msg.length() > 0)
display("waiting for " + msg);
while (achivedCount < THRD_COUNT) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
achivedCount = 0;
}
boolean makeSnapshot(int repeat_number) {
Map traces = Thread.getAllStackTraces();
for (int i = 0; i < threads.length; i++) {
snapshots[i] = (StackTraceElement[]) traces.get(threads[i]);
}
return checkTraces(repeat_number);
}
boolean checkTraces(int repeat_number) {
StackTraceElement[] elements;
boolean res = true;
display(">>> snapshot " + repeat_number);
int expectedCount = DEPTH + 1;
for (int i = 0; i < threads.length; i++) {
elements = snapshots[i];
if (elements == null)
continue;
if (elements.length == 0)
continue;
if (elements.length > 3) {
display("\tchecking " + threads[i].getName()
+ "(trace elements: " + elements.length + ")");
}
if (elements.length > expectedCount) {
complain(threads[i].getName() + ">Contains more then " +
+expectedCount + " elements");
}
for (int j = 0; j < elements.length; j++) {
if (!checkElement(elements[j])) {
complain(threads[i].getName() + ">Unexpected method name: "
+ elements[j].getMethodName());
complain("\tat " + j + " position");
if (elements[j].isNativeMethod()) {
complain("\tline number: (native method)");
complain("\tclass name: " + elements[j].getClassName());
} else {
complain("\tline number: " + elements[j].getLineNumber());
complain("\tclass name: " + elements[j].getClassName());
complain("\tfile name: " + elements[j].getFileName());
}
res = false;
}
}
}
return res;
}
boolean checkElement(StackTraceElement element) {
String name = element.getClassName() + "." + element.getMethodName();
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
if (EXPECTED_METHODS[i].compareTo(name) == 0)
return true;
}
return false;
}
void finishThreads() {
try {
for (int i = 0; i < threads.length; i++) {
if (threads[i].isAlive())
threads[i].join(waitTime / THRD_COUNT);
}
} catch (InterruptedException e) {
complain("" + e);
}
isLocked = false;
}
static void display(String message) {
log.display(message);
}
static void complain(String message) {
log.complain(message);
}
}
class strace004Thread extends Thread {
private int currentDepth = 0;
strace004 test;
static {
try {
System.loadLibrary("strace004");
} catch (UnsatisfiedLinkError e) {
System.err.println("Could not load strace004 library");
System.err.println("java.library.path:"
+ System.getProperty("java.library.path"));
throw e;
}
}
strace004Thread(strace004 test, String name) {
this.test = test;
setName(name);
}
public void run() {
recursiveMethod();
}
native void recursiveMethod();
}

View File

@ -0,0 +1,107 @@
/*
* 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 <stdio.h>
#include "nsk_strace.h"
#include "nsk_tools.h"
#ifdef __cplusplus
extern "C" {
#endif
static const char *Stest_cn="nsk/stress/strace/strace005";
static jclass stackOverflowErrorClass;
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION) != JNI_OK) {
printf("%s:%d: Failed to call GetEnv\n", __FILE__, __LINE__);
return 0;
}
FIND_CLASS(stackOverflowErrorClass, "java/lang/StackOverflowError");
if ((stackOverflowErrorClass = (*env)->NewGlobalRef(env, stackOverflowErrorClass)) == NULL) {
printf("Can't create global ref for stack overflow class\n");
return 0;
}
return JNI_VERSION;
}
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *vm, void *reserved)
{
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION) != JNI_OK) {
if (stackOverflowErrorClass != NULL) {
(*env)->DeleteGlobalRef(env, stackOverflowErrorClass);
}
} else {
printf("%s:%d: Failed to call GetEnv\n", __FILE__, __LINE__);
}
}
JNIEXPORT void JNICALL
Java_nsk_stress_strace_strace005Thread_recursiveMethod2(JNIEnv *env, jobject obj)
{
jfieldID field;
jmethodID method;
jint currDepth;
jclass testClass, threadClass;
jint maxDepth;
FIND_CLASS(testClass, Stest_cn);
GET_OBJECT_CLASS(threadClass, obj);
GET_STATIC_INT_FIELD(maxDepth, testClass, "DEPTH");
/* currDepth++ */
GET_INT_FIELD(currDepth, obj, threadClass, "currentDepth");
currDepth++;
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
if (maxDepth - currDepth > 0)
{
GET_STATIC_METHOD_ID(method, threadClass, "yield", "()V");
NSK_CPP_STUB3(CallStaticVoidMethod, env, threadClass, method);
EXCEPTION_CHECK(stackOverflowErrorClass, currDepth);
GET_METHOD_ID(method, threadClass, "recursiveMethod1", "()V");
NSK_CPP_STUB3(CallVoidMethod, env, obj, method);
EXCEPTION_CHECK(stackOverflowErrorClass, currDepth);
}
currDepth--;
GET_OBJECT_CLASS(threadClass, obj);
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,401 @@
/*
* 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/strace005.
* VM testbase keywords: [stress, strace]
* VM testbase readme:
* DESCRIPTION
* The test checks up java.lang.Thread.getStackTrace() method for many threads,
* that recursively invoke pure java and native methods by turns in running
* mode ("alive" stack).
* The test fails if:
* - amount of stack trace elements is more than depth of recursion plus
* four elements corresponding to invocations of Thread.run(), Thread.wait(),
* Thread.exit(), Thread.yield() and ThreadGroup.remove() methods;
* - there is at least one element corresponding to invocation of unexpected
* method.
* This test is almost the same as nsk.stress.strace.strace001 and
* nsk.stress.strace.strace003 except for the recursive methods are
* pure java and native one.
* COMMENTS
* Below assertion is revealed on engineer's build. It is needed to check
* on a promoted build.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* waiting for all threads started ...
* Unexpected Signal : 11 occurred at PC=0xFDBB7820
* Function=[Unknown. Nearest: SUNWprivate_1.1+0x3B7820]
* Library=java/vitp/jdk/4593133/solaris-sparc/jre/lib/sparc/client/libjvm.so
* Current Java thread:
* at nsk.stress.strace.strace005Thread.recursiveMethod2(Native Method)
* at nsk.stress.strace.strace005Thread.recursiveMethod1(strace005.java:285)
* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
* at nsk.stress.strace.strace005Thread.recursiveMethod2(Native Method)
* at nsk.stress.strace.strace005Thread.recursiveMethod1(strace005.java:285)
* at nsk.stress.strace.strace005Thread.recursiveMethod2(Native Method)
* Dynamic libraries:
* 0x10000 jdk/4593133/solaris-sparc/bin/java
* 0xff350000 /usr/lib/libthread.so.1
* 0xff390000 /usr/lib/libdl.so.1
* 0xff200000 /usr/lib/libc.so.1
* 0xff330000 /usr/platform/SUNW,Ultra-60/lib/libc_psr.so.1
* 0xfd800000 java/vitp/jdk/4593133/solaris-sparc/jre/lib/sparc/client/libjvm.so
* 0xff2d0000 /usr/lib/libCrun.so.1
* 0xff1d0000 /usr/lib/libsocket.so.1
* 0xff100000 /usr/lib/libnsl.so.1
* 0xff0d0000 /usr/lib/libm.so.1
* 0xff0b0000 /usr/lib/libsched.so.1
* 0xff300000 /usr/lib/libw.so.1
* 0xff090000 /usr/lib/libmp.so.2
* 0xff050000 java/vitp/jdk/4593133/solaris-sparc/jre/lib/sparc/native_threads/libhpi.so
* 0xfd7d0000 java/vitp/jdk/4593133/solaris-sparc/jre/lib/sparc/libverify.so
* 0xfd790000 java/vitp/jdk/4593133/solaris-sparc/jre/lib/sparc/libjava.so
* 0xfe7e0000 java/vitp/jdk/4593133/solaris-sparc/jre/lib/sparc/libzip.so
* 0xfc6e0000 java/vitp/tests/4593133/src/libstrace005.so
* Heap at VM Abort:
* Heap
* def new generation total 2112K, used 336K [0xf1800000, 0xf1a20000, 0xf1f10000)
* eden space 2048K, 16% used [0xf1800000, 0xf1854300, 0xf1a00000)
* from space 64K, 0% used [0xf1a00000, 0xf1a00000, 0xf1a10000)
* to space 64K, 0% used [0xf1a10000, 0xf1a10000, 0xf1a20000)
* tenured generation total 1408K, used 0K [0xf1f10000, 0xf2070000, 0xf5800000)
* the space 1408K, 0% used [0xf1f10000, 0xf1f10000, 0xf1f10200, 0xf2070000)
* compacting perm gen total 4096K, used 1020K [0xf5800000, 0xf5c00000, 0xf9800000)
* the space 4096K, 24% used [0xf5800000, 0xf58ff028, 0xf58ff200, 0xf5c00000)
* Local Time = Fri Apr 25 18:09:16 2003
* Elapsed Time = 13
* #
* # HotSpot Virtual Machine Error : 11
* # Error ID : src/share/vm/runtime/os.cpp, 753 [ Patched ]
* # Please report this error at
* # http://java.sun.com/cgi-bin/bugreport.cgi
* #
* # Java VM: Java HotSpot(TM) Client VM (1.4.1-internal-debug mixed mode)
* #
* # An error report file has been saved as hs_err_pid16847.log.
* # Please refer to the file for further information.
* #
* Dumping core....
* Abort
* Finished at: Fri Apr 25 18:09:17 NSK 2003
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native nsk.stress.strace.strace005
*/
package nsk.stress.strace;
import nsk.share.ArgumentParser;
import nsk.share.Failure;
import nsk.share.Log;
import java.io.PrintStream;
/**
* The test checks up <code>java.lang.Thread.getStackTrace()</code> method for many threads,
* that recursively invoke pure java and native methods by turns in running mode
* ("alive" stack).
* <p>
* <p>The test creates <code>THRD_COUNT</code> instances of <code>strace005Thread</code>
* 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 <code>EXPECTED_METHODS</code> array.</p>
* <p>These checking are performed <code>REPEAT_COUNT</code> times.</p>
*/
public class strace005 {
static final int DEPTH = 500;
static final int THRD_COUNT = 100;
static final int REPEAT_COUNT = 10;
static final String[] EXPECTED_METHODS = {
"java.lang.System.arraycopy",
"java.lang.Object.wait",
"java.lang.Thread.exit",
"java.lang.Thread.yield",
"java.lang.ThreadGroup.remove",
"java.lang.ThreadGroup.threadTerminated",
"nsk.stress.strace.strace005Thread.run",
"nsk.stress.strace.strace005Thread.recursiveMethod1",
"nsk.stress.strace.strace005Thread.recursiveMethod2"
};
static volatile boolean isLocked = false;
static PrintStream out;
static long waitTime = 2;
static Object waitStart = new Object();
static strace005Thread[] threads;
static StackTraceElement[][] snapshots = new StackTraceElement[THRD_COUNT][];
static Log log;
volatile int achivedCount = 0;
public static void main(String[] args) {
out = System.out;
int exitCode = run(args);
System.exit(exitCode + 95);
}
public static int run(String[] args) {
ArgumentParser argHandler = new ArgumentParser(args);
log = new Log(out, argHandler);
waitTime = argHandler.getWaitTime() * 60000;
strace005 test = new strace005();
boolean res = true;
for (int j = 0; j < REPEAT_COUNT; j++) {
test.startThreads();
if (!test.makeSnapshot(j + 1)) res = false;
display("waiting for threads finished\n");
test.finishThreads();
}
if (!res) {
complain("***>>>Test failed<<<***");
return 2;
}
return 0;
}
void startThreads() {
threads = new strace005Thread[THRD_COUNT];
achivedCount = 0;
String tmp_name;
for (int i = 0; i < THRD_COUNT; i++) {
tmp_name = "strace005Thread" + Integer.toString(i);
threads[i] = new strace005Thread(this, tmp_name);
// threads[i].setPriority(Thread.MIN_PRIORITY);
}
for (int i = 0; i < THRD_COUNT; i++) {
threads[i].start();
}
waitFor("all threads started ...");
synchronized (waitStart) {
isLocked = true;
waitStart.notifyAll();
}
try {
Thread.yield();
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
void waitFor(String msg) {
if (msg.length() > 0)
display("waiting for " + msg);
while (achivedCount < THRD_COUNT) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
achivedCount = 0;
}
boolean makeSnapshot(int repeat_number) {
// wait for native resolution completed (all threads have finished recursiveMethod2)
boolean isNativeResolved = false;
while (!isNativeResolved) {
try {
isNativeResolved = true;
for (int i = 0; i < threads.length; ++i)
if (!threads[i].isNativeResolved)
isNativeResolved = false;
Thread.sleep(20);
} catch (InterruptedException e) {
throw new Error(e);
}
}
for (int i = 0; i < threads.length; i++) {
snapshots[i] = threads[i].getStackTrace();
}
return checkTraces(repeat_number);
}
boolean checkTraces(int repeat_number) {
StackTraceElement[] elements;
boolean res = true;
display(">>> snapshot " + repeat_number);
int expectedCount = DEPTH + 1;
for (int i = 0; i < threads.length; i++) {
elements = snapshots[i];
if (elements == null || elements.length == 0)
continue;
if (elements.length > 0) {
display("\tchecking " + threads[i].getName()
+ "(trace elements: " + elements.length + ")");
}
if (elements.length > expectedCount) {
complain(threads[i].getName() + ">Contains more then " +
+expectedCount + " elements");
}
for (int j = 0; j < elements.length; j++) {
if (!checkElement(elements[j])) {
complain(threads[i].getName() + ">Unexpected method name: "
+ elements[j].getMethodName());
complain("\tat " + j + " position");
if (elements[j].isNativeMethod()) {
complain("\tline number: (native method)");
complain("\tclass name: " + elements[j].getClassName());
} else {
complain("\tline number: " + elements[j].getLineNumber());
complain("\tclass name: " + elements[j].getClassName());
complain("\tfile name: " + elements[j].getFileName());
}
res = false;
}
}
}
return res;
}
boolean checkElement(StackTraceElement element) {
String name = element.getClassName() + "." + element.getMethodName();
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
if (EXPECTED_METHODS[i].compareTo(name) == 0)
return true;
}
return false;
}
void finishThreads() {
try {
for (int i = 0; i < threads.length; i++) {
if (threads[i].isAlive())
threads[i].join(waitTime / THRD_COUNT);
}
} catch (InterruptedException e) {
complain("" + e);
}
isLocked = false;
}
static void display(String message) {
log.display(message);
}
static void complain(String message) {
log.complain(message);
}
}
/**
* The test creates many instances of <code>strace005Thread</code> 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();
}

View File

@ -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 <stdio.h>
#include "nsk_strace.h"
#ifdef __cplusplus
extern "C" {
#endif
static const char *Stest_cn="nsk/stress/strace/strace006";
static jclass testClass, threadClass;
static jint DEPTH;
static jclass stackOverflowErrorClass;
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION) != JNI_OK) {
printf("%s:%d: Failed to call GetEnv\n", __FILE__, __LINE__);
return 0;
}
FIND_CLASS(stackOverflowErrorClass, "java/lang/StackOverflowError");
if ((stackOverflowErrorClass = (*env)->NewGlobalRef(env, stackOverflowErrorClass)) == NULL) {
printf("Can't create global ref for stack overflow class\n");
return 0;
}
return JNI_VERSION;
}
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *vm, void *reserved)
{
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION) != JNI_OK) {
if (stackOverflowErrorClass != NULL) {
(*env)->DeleteGlobalRef(env, stackOverflowErrorClass);
}
} else {
printf("%s:%d: Failed to call GetEnv\n", __FILE__, __LINE__);
}
}
JNIEXPORT void JNICALL
Java_nsk_stress_strace_strace006Thread_recursiveMethod2(JNIEnv *env, jobject obj)
{
jfieldID field;
jmethodID method;
jint currDepth;
jclass testClass, threadClass;
jint maxDepth;
FIND_CLASS(testClass, Stest_cn);
GET_OBJECT_CLASS(threadClass, obj);
GET_STATIC_INT_FIELD(maxDepth, testClass, "DEPTH");
/* currDepth++ */
GET_INT_FIELD(currDepth, obj, threadClass, "currentDepth");
currDepth++;
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
if (maxDepth - currDepth > 0)
{
GET_STATIC_METHOD_ID(method, threadClass, "yield", "()V");
NSK_CPP_STUB3(CallStaticVoidMethod, env, threadClass, method);
EXCEPTION_CHECK(stackOverflowErrorClass, currDepth);
GET_METHOD_ID(method, threadClass, "recursiveMethod1", "()V");
NSK_CPP_STUB3(CallVoidMethod, env, obj, method);
EXCEPTION_CHECK(stackOverflowErrorClass, currDepth);
}
currDepth--;
GET_OBJECT_CLASS(threadClass, obj);
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,345 @@
/*
* 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/strace006.
* VM testbase keywords: [stress, strace]
* VM testbase readme:
* DESCRIPTION
* The test checks up java.lang.Thread.getAllStackTraces() method for many
* threads, that recursively invoke pure java and native methods by turns
* in running mode ("alive" stack).
* The test fails if:
* - amount of stack trace elements is more than depth of recursion plus
* four elements corresponding to invocations of Thread.run(), Thread.wait(),
* Thread.exit(), Thread.yield() and ThreadGroup.remove() methods;
* - there is at least one element corresponding to invocation of unexpected
* method.
* This test is almost the same as nsk.stress.strace.strace005 except for
* checking is performed for java.lang.Thread.getAllStackTraces() method.
* COMMENTS
* Similar assertion is thrown (see strace005.README).
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native nsk.stress.strace.strace006
*/
package nsk.stress.strace;
import nsk.share.ArgumentParser;
import nsk.share.Failure;
import nsk.share.Log;
import java.io.PrintStream;
import java.util.Map;
/**
* The test check up <code>java.lang.Thread.getStackTrace()</code> method for the pure
* java recursion.
* <p>The test creates <code>THRD_COUNT</code> instances of <code>strace006Thread</code>
* 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 <code>expectedMethod</code> array.</p>
* <p>These checking are performed <code>REPEAT_COUNT</code> times.</p>
*/
public class strace006 {
static final int DEPTH = 500;
static final int THRD_COUNT = 100;
static final int REPEAT_COUNT = 10;
static final String[] EXPECTED_METHODS = {
"java.lang.System.arraycopy",
"java.lang.Object.wait",
"java.lang.Thread.exit",
"java.lang.Thread.yield",
"java.lang.ThreadGroup.remove",
"java.lang.ThreadGroup.threadTerminated",
"nsk.stress.strace.strace006Thread.run",
"nsk.stress.strace.strace006Thread.recursiveMethod1",
"nsk.stress.strace.strace006Thread.recursiveMethod2"
};
static volatile boolean isLocked = false;
static PrintStream out;
static long waitTime = 2;
static Object waitStart = new Object();
static strace006Thread[] threads;
static StackTraceElement[][] snapshots = new StackTraceElement[THRD_COUNT][];
static Log log;
volatile int achivedCount = 0;
public static void main(String[] args) {
out = System.out;
int exitCode = run(args);
System.exit(exitCode + 95);
}
public static int run(String[] args) {
ArgumentParser argHandler = new ArgumentParser(args);
log = new Log(out, argHandler);
waitTime = argHandler.getWaitTime() * 60000;
strace006 test = new strace006();
boolean res = true;
for (int j = 0; j < REPEAT_COUNT; j++) {
test.startThreads();
if (!test.makeSnapshot(j + 1)) res = false;
display("waiting for threads finished\n");
test.finishThreads();
}
if (!res) {
complain("***>>>Test failed<<<***");
return 2;
}
return 0;
}
void startThreads() {
threads = new strace006Thread[THRD_COUNT];
achivedCount = 0;
String tmp_name;
for (int i = 0; i < THRD_COUNT; i++) {
tmp_name = "strace006Thread" + Integer.toString(i);
threads[i] = new strace006Thread(this, tmp_name);
// threads[i].setPriority(Thread.MIN_PRIORITY);
}
for (int i = 0; i < THRD_COUNT; i++) {
threads[i].start();
}
waitFor("all threads started ...");
synchronized (waitStart) {
isLocked = true;
waitStart.notifyAll();
}
try {
Thread.yield();
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
void waitFor(String msg) {
if (msg.length() > 0)
display("waiting for " + msg);
while (achivedCount < THRD_COUNT) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
achivedCount = 0;
}
boolean makeSnapshot(int repeat_number) {
// wait for native resolution completed (all threads have finished recursiveMethod2)
boolean isNativeResolved = false;
while (!isNativeResolved) {
try {
isNativeResolved = true;
for (int i = 0; i < threads.length; ++i)
if (!threads[i].isNativeResolved)
isNativeResolved = false;
Thread.sleep(20);
} catch (InterruptedException e) {
throw new Error(e);
}
}
Map traces = Thread.getAllStackTraces();
for (int i = 0; i < threads.length; i++) {
snapshots[i] = (StackTraceElement[]) traces.get(threads[i]);
}
return checkTraces(repeat_number);
}
boolean checkTraces(int repeat_number) {
StackTraceElement[] elements;
boolean res = true;
display(">>> snapshot " + repeat_number);
int expectedCount = DEPTH + 1;
for (int i = 0; i < threads.length; i++) {
elements = snapshots[i];
if (elements == null || elements.length == 0)
continue;
if (elements.length > 0) {
display("\tchecking " + threads[i].getName()
+ "(trace elements: " + elements.length + ")");
}
if (elements.length > expectedCount) {
complain(threads[i].getName() + ">Contains more then "
+ expectedCount + " elements");
}
for (int j = 0; j < elements.length; j++) {
if (!checkElement(elements[j])) {
complain(threads[i].getName() + ">Unexpected method name: "
+ elements[j].getMethodName());
complain("\tat " + j + " position");
if (elements[j].isNativeMethod()) {
complain("\tline number: (native method)");
complain("\tclass name: " + elements[j].getClassName());
} else {
complain("\tline number: " + elements[j].getLineNumber());
complain("\tclass name: " + elements[j].getClassName());
complain("\tfile name: " + elements[j].getFileName());
}
res = false;
}
}
}
return res;
}
boolean checkElement(StackTraceElement element) {
if (element.getClassName().equals("java.lang.ClassLoader"))
return true;
String name = element.getClassName() + "." + element.getMethodName();
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
if (EXPECTED_METHODS[i].compareTo(name) == 0)
return true;
}
return false;
}
void finishThreads() {
try {
for (int i = 0; i < threads.length; i++) {
if (threads[i].isAlive())
threads[i].join(waitTime / THRD_COUNT);
}
} catch (InterruptedException e) {
complain("" + e);
}
isLocked = false;
}
static void display(String message) {
log.display(message);
}
static void complain(String message) {
log.complain(message);
}
}
/**
* The test creates many instances of <code>strace006Thread</code> 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();
}

View File

@ -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 <code>THRD_COUNT</code> instances of <code>strace007Thread</code>,
* that recursively invoke a pure java method. After arriving at defined depth
* <code>DEPTH</code> of recursion, the test calls
* <code>java.lang.Thread.getStackTrace()</code> and
* <code>java.lang.Thread.getAllStackTraces()</code> methods and checks their results.
* <p>
* <p>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 <code>EXPECTED_METHODS</code> array.</p>
*/
public class strace007 {
static final int DEPTH = 500;
static final int THRD_COUNT = 100;
static final int SLEEP_TIME = 50;
static final String[] EXPECTED_METHODS = {
"java.lang.Thread.sleep",
"nsk.stress.strace.strace007Thread.run",
"nsk.stress.strace.strace007Thread.recursiveMethod"
};
static PrintStream out;
static long waitTime = 2;
static Object doSnapshot = new Object();
static volatile boolean isSnapshotDone = false;
static volatile int achivedCount = 0;
static Log log;
static strace007Thread[] threads;
public static void main(String[] args) {
out = System.out;
int exitCode = run(args);
System.exit(exitCode + 95);
}
public static int run(String[] args) {
ArgumentParser argHandler = new ArgumentParser(args);
log = new Log(out, argHandler);
waitTime = argHandler.getWaitTime() * 60000;
boolean res = true;
startThreads();
res = makeSnapshot();
finishThreads();
if (!res) {
complain("***>>>Test failed<<<***");
return 2;
}
display(">>>Test passed<<<");
return 0;
}
static void startThreads() {
threads = new strace007Thread[THRD_COUNT];
achivedCount = 0;
String tmp_name;
display("starting threads...");
for (int i = 0; i < THRD_COUNT; i++) {
tmp_name = "strace007Thread" + Integer.toString(i);
threads[i] = new strace007Thread(tmp_name);
threads[i].start();
}
display("waiting for the defined recursion depth ...");
while (achivedCount < THRD_COUNT) {
synchronized (doSnapshot) {
try {
doSnapshot.wait(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
}
}
static boolean makeSnapshot() {
display("making all threads snapshots...");
Map traces = Thread.getAllStackTraces();
int count = ((StackTraceElement[]) traces.get(threads[0])).length;
display("making snapshots of each thread...");
StackTraceElement[][] elements = new StackTraceElement[THRD_COUNT][];
for (int i = 0; i < THRD_COUNT; i++) {
elements[i] = threads[i].getStackTrace();
}
display("checking lengths of stack traces...");
StackTraceElement[] all;
for (int i = 1; i < THRD_COUNT; i++) {
all = (StackTraceElement[]) traces.get(threads[i]);
int k = all.length;
if (count - k > 2) {
complain("wrong lengths of stack traces:\n\t"
+ threads[0].getName() + ": " + count
+ "\t"
+ threads[i].getName() + ": " + k);
return false;
}
}
display("checking stack traces...");
boolean res = true;
for (int i = 0; i < THRD_COUNT; i++) {
all = (StackTraceElement[]) traces.get(threads[i]);
if (!checkTraces(threads[i].getName(), elements[i], all)) {
res = false;
}
}
return res;
}
static boolean checkTraces(String threadName, StackTraceElement[] threadSnap,
StackTraceElement[] allSnap) {
int checkedLength = threadSnap.length < allSnap.length ?
threadSnap.length : allSnap.length;
boolean res = true;
for (int j = 0; j < checkedLength; j++) {
if (!checkElement(threadSnap[j])) {
complain("Unexpected " + j + "-element:");
complain("\tmethod name: " + threadSnap[j].getMethodName());
complain("\tclass name: " + threadSnap[j].getClassName());
if (threadSnap[j].isNativeMethod()) {
complain("\tline number: (native method)");
} else {
complain("\tline number: " + threadSnap[j].getLineNumber());
complain("\tfile name: " + threadSnap[j].getFileName());
}
complain("");
res = false;
}
}
return res;
}
static boolean checkElement(StackTraceElement element) {
String name = element.getClassName() + "." + element.getMethodName();
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
if (EXPECTED_METHODS[i].compareTo(name) == 0)
return true;
}
return false;
}
static void finishThreads() {
isSnapshotDone = true;
try {
for (int i = 0; i < threads.length; i++) {
if (threads[i].isAlive()) {
display("waiting for finish " + threads[i].getName());
threads[i].join(waitTime);
}
}
} catch (InterruptedException e) {
complain("" + e);
}
isSnapshotDone = false;
}
static void display(String message) {
log.display(message);
}
static void complain(String message) {
log.complain(message);
}
}
class strace007Thread extends Thread {
private int currentDepth = 0;
static int[] arr = new int[1000];
strace007Thread(String name) {
setName(name);
}
public void run() {
try {
recursiveMethod(arr);
} catch (Throwable throwable) {
System.err.println("# ERROR: " + getName() + ": " + throwable);
System.exit(1);
}
}
void recursiveMethod(int[] arr) {
currentDepth++;
if (strace007.DEPTH - currentDepth > 0) {
recursiveMethod(arr);
}
if (strace007.DEPTH == currentDepth) {
synchronized (strace007.doSnapshot) {
strace007.achivedCount++;
strace007.doSnapshot.notify();
}
while (!strace007.isSnapshotDone) {
try {
sleep(strace007.SLEEP_TIME);
} catch (InterruptedException e) {
strace007.complain(getName() + "> " + e);
}
}
}
currentDepth--;
}
}

View File

@ -0,0 +1,92 @@
/*
* 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 <stdio.h>
#include "nsk_strace.h"
#ifdef __cplusplus
extern "C" {
#endif
static const char *Stest_cn="nsk/stress/strace/strace008";
JNIEXPORT void JNICALL
Java_nsk_stress_strace_strace008Thread_recursiveMethod(JNIEnv *env, jobject obj)
{
jfieldID field;
jmethodID method;
jint currDepth;
jclass testClass, threadClass;
jint maxDepth;
jboolean isDone;
jint achivedCount;
jobject doSnapshot;
jint sleepTime;
FIND_CLASS(testClass, Stest_cn);
GET_OBJECT_CLASS(threadClass, obj);
/* currDepth++ */
GET_INT_FIELD(currDepth, obj, threadClass, "currentDepth");
currDepth++;
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
GET_STATIC_INT_FIELD(maxDepth, testClass, "DEPTH");
GET_STATIC_INT_FIELD(sleepTime, testClass, "SLEEP_TIME");
if (maxDepth - currDepth > 0)
{
CALL_VOID_NOPARAM(obj, threadClass, "recursiveMethod");
}
if (maxDepth == currDepth)
{
GET_STATIC_OBJ_FIELD(doSnapshot, testClass, "doSnapshot",
"Ljava/lang/Object;");
MONITOR_ENTER(doSnapshot);
GET_STATIC_INT_FIELD(achivedCount, testClass, "achivedCount");
achivedCount++;
SET_STATIC_INT_FIELD(testClass, "achivedCount", achivedCount);
CALL_VOID_NOPARAM(doSnapshot, testClass, "notify");
MONITOR_EXIT(doSnapshot);
}
GET_STATIC_BOOL_FIELD(isDone, testClass, "isSnapshotDone");
while (!isDone)
{
CALL_STATIC_VOID(threadClass, "sleep", "(J)V", (jlong)sleepTime);
GET_STATIC_BOOL_FIELD(isDone, testClass, "isSnapshotDone");
}
currDepth--;
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,270 @@
/*
* 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/strace008.
* VM testbase keywords: [stress, quick, strace]
* VM testbase readme:
* DESCRIPTION
* The test runs many threads, that recursively invoke a native 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.
* This test is almost the same as nsk.stress.strace.strace007 except for
* the recursive method is a native one.
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm/native nsk.stress.strace.strace008
*/
package nsk.stress.strace;
import nsk.share.ArgumentParser;
import nsk.share.Log;
import java.io.PrintStream;
import java.util.Map;
/**
* The test runs <code>THRD_COUNT</code> instances of <code>strace008Thread</code>,
* that recursively invoke a native method. After arriving at defined depth
* <code>DEPTH</code> of recursion, the test calls
* <code>java.lang.Thread.getStackTrace()</code> and
* <code>java.lang.Thread.getAllStackTraces()</code> methods and checks their results.
* <p>
* 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 <code>EXPECTED_METHODS</code> array.</p>
*/
public class strace008 {
static final int DEPTH = 100;
static final int THRD_COUNT = 50;
static final int SLEEP_TIME = 50;
static final String NATIVE_LIB = "strace008";
static final String[] EXPECTED_METHODS = {
"java.lang.Thread.sleep",
"nsk.stress.strace.strace008Thread.run",
"nsk.stress.strace.strace008Thread.recursiveMethod"
};
static long waitTime = 2;
static Object doSnapshot = new Object();
static volatile boolean isSnapshotDone = false;
static volatile int achivedCount = 0;
static PrintStream out;
static Log log;
static strace008Thread[] threads;
public static void main(String[] args) {
out = System.out;
int exitCode = run(args);
System.exit(exitCode + 95);
}
public static int run(String[] args) {
ArgumentParser argHandler = new ArgumentParser(args);
log = new Log(out, argHandler);
waitTime = argHandler.getWaitTime() * 60000;
boolean res = true;
startThreads();
res = makeSnapshot();
finishThreads();
if (!res) {
complain("***>>>Test failed<<<***");
return 2;
}
display(">>>Test passed<<<");
return 0;
}
static void startThreads() {
threads = new strace008Thread[THRD_COUNT];
achivedCount = 0;
String tmp_name;
display("starting threads...");
for (int i = 0; i < THRD_COUNT; i++) {
tmp_name = "strace008Thread" + Integer.toString(i);
threads[i] = new strace008Thread(tmp_name);
threads[i].start();
}
display("waiting for the defined recursion depth ...");
while (achivedCount < THRD_COUNT) {
synchronized (doSnapshot) {
try {
doSnapshot.wait(1);
} catch (InterruptedException e) {
complain("" + e);
}
}
}
}
static boolean makeSnapshot() {
display("making all threads snapshots...");
Map traces = Thread.getAllStackTraces();
int count = ((StackTraceElement[]) traces.get(threads[0])).length;
display("making snapshots of each thread...");
StackTraceElement[][] elements = new StackTraceElement[THRD_COUNT][];
for (int i = 0; i < THRD_COUNT; i++) {
elements[i] = threads[i].getStackTrace();
}
display("checking lengths of stack traces...");
StackTraceElement[] all;
for (int i = 1; i < THRD_COUNT; i++) {
all = (StackTraceElement[]) traces.get(threads[i]);
int k = all.length;
if (count - k > 2) {
complain("wrong lengths of stack traces:\n\t"
+ threads[0].getName() + ": " + count
+ "\t"
+ threads[i].getName() + ": " + k);
return false;
}
}
display("checking stack traces...");
boolean res = true;
for (int i = 0; i < THRD_COUNT; i++) {
all = (StackTraceElement[]) traces.get(threads[i]);
if (!checkTraces(threads[i].getName(), elements[i], all)) {
res = false;
}
}
return res;
}
static boolean checkTraces(String threadName, StackTraceElement[] threadSnap,
StackTraceElement[] allSnap) {
int checkedLength = threadSnap.length < allSnap.length ?
threadSnap.length : allSnap.length;
boolean res = true;
for (int j = checkedLength; j < 0; j--) {
if (!checkElement(threadSnap[j])) {
complain("Unexpected " + j + "-element:");
complain("\tmethod name: " + threadSnap[j].getMethodName());
complain("\tclass name: " + threadSnap[j].getClassName());
if (threadSnap[j].isNativeMethod()) {
complain("\tline number: (native method)");
} else {
complain("\tline number: " + threadSnap[j].getLineNumber());
complain("\tfile name: " + threadSnap[j].getFileName());
}
complain("");
res = false;
}
}
return res;
}
static boolean checkElement(StackTraceElement element) {
String name = element.getClassName() + "." + element.getMethodName();
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
if (EXPECTED_METHODS[i].compareTo(name) == 0)
return true;
}
return false;
}
static void finishThreads() {
isSnapshotDone = true;
/* try {
for (int i=0; i<threads.length; i++) {
if (threads[i].isAlive()) {
display("waiting for finish " + threads[i].getName());
threads[i].join(waitTime);
}
}
} catch (InterruptedException e) {
display(e);
}
*/
isSnapshotDone = false;
}
static void display(String message) {
log.display(message);
}
static void complain(String message) {
log.complain(message);
}
}
class strace008Thread extends Thread {
private int currentDepth = 0;
static {
try {
System.loadLibrary(strace008.NATIVE_LIB);
} catch (UnsatisfiedLinkError e) {
System.err.println("Could not load strace008 library");
System.err.println("java.library.path:"
+ System.getProperty("java.library.path"));
throw e;
}
}
strace008Thread(String name) {
setName(name);
}
public void run() {
recursiveMethod();
}
native void recursiveMethod();
}

View File

@ -0,0 +1,64 @@
/*
* 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 <stdio.h>
#include "nsk_strace.h"
#ifdef __cplusplus
extern "C" {
#endif
static const char *Stest_cn="nsk/stress/strace/strace009";
JNIEXPORT void JNICALL
Java_nsk_stress_strace_strace009Thread_recursiveMethod2(JNIEnv *env, jobject obj)
{
jclass testClass, threadClass;
jint currDepth, maxDepth;
jmethodID method;
jfieldID field;
FIND_CLASS(testClass, Stest_cn);
GET_OBJECT_CLASS(threadClass, obj);
/* currDepth++ */
GET_INT_FIELD(currDepth, obj, threadClass, "currentDepth");
currDepth++;
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
GET_STATIC_INT_FIELD(maxDepth, testClass, "DEPTH");
if (maxDepth - currDepth > 0)
{
CALL_VOID_NOPARAM(obj, threadClass, "recursiveMethod1");
}
currDepth--;
GET_OBJECT_CLASS(threadClass, obj);
SET_INT_FIELD(obj, threadClass, "currentDepth", currDepth);
}
#ifdef __cplusplus
}
#endif

Some files were not shown because too many files have changed in this diff Show More