src/hotspot/share/runtime/thread.cpp
changeset 52302 912b79d983d9
parent 52297 99962c340e73
child 52341 2b58b8e1d28f
--- a/src/hotspot/share/runtime/thread.cpp	Fri Oct 26 08:23:52 2018 -0400
+++ b/src/hotspot/share/runtime/thread.cpp	Fri Oct 19 09:39:29 2018 +0200
@@ -338,32 +338,61 @@
 }
 
 void Thread::record_stack_base_and_size() {
+  // Note: at this point, Thread object is not yet initialized. Do not rely on
+  // any members being initialized. Do not rely on Thread::current() being set.
+  // If possible, refrain from doing anything which may crash or assert since
+  // quite probably those crash dumps will be useless.
   set_stack_base(os::current_stack_base());
   set_stack_size(os::current_stack_size());
-  // CR 7190089: on Solaris, primordial thread's stack is adjusted
-  // in initialize_thread(). Without the adjustment, stack size is
-  // incorrect if stack is set to unlimited (ulimit -s unlimited).
-  // So far, only Solaris has real implementation of initialize_thread().
-  //
-  // set up any platform-specific state.
-  os::initialize_thread(this);
+
+#ifdef SOLARIS
+  if (os::is_primordial_thread()) {
+    os::Solaris::correct_stack_boundaries_for_primordial_thread(this);
+  }
+#endif
 
   // Set stack limits after thread is initialized.
   if (is_Java_thread()) {
     ((JavaThread*) this)->set_stack_overflow_limit();
     ((JavaThread*) this)->set_reserved_stack_activation(stack_base());
   }
+}
+
 #if INCLUDE_NMT
-  // record thread's native stack, stack grows downward
+void Thread::register_thread_stack_with_NMT() {
   MemTracker::record_thread_stack(stack_end(), stack_size());
+}
 #endif // INCLUDE_NMT
+
+void Thread::call_run() {
+  // At this point, Thread object should be fully initialized and
+  // Thread::current() should be set.
+
+  register_thread_stack_with_NMT();
+
   log_debug(os, thread)("Thread " UINTX_FORMAT " stack dimensions: "
     PTR_FORMAT "-" PTR_FORMAT " (" SIZE_FORMAT "k).",
     os::current_thread_id(), p2i(stack_base() - stack_size()),
     p2i(stack_base()), stack_size()/1024);
+
+  // Invoke <ChildClass>::run()
+  this->run();
+  // Returned from <ChildClass>::run(). Thread finished.
+
+  // Note: at this point the thread object may already have deleted itself.
+  // So from here on do not dereference *this*.
+
+  // If a thread has not deleted itself ("delete this") as part of its
+  // termination sequence, we have to ensure thread-local-storage is
+  // cleared before we actually terminate. No threads should ever be
+  // deleted asynchronously with respect to their termination.
+  if (Thread::current_or_null_safe() != NULL) {
+    assert(Thread::current_or_null_safe() == this, "current thread is wrong");
+    Thread::clear_thread_current();
+  }
+
 }
 
-
 Thread::~Thread() {
   JFR_ONLY(Jfr::on_thread_destruct(this);)
 
@@ -417,17 +446,12 @@
   // clear Thread::current if thread is deleting itself.
   // Needed to ensure JNI correctly detects non-attached threads.
   if (this == Thread::current()) {
-    clear_thread_current();
+    Thread::clear_thread_current();
   }
 
   CHECK_UNHANDLED_OOPS_ONLY(if (CheckUnhandledOops) delete unhandled_oops();)
 }
 
-// NOTE: dummy function for assertion purpose.
-void Thread::run() {
-  ShouldNotReachHere();
-}
-
 #ifdef ASSERT
 // A JavaThread is considered "dangling" if it is not the current
 // thread, has been added the Threads list, the system is not at a
@@ -1374,7 +1398,6 @@
 void WatcherThread::run() {
   assert(this == watcher_thread(), "just checking");
 
-  this->record_stack_base_and_size();
   this->set_native_thread_name(this->name());
   this->set_active_handles(JNIHandleBlock::allocate_block());
   while (true) {
@@ -1740,9 +1763,6 @@
   // used to test validity of stack trace backs
   this->record_base_of_stack_pointer();
 
-  // Record real stack base and size.
-  this->record_stack_base_and_size();
-
   this->create_stack_guard_pages();
 
   this->cache_global_variables();
@@ -3709,6 +3729,7 @@
   main_thread->initialize_thread_current();
   // must do this before set_active_handles
   main_thread->record_stack_base_and_size();
+  main_thread->register_thread_stack_with_NMT();
   main_thread->set_active_handles(JNIHandleBlock::allocate_block());
 
   if (!main_thread->set_as_starting_thread()) {