--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Oct 18 13:09:47 2012 -0400
+++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Oct 19 21:40:07 2012 -0400
@@ -323,12 +323,10 @@
os::initialize_thread(this);
#if INCLUDE_NMT
- // record thread's native stack, stack grows downward
- if (MemTracker::is_on()) {
- address stack_low_addr = stack_base() - stack_size();
- MemTracker::record_thread_stack(stack_low_addr, stack_size(), this,
+ // record thread's native stack, stack grows downward
+ address stack_low_addr = stack_base() - stack_size();
+ MemTracker::record_thread_stack(stack_low_addr, stack_size(), this,
CURRENT_PC);
- }
#endif // INCLUDE_NMT
}
@@ -345,6 +343,9 @@
if (_stack_base != NULL) {
address low_stack_addr = stack_base() - stack_size();
MemTracker::release_thread_stack(low_stack_addr, stack_size(), this);
+#ifdef ASSERT
+ set_stack_base(NULL);
+#endif
}
#endif // INCLUDE_NMT
@@ -1521,10 +1522,12 @@
tty->print_cr("terminate thread %p", this);
}
- // Info NMT that this JavaThread is exiting, its memory
- // recorder should be collected
+ // By now, this thread should already be invisible to safepoint,
+ // and its per-thread recorder also collected.
assert(!is_safepoint_visible(), "wrong state");
- MemTracker::thread_exiting(this);
+#if INCLUDE_NMT
+ assert(get_recorder() == NULL, "Already collected");
+#endif // INCLUDE_NMT
// JSR166 -- return the parker to the free list
Parker::Release(_parker);
@@ -2425,6 +2428,7 @@
}
void JavaThread::remove_stack_guard_pages() {
+ assert(Thread::current() == this, "from different thread");
if (_stack_guard_state == stack_guard_unused) return;
address low_addr = stack_base() - stack_size();
size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
@@ -4093,7 +4097,10 @@
// Now, this thread is not visible to safepoint
p->set_safepoint_visible(false);
-
+ // once the thread becomes safepoint invisible, we can not use its per-thread
+ // recorder. And Threads::do_threads() no longer walks this thread, so we have
+ // to release its per-thread recorder here.
+ MemTracker::thread_exiting(p);
} // unlock Threads_lock
// Since Events::log uses a lock, we grab it outside the Threads_lock