--- old/src/hotspot/share/runtime/threadSMR.cpp Tue Nov 21 14:45:02 2017 +++ new/src/hotspot/share/runtime/threadSMR.cpp Tue Nov 21 14:45:01 2017 @@ -29,7 +29,7 @@ #include "services/threadService.hpp" // 'entries + 1' so we always have at least one entry. -ThreadsList::ThreadsList(int entries) : _length(entries), _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtGC)), _next_list(NULL) { +ThreadsList::ThreadsList(int entries) : _length(entries), _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread)), _next_list(NULL) { *(JavaThread**)(_threads + entries) = NULL; // Make sure the extra entry is NULL. } --- old/src/hotspot/share/runtime/threadSMR.hpp Tue Nov 21 14:45:05 2017 +++ new/src/hotspot/share/runtime/threadSMR.hpp Tue Nov 21 14:45:04 2017 @@ -28,6 +28,55 @@ #include "memory/allocation.hpp" #include "runtime/timer.hpp" +// Thread Safe Memory Reclaimation (Thread-SMR) support. +// +// ThreadsListHandles are used to safely perform operations on one or more +// threads without the risk of the thread or threads exiting during the +// operation. It is no longer necessary to hold the Threads_lock to safely +// perform an operation on a target thread. +// +// There are several different ways to refer to java.lang.Thread objects +// so we have a few ways to get a protected JavaThread *: +// +// JNI jobject example: +// jobject jthread = ...; +// : +// ThreadsListHandle tlh; +// JavaThread* jt = NULL; +// bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &jt, NULL); +// if (is_alive) { +// : // do stuff with 'jt'... +// } +// +// JVM/TI jthread example: +// jthread thread = ...; +// : +// JavaThread* jt = NULL; +// ThreadsListHandle tlh; +// jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &jt, NULL); +// if (err != JVMTI_ERROR_NONE) { +// return err; +// } +// : // do stuff with 'jt'... +// +// JVM/TI oop example (this one should be very rare): +// oop thread_obj = ...; +// : +// JavaThread *jt = NULL; +// ThreadsListHandle tlh; +// jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &jt); +// if (err != JVMTI_ERROR_NONE) { +// return err; +// } +// : // do stuff with 'jt'... +// +// A JavaThread * that is included in the ThreadsList that is held by +// a ThreadsListHandle is protected as long as the ThreadsListHandle +// remains in scope. The target JavaThread * may have logically exited, +// but that target JavaThread * will not be deleted until it is no +// longer protected by a ThreadsListHandle. + + // A fast list of JavaThreads. // class ThreadsList : public CHeapObj { @@ -183,7 +232,7 @@ uint _index; public: - JavaThreadIteratorWithHandle() : _tlh(), _index(0) {} + JavaThreadIteratorWithHandle() : _index(0) {} uint length() const { return _tlh.length(); --- old/test/hotspot/jtreg/runtime/ErrorHandling/ErrorHandler.java Tue Nov 21 14:45:08 2017 +++ new/test/hotspot/jtreg/runtime/ErrorHandling/ErrorHandler.java Tue Nov 21 14:45:07 2017 @@ -23,6 +23,7 @@ /* * @test + * @requires (vm.debug == true) * @bug 6888954 * @bug 8015884 * @summary Exercise HotSpot error handling code by invoking java with @@ -39,6 +40,7 @@ public class ErrorHandler { public static OutputAnalyzer runTest(int testcase) throws Exception { + // The -XX:ErrorHandlerTest=N option requires debug bits. return new OutputAnalyzer( ProcessTools.createJavaProcessBuilder( "-XX:-TransmitErrorReport", "-XX:-CreateCoredumpOnCrash", "-XX:ErrorHandlerTest=" + testcase) @@ -46,10 +48,6 @@ } public static void main(String[] args) throws Exception { - // Test is only applicable for debug builds - if (!Platform.isDebugBuild()) { - return; - } // Keep this in sync with hotspot/src/share/vm/utilities/debug.cpp int i = 1; String[] strings = { --- old/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java Tue Nov 21 14:45:11 2017 +++ new/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java Tue Nov 21 14:45:10 2017 @@ -33,6 +33,7 @@ /* * @test + * @requires (vm.debug == true) * @bug 8167108 * @summary Nested ThreadsListHandle info should be in error handling output. * @modules java.base/jdk.internal.misc @@ -47,11 +48,7 @@ public class NestedThreadsListHandleInErrorHandlingTest { public static void main(String[] args) throws Exception { - if (!Platform.isDebugBuild()) { - // -XX:ErrorHandlerTest=N option requires debug bits. - return; - } - + // The -XX:ErrorHandlerTest=N option requires debug bits. ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UnlockDiagnosticVMOptions", "-Xmx100M", --- old/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java Tue Nov 21 14:45:14 2017 +++ new/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java Tue Nov 21 14:45:13 2017 @@ -33,6 +33,7 @@ /* * @test + * @requires (vm.debug == true) * @bug 8167108 * @summary ThreadsListHandle info should be in error handling output. * @modules java.base/jdk.internal.misc @@ -47,11 +48,7 @@ public class ThreadsListHandleInErrorHandlingTest { public static void main(String[] args) throws Exception { - if (!Platform.isDebugBuild()) { - // -XX:ErrorHandlerTest=N option requires debug bits. - return; - } - + // The -XX:ErrorHandlerTest=N option requires debug bits. ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UnlockDiagnosticVMOptions", "-Xmx100M",