safepoint.cpp revision 2796
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
07e378a9c399b1e7fb218477b3b7eaf165f3365dChristian Maeder * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang * This code is free software; you can redistribute it and/or modify it
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang * under the terms of the GNU General Public License version 2 only, as
07e378a9c399b1e7fb218477b3b7eaf165f3365dChristian Maeder * published by the Free Software Foundation.
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang * This code is distributed in the hope that it will be useful, but WITHOUT
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang * version 2 for more details (a copy is included in the LICENSE file that
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang * accompanied this code).
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang * You should have received a copy of the GNU General Public License version
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder * 2 along with this work; if not, write to the Free Software Foundation,
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder * or visit www.oracle.com if you need additional information or have any
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#include "gc_implementation/shared/concurrentGCThread.hpp"
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder// --------------------------------------------------------------------------------------------------
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder// Implementation of Safepoint begin/end
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian MaederSafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maedervolatile int SafepointSynchronize::_waiting_to_block = 0;
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maedervolatile int SafepointSynchronize::_safepoint_counter = 0;
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maederlong SafepointSynchronize::_end_of_last_safepoint = 0;
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maederstatic volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maederstatic volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maederstatic bool timeout_error_printed = false;
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder// Roll all threads forward to a safepoint and suspend them all
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint");
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder _safepoint_begin_time = os::javaTimeNanos();
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder _ts_of_current_safepoint = tty->time_stamp().seconds();
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder // In the future we should investigate whether CMS can use the
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder // more-general mechanism below. DLD (01/05).
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder ConcurrentMarkSweepThread::synchronize(false);
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder ConcurrentGCThread::safepoint_synchronize();
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#endif // SERIALGC
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder // By getting the Threads_lock, we assure that no threads are about to start or
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang // exit. It is released again in SafepointSynchronize::end().
831bfb0c3598d0508b976cd36fa97c65839ed5a3Christian Maeder assert( _state == _not_synchronized, "trying to safepoint synchronize with wrong state");
99ce88d7dbaac66bff850dff5e8b4be65b577249Christian Maeder int nof_threads = Threads::number_of_threads();
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang tty->print_cr("Safepoint synchronization initiated. (%d)", nof_threads);
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // Set number of threads to wait for, before we initiate the callbacks
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang // Save the starting time, so that it can be compared to see if this has taken
99ce88d7dbaac66bff850dff5e8b4be65b577249Christian Maeder // too long to complete.
99ce88d7dbaac66bff850dff5e8b4be65b577249Christian Maeder // PrintSafepointStatisticsTimeout can be specified separately. When
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang // specified, PrintSafepointStatistics will be set to true in
99ce88d7dbaac66bff850dff5e8b4be65b577249Christian Maeder // deferred_initialize_stat method. The initialization has to be done
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // early enough to avoid any races. See bug 6880029 for details.
d7b3ce2c285453331cca8ac7bec7a3b49b3e1ee9Jian Chun Wang if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder // Begin the process of bringing the system to a safepoint.
f3748d50876b05620b20ec3283b747f489f70ec5Christian Maeder // Java threads can be in several different states and are
831bfb0c3598d0508b976cd36fa97c65839ed5a3Christian Maeder // stopped by different mechanisms:
d083810bc36697e03dd2c23434e060f47360e8e6Christian Maeder // 1. Running interpreted
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder // The interpeter dispatch table is changed to force it to
7594b215a69a720304fc8a00236e24ed80fee0b0Christian Maeder // check for a safepoint condition between bytecodes.
7594b215a69a720304fc8a00236e24ed80fee0b0Christian Maeder // 2. Running in native code
7594b215a69a720304fc8a00236e24ed80fee0b0Christian Maeder // When returning from the native code, a Java thread must check
7594b215a69a720304fc8a00236e24ed80fee0b0Christian Maeder // the safepoint _state to see if we must block. If the
7594b215a69a720304fc8a00236e24ed80fee0b0Christian Maeder // VM thread sees a Java thread in native, it does
7594b215a69a720304fc8a00236e24ed80fee0b0Christian Maeder // not wait for this thread to block. The order of the memory
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // writes and reads of both the safepoint state and the Java
831bfb0c3598d0508b976cd36fa97c65839ed5a3Christian Maeder // threads state is critical. In order to guarantee that the
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // memory writes are serialized with respect to each other,
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // the VM thread issues a memory barrier instruction
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // (on MP systems). In order to avoid the overhead of issuing
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // a memory barrier for each Java thread making native calls, each Java
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // thread performs a write to a single memory page after changing
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // the thread state. The VM thread performs a sequence of
831bfb0c3598d0508b976cd36fa97c65839ed5a3Christian Maeder // mprotect OS calls which forces all previous writes from all
e42eddbc69dd31f7cd696e38f82acad678831cb7Jian Chun Wang // Java threads to be serialized. This is done in the
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // os::serialize_thread_states() call. This has proven to be
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // much more efficient than executing a membar instruction
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // on every call to native code.
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // 3. Running compiled Code
e6644795352edafa0a02ea95eb70cde410199adaChristian Maeder // Compiled code reads a global (Safepoint Polling) page that
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder // is set to fault if we are trying to get to a safepoint.
b09390ddf0a066ccbb220b0424e4030d5168463dChristian Maeder // 4. Blocked
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder // A thread which is blocked will not be allowed to return from the
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder // block condition until the safepoint operation is complete.
e42eddbc69dd31f7cd696e38f82acad678831cb7Jian Chun Wang // 5. In VM or Transitioning between states
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder // If a Java thread is currently running in the VM or transitioning
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder // between states, the safepointing code will wait for the thread to
c438c79d00fc438f99627e612498744bdc0d0c89Christian Maeder // block itself when it attempts transitions to a new state.
if (!UseMembar) {
#ifdef ASSERT
if (SafepointTimeout)
unsigned int iterations = 0;
int steps = 0 ;
while(still_running > 0) {
if (still_running > 0) {
// See the comments in synchronizer.cpp for additional remarks on spinning.
// to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
++steps ;
iterations ++ ;
if (PrintSafepointStatistics) {
while (_waiting_to_block > 0) {
#ifndef PRODUCT
if (SafepointTimeout) {
if (TraceSafepoint) {
if (PrintSafepointStatistics) {
if (PrintSafepointStatistics) {
if (PrintSafepointStatistics) {
#ifdef ASSERT
if (PageArmed) {
PageArmed = 0 ;
if (TraceSafepoint) {
if (VMThreadHintNoPreempt) {
#ifndef SERIALGC
if (UseConcMarkSweepGC) {
} else if (UseG1GC) {
if (UseGCLogFileRotation) {
switch(state) {
case _thread_in_native:
case _thread_blocked:
assert(!thread->has_last_Java_frame() || thread->frame_anchor()->walkable(), "blocked and not walkable");
// -------------------------------------------------------------------------------------------------------
switch(state) {
case _thread_in_vm_trans:
if (is_synchronizing()) {
if (is_synchronizing()) {
if (_waiting_to_block == 0) {
case _thread_in_native_trans:
case _thread_blocked_trans:
case _thread_new_trans:
// ------------------------------------------------------------------------------------------------------
#ifndef PRODUCT
#ifdef _LP64
newptr, is_oop?"oop":" ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":" "));
newptr, is_oop?"oop":" ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":" "));
#ifdef SPARC
#ifdef _LP64
tty->print("blob %c%d |"PTR_FORMAT" ","LO"[i>>3],i&7,new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); }
tty->print(" G1 |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
tty->print(" G3 |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
tty->print(" G4 |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
tty->print(" G5 |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
tty->print_cr(" FSR |"PTR_FORMAT" "PTR64_FORMAT" "PTR64_FORMAT,new_sp,*(jlong*)old_sp,*(jlong*)new_sp);
tty->print("call %c%d |"PTR_FORMAT" ","LI"[i2>>3],i2&7,new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); }
assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization");
if (ShowSafepointMsgs) {
if (PrintSafepointStatistics) {
if (!timeout_error_printed) {
timeout_error_printed = true;
if (DieOnSafepointTimeout) {
// -------------------------------------------------------------------------------------------------------
_has_called_back = false;
_at_poll_safepoint = false;
if (is_suspended) {
switch(_type) {
case _at_safepoint:
case _call_back:
set_has_called_back(false);
case _running:
switch(type()) {
case _at_safepoint:
case _call_back:
case _running:
set_has_called_back(false);
switch(_type) {
// ---------------------------------------------------------------------------------------------------------------------
if (return_oop) {
if (return_oop) {
set_at_poll_safepoint(true);
set_at_poll_safepoint(false);
static bool need_to_track_page_armed_status = false;
static bool init_done = false;
static void print_header() {
if (init_done) return;
if (PrintSafepointStatisticsCount <= 0) {
int stats_array_size;
if (PrintSafepointStatisticsTimeout > 0) {
PrintSafepointStatistics = true;
* sizeof(SafepointStats));
need_to_track_page_armed_status = true;
init_done = true;
if (nof_running != 0) {
if (_waiting_to_block != 0) {
if ( PrintSafepointStatisticsTimeout > 0) {
_cur_stat_index = 0;
print_header();
if ( PrintSafepointStatisticsTimeout < 0 ||
if (!need_to_track_page_armed_status) {
if (UseCompilerSafepoints) {
#ifndef PRODUCT
if (ShowSafepointMsgs) {