src/share/vm/runtime/safepoint.cpp
Print this page
rev 13113 : 8182651: Add TRACE_ONLY conditional macro to support more fine-grained INCLUDE_TRACE programming
Reviewed-by:
*** 54,74 ****
#include "runtime/sweeper.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "services/runtimeService.hpp"
- #include "trace/tracing.hpp"
- #include "trace/traceMacros.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc/cms/concurrentMarkSweepThread.hpp"
#include "gc/g1/suspendibleThreadSet.hpp"
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_globals.hpp"
#endif
// --------------------------------------------------------------------------------------------------
// Implementation of Safepoint begin/end
SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
--- 54,142 ----
#include "runtime/sweeper.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "services/runtimeService.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc/cms/concurrentMarkSweepThread.hpp"
#include "gc/g1/suspendibleThreadSet.hpp"
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_globals.hpp"
#endif
+ #if INCLUDE_TRACE
+ #include "trace/tracing.hpp"
+
+ static void post_safepoint_begin_event(EventSafepointBegin* event,
+ int safepoint_id,
+ int thread_count,
+ int critical_thread_count) {
+ assert(event != NULL, "invariant");
+ if (event->should_commit()) {
+ event->set_safepointId(safepoint_id);
+ event->set_totalThreadCount(thread_count);
+ event->set_jniCriticalThreadCount(critical_thread_count);
+ event->commit();
+ }
+ }
+
+ static void post_safepoint_cleanup_event(EventSafepointCleanup* event,
+ int safepoint_id) {
+ assert(event != NULL, "invariant");
+ if (event->should_commit()) {
+ event->set_safepointId(safepoint_id);
+ event->commit();
+ }
+ }
+
+ static void post_safepoint_synchronize_event(EventSafepointStateSynchronization* event,
+ int safepoint_id,
+ int initial_number_of_threads,
+ int threads_waiting_to_block,
+ unsigned int iterations) {
+ assert(event != NULL, "invariant");
+ if (event->should_commit()) {
+ event->set_safepointId(safepoint_id);
+ event->set_initialThreadCount(initial_number_of_threads);
+ event->set_runningThreadCount(threads_waiting_to_block);
+ event->set_iterations(iterations);
+ event->commit();
+ }
+ }
+
+ static void post_safepoint_wait_blocked_event(EventSafepointWaitBlocked* event,
+ int safepoint_id,
+ int initial_threads_waiting_to_block) {
+ assert(event != NULL, "invariant");
+ if (event->should_commit()) {
+ event->set_safepointId(safepoint_id);
+ event->set_runningThreadCount(initial_threads_waiting_to_block);
+ event->commit();
+ }
+ }
+
+ static void post_safepoint_end_event(EventSafepointEnd* event, int safepoint_id) {
+ assert(event != NULL, "invariant");
+ if (event->should_commit()) {
+ event->set_safepointId(safepoint_id);
+ event->commit();
+ }
+ }
+
+ static void post_safepoint_cleanup_task_event(EventSafepointCleanupTask* event,
+ int safepoint_id,
+ const char* name) {
+ assert(event != NULL, "invariant");
+ if (event->should_commit()) {
+ event->set_safepointId(safepoint_id);
+ event->set_name(name);
+ event->commit();
+ }
+ }
+ #endif // INCLUDE_TRACE
// --------------------------------------------------------------------------------------------------
// Implementation of Safepoint begin/end
SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
*** 80,90 ****
static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only
static bool timeout_error_printed = false;
// Roll all threads forward to a safepoint and suspend them all
void SafepointSynchronize::begin() {
! EventSafepointBegin begin_event;
Thread* myThread = Thread::current();
assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint");
if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
_safepoint_begin_time = os::javaTimeNanos();
--- 148,158 ----
static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only
static bool timeout_error_printed = false;
// Roll all threads forward to a safepoint and suspend them all
void SafepointSynchronize::begin() {
! TRACE_ONLY(EventSafepointBegin begin_event;)
Thread* myThread = Thread::current();
assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint");
if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
_safepoint_begin_time = os::javaTimeNanos();
*** 171,181 ****
// If a Java thread is currently running in the VM or transitioning
// between states, the safepointing code will wait for the thread to
// block itself when it attempts transitions to a new state.
//
{
! EventSafepointStateSynchronization sync_event;
int initial_running = 0;
_state = _synchronizing;
OrderAccess::fence();
--- 239,249 ----
// If a Java thread is currently running in the VM or transitioning
// between states, the safepointing code will wait for the thread to
// block itself when it attempts transitions to a new state.
//
{
! TRACE_ONLY(EventSafepointStateSynchronization sync_event;)
int initial_running = 0;
_state = _synchronizing;
OrderAccess::fence();
*** 325,346 ****
if (PrintSafepointStatistics) {
update_statistics_on_spin_end();
}
! if (sync_event.should_commit()) {
! sync_event.set_safepointId(safepoint_counter());
! sync_event.set_initialThreadCount(initial_running);
! sync_event.set_runningThreadCount(_waiting_to_block);
! sync_event.set_iterations(iterations);
! sync_event.commit();
}
- } //EventSafepointStateSync
// wait until all threads are stopped
{
! EventSafepointWaitBlocked wait_blocked_event;
int initial_waiting_to_block = _waiting_to_block;
while (_waiting_to_block > 0) {
log_debug(safepoint)("Waiting for %d thread(s) to block", _waiting_to_block);
if (!SafepointTimeout || timeout_error_printed) {
--- 393,412 ----
if (PrintSafepointStatistics) {
update_statistics_on_spin_end();
}
! TRACE_ONLY(post_safepoint_synchronize_event(&sync_event,
! safepoint_counter(),
! initial_running,
! _waiting_to_block,
! iterations);)
}
// wait until all threads are stopped
{
! TRACE_ONLY(EventSafepointWaitBlocked wait_blocked_event;)
int initial_waiting_to_block = _waiting_to_block;
while (_waiting_to_block > 0) {
log_debug(safepoint)("Waiting for %d thread(s) to block", _waiting_to_block);
if (!SafepointTimeout || timeout_error_printed) {
*** 376,391 ****
// Record state
_state = _synchronized;
OrderAccess::fence();
! if (wait_blocked_event.should_commit()) {
! wait_blocked_event.set_safepointId(safepoint_counter());
! wait_blocked_event.set_runningThreadCount(initial_waiting_to_block);
! wait_blocked_event.commit();
}
- } // EventSafepointWaitBlocked
#ifdef ASSERT
for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
// make sure all the threads were visited
assert(cur->was_visited_for_critical_count(), "missed a thread");
--- 442,455 ----
// Record state
_state = _synchronized;
OrderAccess::fence();
! TRACE_ONLY(post_safepoint_wait_blocked_event(&wait_blocked_event,
! safepoint_counter(),
! initial_waiting_to_block);)
}
#ifdef ASSERT
for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
// make sure all the threads were visited
assert(cur->was_visited_for_critical_count(), "missed a thread");
*** 404,437 ****
update_statistics_on_sync_end(os::javaTimeNanos());
}
// Call stuff that needs to be run when a safepoint is just about to be completed
{
! EventSafepointCleanup cleanup_event;
do_cleanup_tasks();
! if (cleanup_event.should_commit()) {
! cleanup_event.set_safepointId(safepoint_counter());
! cleanup_event.commit();
! }
}
if (PrintSafepointStatistics) {
// Record how much time spend on the above cleanup tasks
update_statistics_on_cleanup_end(os::javaTimeNanos());
}
! if (begin_event.should_commit()) {
! begin_event.set_safepointId(safepoint_counter());
! begin_event.set_totalThreadCount(nof_threads);
! begin_event.set_jniCriticalThreadCount(_current_jni_active_count);
! begin_event.commit();
! }
}
// Wake up all threads, so they are ready to resume execution after the safepoint
// operation has been carried out
void SafepointSynchronize::end() {
! EventSafepointEnd event;
int safepoint_id = safepoint_counter(); // Keep the odd counter as "id"
assert(Threads_lock->owned_by_self(), "must hold Threads_lock");
assert((_safepoint_counter & 0x1) == 1, "must be odd");
_safepoint_counter ++;
--- 468,494 ----
update_statistics_on_sync_end(os::javaTimeNanos());
}
// Call stuff that needs to be run when a safepoint is just about to be completed
{
! TRACE_ONLY(EventSafepointCleanup cleanup_event;)
do_cleanup_tasks();
! TRACE_ONLY(post_safepoint_cleanup_event(&cleanup_event, safepoint_counter());)
}
if (PrintSafepointStatistics) {
// Record how much time spend on the above cleanup tasks
update_statistics_on_cleanup_end(os::javaTimeNanos());
}
! TRACE_ONLY(post_safepoint_begin_event(&begin_event, safepoint_counter(),
! nof_threads, _current_jni_active_count);)
}
// Wake up all threads, so they are ready to resume execution after the safepoint
// operation has been carried out
void SafepointSynchronize::end() {
! TRACE_ONLY(EventSafepointEnd event;)
int safepoint_id = safepoint_counter(); // Keep the odd counter as "id"
assert(Threads_lock->owned_by_self(), "must hold Threads_lock");
assert((_safepoint_counter & 0x1) == 1, "must be odd");
_safepoint_counter ++;
*** 516,604 ****
#endif // INCLUDE_ALL_GCS
// record this time so VMThread can keep track how much time has elapsed
// since last safepoint.
_end_of_last_safepoint = os::javaTimeMillis();
! if (event.should_commit()) {
! event.set_safepointId(safepoint_id);
! event.commit();
! }
}
bool SafepointSynchronize::is_cleanup_needed() {
// Need a safepoint if there are many monitors to deflate.
if (ObjectSynchronizer::is_cleanup_needed()) return true;
// Need a safepoint if some inline cache buffers is non-empty
if (!InlineCacheBuffer::is_empty()) return true;
return false;
}
- static void event_safepoint_cleanup_task_commit(EventSafepointCleanupTask& event, const char* name) {
- if (event.should_commit()) {
- event.set_safepointId(SafepointSynchronize::safepoint_counter());
- event.set_name(name);
- event.commit();
- }
- }
-
// Various cleaning tasks that should be done periodically at safepoints
void SafepointSynchronize::do_cleanup_tasks() {
{
const char* name = "deflating idle monitors";
! EventSafepointCleanupTask event;
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
ObjectSynchronizer::deflate_idle_monitors();
! event_safepoint_cleanup_task_commit(event, name);
}
{
const char* name = "updating inline caches";
! EventSafepointCleanupTask event;
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
InlineCacheBuffer::update_inline_caches();
! event_safepoint_cleanup_task_commit(event, name);
}
{
const char* name = "compilation policy safepoint handler";
! EventSafepointCleanupTask event;
TraceTime timer("compilation policy safepoint handler", TRACETIME_LOG(Info, safepoint, cleanup));
CompilationPolicy::policy()->do_safepoint_work();
! event_safepoint_cleanup_task_commit(event, name);
}
{
const char* name = "mark nmethods";
! EventSafepointCleanupTask event;
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
NMethodSweeper::mark_active_nmethods();
! event_safepoint_cleanup_task_commit(event, name);
}
if (SymbolTable::needs_rehashing()) {
const char* name = "rehashing symbol table";
! EventSafepointCleanupTask event;
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
SymbolTable::rehash_table();
! event_safepoint_cleanup_task_commit(event, name);
}
if (StringTable::needs_rehashing()) {
const char* name = "rehashing string table";
! EventSafepointCleanupTask event;
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
StringTable::rehash_table();
! event_safepoint_cleanup_task_commit(event, name);
}
{
// CMS delays purging the CLDG until the beginning of the next safepoint and to
// make sure concurrent sweep is done
const char* name = "purging class loader data graph";
! EventSafepointCleanupTask event;
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
ClassLoaderDataGraph::purge_if_needed();
! event_safepoint_cleanup_task_commit(event, name);
}
}
bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) {
--- 573,650 ----
#endif // INCLUDE_ALL_GCS
// record this time so VMThread can keep track how much time has elapsed
// since last safepoint.
_end_of_last_safepoint = os::javaTimeMillis();
! TRACE_ONLY(post_safepoint_end_event(&event, safepoint_id);)
}
bool SafepointSynchronize::is_cleanup_needed() {
// Need a safepoint if there are many monitors to deflate.
if (ObjectSynchronizer::is_cleanup_needed()) return true;
// Need a safepoint if some inline cache buffers is non-empty
if (!InlineCacheBuffer::is_empty()) return true;
return false;
}
// Various cleaning tasks that should be done periodically at safepoints
void SafepointSynchronize::do_cleanup_tasks() {
{
const char* name = "deflating idle monitors";
! TRACE_ONLY(EventSafepointCleanupTask event;)
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
ObjectSynchronizer::deflate_idle_monitors();
! TRACE_ONLY(post_safepoint_cleanup_task_event(&event, safepoint_counter(), name);)
}
{
const char* name = "updating inline caches";
! TRACE_ONLY(EventSafepointCleanupTask event;)
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
InlineCacheBuffer::update_inline_caches();
! TRACE_ONLY(post_safepoint_cleanup_task_event(&event, safepoint_counter(), name);)
}
{
const char* name = "compilation policy safepoint handler";
! TRACE_ONLY(EventSafepointCleanupTask event;)
TraceTime timer("compilation policy safepoint handler", TRACETIME_LOG(Info, safepoint, cleanup));
CompilationPolicy::policy()->do_safepoint_work();
! TRACE_ONLY(post_safepoint_cleanup_task_event(&event, safepoint_counter(), name);)
}
{
const char* name = "mark nmethods";
! TRACE_ONLY(EventSafepointCleanupTask event;)
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
NMethodSweeper::mark_active_nmethods();
! TRACE_ONLY(post_safepoint_cleanup_task_event(&event, safepoint_counter(), name);)
}
if (SymbolTable::needs_rehashing()) {
const char* name = "rehashing symbol table";
! TRACE_ONLY(EventSafepointCleanupTask event;)
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
SymbolTable::rehash_table();
! TRACE_ONLY(post_safepoint_cleanup_task_event(&event, safepoint_counter(), name);)
}
if (StringTable::needs_rehashing()) {
const char* name = "rehashing string table";
! TRACE_ONLY(EventSafepointCleanupTask event;)
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
StringTable::rehash_table();
! TRACE_ONLY(post_safepoint_cleanup_task_event(&event, safepoint_counter(), name);)
}
{
// CMS delays purging the CLDG until the beginning of the next safepoint and to
// make sure concurrent sweep is done
const char* name = "purging class loader data graph";
! TRACE_ONLY(EventSafepointCleanupTask event;)
TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
ClassLoaderDataGraph::purge_if_needed();
! TRACE_ONLY(post_safepoint_cleanup_task_event(&event, safepoint_counter(), name);)
}
}
bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) {