--- old/src/hotspot/share/runtime/thread.hpp 2018-12-27 19:46:59.485909870 -0500 +++ new/src/hotspot/share/runtime/thread.hpp 2018-12-27 19:46:57.765811917 -0500 @@ -110,6 +110,27 @@ // This means !t->is_Java_thread() iff t is a NonJavaThread, or t is // a partially constructed/destroyed Thread. +// Thread execution sequence and actions: +// All threads: +// - thread_native_entry // per-OS native entry point +// - stack initialization +// - other OS-level initialization (signal masks etc) +// - handshake with creating thread (if not started suspended) +// - this->call_run() // common shared entry point +// - shared common initialization +// - this->pre_run() // virtual per-thread-type initialization +// - this->run() // virtual per-thread-type "main" logic +// - shared common tear-down +// - this->post_run() // virtual per-thread-type tear-down +// - // 'this' no longer referenceable +// - OS-level tear-down (minimal) +// - final logging +// +// For JavaThread: +// - this->run() // virtual but not normally overridden +// - this->thread_main_inner() // extra call level to ensure correct stack calculations +// - this->entry_point() // set differently for each kind of JavaThread + class Thread: public ThreadShadow { friend class VMStructs; friend class JVMCIVMStructs; @@ -120,7 +141,6 @@ static THREAD_LOCAL_DECL Thread* _thr_current; #endif - private: // Thread local data area available to the GC. The internal // structure and contents of this data area is GC-specific. // Only GC and GC barrier code should access this data area. @@ -142,6 +162,9 @@ // const char* _exception_file; // file information for exception (debugging only) // int _exception_line; // line information for exception (debugging only) protected: + + DEBUG_ONLY(static Thread* _starting_thread;) + // Support for forcing alignment of thread objects for biased locking void* _real_malloc_address; @@ -418,6 +441,21 @@ protected: // To be implemented by children. virtual void run() = 0; + virtual void pre_run() = 0; + virtual void post_run() = 0; // Note: Thread must not be deleted prior to calling this! + +#ifdef ASSERT + enum RunState { + PRE_CALL_RUN, + CALL_RUN, + PRE_RUN, + RUN, + POST_RUN + // POST_CALL_RUN - can't define this one as 'this' may be deleted when we want to set it + }; + RunState _run_state; // for lifecycle checks +#endif + public: // invokes ::run(), with common preparations and cleanups. @@ -796,6 +834,13 @@ class List; static List _the_list; + void add_to_the_list(); + void remove_from_the_list(); + + protected: + virtual void pre_run(); + virtual void post_run(); + public: NonJavaThread(); ~NonJavaThread(); @@ -803,12 +848,12 @@ class Iterator; }; -// Provides iteration over the list of NonJavaThreads. Because list -// management occurs in the NonJavaThread constructor and destructor, -// entries in the list may not be fully constructed instances of a -// derived class. Threads created after an iterator is constructed -// will not be visited by the iterator. The scope of an iterator is a -// critical section; there must be no safepoint checks in that scope. +// Provides iteration over the list of NonJavaThreads. +// List addition occurs in pre_run(), and removal occurs in post_run(), +// so that only live fully-initialized threads can be found in the list. +// Threads created after an iterator is constructed will not be visited +// by the iterator. The scope of an iterator is a critical section; there +// must be no safepoint checks in that scope. class NonJavaThread::Iterator : public StackObj { uint _protect_enter; NonJavaThread* _current; @@ -844,7 +889,6 @@ ~NamedThread(); // May only be called once per thread. void set_name(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); - void initialize_named_thread(); virtual bool is_Named_thread() const { return true; } virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; } JavaThread *processed_thread() { return _processed_thread; } @@ -875,7 +919,7 @@ // A single WatcherThread is used for simulating timer interrupts. class WatcherThread: public NonJavaThread { friend class VMStructs; - public: + protected: virtual void run(); private: @@ -1832,9 +1876,9 @@ void print_name_on_error(outputStream* st, char* buf, int buflen) const; void verify(); const char* get_thread_name() const; - private: + protected: // factor out low-level mechanics for use in both normal and error cases - const char* get_thread_name_string(char* buf = NULL, int buflen = 0) const; + virtual const char* get_thread_name_string(char* buf = NULL, int buflen = 0) const; public: const char* get_threadgroup_name() const; const char* get_parent_name() const; @@ -1887,9 +1931,12 @@ inline CompilerThread* as_CompilerThread(); - public: + protected: + virtual void pre_run(); virtual void run(); void thread_main_inner(); + virtual void post_run(); + private: GrowableArray* _array_for_gc;