< prev index next >
src/share/vm/runtime/safepoint.cpp
Print this page
*** 53,62 ****
--- 53,64 ----
#include "runtime/stubRoutines.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.inline.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"
*** 77,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() {
!
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();
_ts_of_current_safepoint = tty->time_stamp().seconds();
}
--- 79,91 ----
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();
_ts_of_current_safepoint = tty->time_stamp().seconds();
}
*** 167,176 ****
--- 168,181 ----
// 5. In VM or Transitioning between states
// 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.
//
+ {
+ EventSafepointStateSync sync_event;
+ int initial_running = 0;
+
_state = _synchronizing;
OrderAccess::fence();
// Flush all thread states to memory
if (!UseMembar) {
*** 224,236 ****
cur_state->print_on(LogHandle(safepoint)::debug_stream());
}
}
}
! if (PrintSafepointStatistics && iterations == 0) {
begin_statistics(nof_threads, still_running);
}
if (still_running > 0) {
// Check for if it takes to long
if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
print_safepoint_timeout(_spinning_timeout);
--- 229,244 ----
cur_state->print_on(LogHandle(safepoint)::debug_stream());
}
}
}
! if (iterations == 0) {
! initial_running = still_running;
! if (PrintSafepointStatistics) {
begin_statistics(nof_threads, still_running);
}
+ }
if (still_running > 0) {
// Check for if it takes to long
if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
print_safepoint_timeout(_spinning_timeout);
*** 315,325 ****
--- 323,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) {
Safepoint_lock->wait(true); // true, means with no safepoint checks
} else {
*** 352,361 ****
--- 373,388 ----
// 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");
*** 375,395 ****
--- 402,437 ----
if (PrintSafepointStatistics) {
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 ++;
// memory fence isn't required here since an odd _safepoint_counter
*** 472,481 ****
--- 514,528 ----
}
#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 some inline cache buffers is non-empty
if (!InlineCacheBuffer::is_empty()) return true;
*** 485,527 ****
// Various cleaning tasks that should be done periodically at safepoints
void SafepointSynchronize::do_cleanup_tasks() {
{
! TraceTime t1("deflating idle monitors", TraceSafepointCleanupTime);
ObjectSynchronizer::deflate_idle_monitors();
}
{
! TraceTime t2("updating inline caches", TraceSafepointCleanupTime);
InlineCacheBuffer::update_inline_caches();
}
{
! TraceTime t3("compilation policy safepoint handler", TraceSafepointCleanupTime);
CompilationPolicy::policy()->do_safepoint_work();
}
{
! TraceTime t4("mark nmethods", TraceSafepointCleanupTime);
NMethodSweeper::mark_active_nmethods();
}
if (SymbolTable::needs_rehashing()) {
! TraceTime t5("rehashing symbol table", TraceSafepointCleanupTime);
SymbolTable::rehash_table();
}
if (StringTable::needs_rehashing()) {
! TraceTime t6("rehashing string table", TraceSafepointCleanupTime);
StringTable::rehash_table();
}
{
// CMS delays purging the CLDG until the beginning of the next safepoint and to
// make sure concurrent sweep is done
! TraceTime t7("purging class loader data graph", TraceSafepointCleanupTime);
ClassLoaderDataGraph::purge_if_needed();
}
}
bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) {
--- 532,623 ----
// Various cleaning tasks that should be done periodically at safepoints
void SafepointSynchronize::do_cleanup_tasks() {
{
! const char* name = "deflating idle monitors";
! EventSafepointCleanupTask event;
! TraceTime t1(name, TraceSafepointCleanupTime);
ObjectSynchronizer::deflate_idle_monitors();
+ if (event.should_commit()) {
+ event.set_safepointId(safepoint_counter());
+ event.set_name(name);
+ event.commit();
+ }
}
{
! const char* name = "updating inline caches";
! EventSafepointCleanupTask event;
! TraceTime t2(name, TraceSafepointCleanupTime);
InlineCacheBuffer::update_inline_caches();
+ if (event.should_commit()) {
+ event.set_safepointId(safepoint_counter());
+ event.set_name(name);
+ event.commit();
+ }
}
{
! const char* name = "compilation policy safepoint handler";
! EventSafepointCleanupTask event;
! TraceTime t3(name, TraceSafepointCleanupTime);
CompilationPolicy::policy()->do_safepoint_work();
+ if (event.should_commit()) {
+ event.set_safepointId(safepoint_counter());
+ event.set_name(name);
+ event.commit();
+ }
}
{
! const char* name = "mark nmethods";
! EventSafepointCleanupTask event;
! TraceTime t4(name, TraceSafepointCleanupTime);
NMethodSweeper::mark_active_nmethods();
+ if (event.should_commit()) {
+ event.set_safepointId(safepoint_counter());
+ event.set_name(name);
+ event.commit();
+ }
}
if (SymbolTable::needs_rehashing()) {
! const char* name = "rehashing symbol table";
! EventSafepointCleanupTask event;
! TraceTime t5(name, TraceSafepointCleanupTime);
SymbolTable::rehash_table();
+ if (event.should_commit()) {
+ event.set_safepointId(safepoint_counter());
+ event.set_name(name);
+ event.commit();
+ }
}
if (StringTable::needs_rehashing()) {
! const char* name = "rehashing string table";
! EventSafepointCleanupTask event;
! TraceTime t6(name, TraceSafepointCleanupTime);
StringTable::rehash_table();
+ if (event.should_commit()) {
+ event.set_safepointId(safepoint_counter());
+ event.set_name(name);
+ event.commit();
+ }
}
{
// 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 t7(name, TraceSafepointCleanupTime);
ClassLoaderDataGraph::purge_if_needed();
+ if (event.should_commit()) {
+ event.set_safepointId(safepoint_counter());
+ event.set_name(name);
+ event.commit();
+ }
}
}
bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) {
< prev index next >