safepoint.hpp revision 6412:53a41e7cbe05
152419Sjulian/* 252419Sjulian * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3139823Simp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4139823Simp * 5139823Simp * This code is free software; you can redistribute it and/or modify it 652419Sjulian * under the terms of the GNU General Public License version 2 only, as 752419Sjulian * published by the Free Software Foundation. 870784Sjulian * 952419Sjulian * This code is distributed in the hope that it will be useful, but WITHOUT 1052419Sjulian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1152419Sjulian * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1252419Sjulian * version 2 for more details (a copy is included in the LICENSE file that 1352419Sjulian * accompanied this code). 1452419Sjulian * 1552419Sjulian * You should have received a copy of the GNU General Public License version 1652419Sjulian * 2 along with this work; if not, write to the Free Software Foundation, 1752419Sjulian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1852419Sjulian * 1970784Sjulian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2052419Sjulian * or visit www.oracle.com if you need additional information or have any 2152419Sjulian * questions. 2252419Sjulian * 2352419Sjulian */ 2452419Sjulian 2552419Sjulian#ifndef SHARE_VM_RUNTIME_SAFEPOINT_HPP 2652419Sjulian#define SHARE_VM_RUNTIME_SAFEPOINT_HPP 2752419Sjulian 2852419Sjulian#include "asm/assembler.hpp" 2952419Sjulian#include "code/nmethod.hpp" 3052419Sjulian#include "memory/allocation.hpp" 3152419Sjulian#include "runtime/extendedPC.hpp" 3252419Sjulian#include "runtime/mutexLocker.hpp" 3352419Sjulian#include "runtime/os.hpp" 3452419Sjulian#include "utilities/ostream.hpp" 3552419Sjulian 3652419Sjulian// 3752419Sjulian// Safepoint synchronization 3867506Sjulian//// 3952419Sjulian// The VMThread or CMS_thread uses the SafepointSynchronize::begin/end 4052419Sjulian// methods to enter/exit a safepoint region. The begin method will roll 4152752Sjulian// all JavaThreads forward to a safepoint. 4252419Sjulian// 4352419Sjulian// JavaThreads must use the ThreadSafepointState abstraction (defined in 4452419Sjulian// thread.hpp) to indicate that that they are at a safepoint. 4552419Sjulian// 4652419Sjulian// The Mutex/Condition variable and ObjectLocker classes calls the enter/ 4752419Sjulian// exit safepoint methods, when a thread is blocked/restarted. Hence, all mutex exter/ 4852419Sjulian// exit points *must* be at a safepoint. 4952419Sjulian 5052419Sjulian 5152419Sjulianclass ThreadSafepointState; 5252419Sjulianclass SnippetCache; 5352419Sjulianclass nmethod; 54230487Sglebius 5552419Sjulian// 56132705Sglebius// Implements roll-forward to safepoint (safepoint synchronization) 5795759Stanimura// 5852419Sjulianclass SafepointSynchronize : AllStatic { 5952419Sjulian public: 60132013Srwatson enum SynchronizeState { 61164033Srwatson _not_synchronized = 0, // Threads not synchronized at a safepoint 6252419Sjulian // Keep this value 0. See the comment in do_call_back() 6395759Stanimura _synchronizing = 1, // Synchronizing in progress 6452419Sjulian _synchronized = 2 // All Java threads are stopped at a safepoint. Only VM thread is running 6552419Sjulian }; 66159590Sjhb 6752419Sjulian enum SafepointingThread { 68195837Srwatson _null_thread = 0, 69195837Srwatson _vm_thread = 1, 70195837Srwatson _other_thread = 2 7152419Sjulian }; 7252419Sjulian 7352919Sjulian enum SafepointTimeoutReason { 7452419Sjulian _spinning_timeout = 0, 7552419Sjulian _blocking_timeout = 1 7670870Sjulian }; 77227293Sed 78227293Sed typedef struct { 7970870Sjulian float _time_stamp; // record when the current safepoint occurs in seconds 8070870Sjulian int _vmop_type; // type of VM operation triggers the safepoint 8170870Sjulian int _nof_total_threads; // total number of Java threads 8270870Sjulian int _nof_initial_running_threads; // total number of initially seen running threads 8370870Sjulian int _nof_threads_wait_to_block; // total number of threads waiting for to block 8452419Sjulian bool _page_armed; // true if polling page is armed, false otherwise 8552419Sjulian int _nof_threads_hit_page_trap; // total number of threads hitting the page trap 8652419Sjulian jlong _time_to_spin; // total time in millis spent in spinning 8752419Sjulian jlong _time_to_wait_to_block; // total time in millis spent in waiting for to block 8852419Sjulian jlong _time_to_do_cleanups; // total time in millis spent in performing cleanups 8952419Sjulian jlong _time_to_sync; // total time in millis spent in getting to _synchronized 9052419Sjulian jlong _time_to_exec_vmop; // total time in millis spent in vm operation itself 9152419Sjulian } SafepointStats; 9252419Sjulian 9352419Sjulian private: 9452419Sjulian static volatile SynchronizeState _state; // Threads might read this flag directly, without acquiring the Threads_lock 9552419Sjulian static volatile int _waiting_to_block; // number of threads we are waiting for to block 9652419Sjulian static int _current_jni_active_count; // Counts the number of active critical natives during the safepoint 9752419Sjulian 9852419Sjulian // This counter is used for fast versions of jni_Get<Primitive>Field. 9952419Sjulian // An even value means there is no ongoing safepoint operations. 10052419Sjulian // The counter is incremented ONLY at the beginning and end of each 10152419Sjulian // safepoint. The fact that Threads_lock is held throughout each pair of 10252419Sjulian // increments (at the beginning and end of each safepoint) guarantees 10352419Sjulian // race freedom. 10452419Sjulianpublic: 10552419Sjulian static volatile int _safepoint_counter; 10652419Sjulianprivate: 10752419Sjulian static long _end_of_last_safepoint; // Time of last safepoint in milliseconds 10852419Sjulian 10952419Sjulian // Statistics 11052419Sjulian static jlong _safepoint_begin_time; // time when safepoint begins 11152752Sjulian static SafepointStats* _safepoint_stats; // array of SafepointStats struct 11252752Sjulian static int _cur_stat_index; // current index to the above array 11370700Sjulian static julong _safepoint_reasons[]; // safepoint count for each VM op 11452752Sjulian static julong _coalesced_vmop_count; // coalesced vmop count 11572053Sjulian static jlong _max_sync_time; // maximum sync time in nanos 116230487Sglebius static jlong _max_vmop_time; // maximum vm operation time in nanos 11752752Sjulian static float _ts_of_current_safepoint; // time stamp of current safepoint in seconds 11852885Sjulian 11952419Sjulian static void begin_statistics(int nof_threads, int nof_running); 12052419Sjulian static void update_statistics_on_spin_end(); 12152419Sjulian static void update_statistics_on_sync_end(jlong end_time); 12252419Sjulian static void update_statistics_on_cleanup_end(jlong end_time); 12352419Sjulian static void end_statistics(jlong end_time); 124151975Sglebius static void print_statistics(); 125151975Sglebius inline static void inc_page_trap_count() { 12652419Sjulian Atomic::inc(&_safepoint_stats[_cur_stat_index]._nof_threads_hit_page_trap); 12752419Sjulian } 12852419Sjulian 12952419Sjulian // For debug long safepoint 130147774Sglebius static void print_safepoint_timeout(SafepointTimeoutReason timeout_reason); 13152419Sjulian 13252419Sjulianpublic: 13352419Sjulian 134129823Sjulian // Main entry points 135129823Sjulian 136129823Sjulian // Roll all threads forward to safepoint. Must be called by the 137129823Sjulian // VMThread or CMS_thread. 138129823Sjulian static void begin(); 139129823Sjulian static void end(); // Start all suspended threads again... 140129823Sjulian 141129823Sjulian static bool safepoint_safe(JavaThread *thread, JavaThreadState state); 142230487Sglebius 143129823Sjulian static void check_for_lazy_critical_native(JavaThread *thread, JavaThreadState state); 144129823Sjulian 14552419Sjulian // Query 146138238Smlaier inline static bool is_at_safepoint() { return _state == _synchronized; } 14752419Sjulian inline static bool is_synchronizing() { return _state == _synchronizing; } 14852419Sjulian 14964512Sarchie inline static bool do_call_back() { 150217320Smdf return (_state != _not_synchronized); 151124871Sru } 15252419Sjulian 153217320Smdf inline static void increment_jni_active_count() { 154125116Sru assert_locked_or_safepoint(Safepoint_lock); 15552419Sjulian _current_jni_active_count++; 156205082Sglebius } 157205082Sglebius 158205082Sglebius // Called when a thread voluntarily blocks 159205082Sglebius static void block(JavaThread *thread); 160205082Sglebius static void signal_thread_at_safepoint() { _waiting_to_block--; } 16153526Sjulian 16252419Sjulian // Exception handling for page polling 163131933Smarcel static void handle_polling_page_exception(JavaThread *thread); 16452419Sjulian 16552419Sjulian // VM Thread interface for determining safepoint rate 16652419Sjulian static long last_non_safepoint_interval() { 16752419Sjulian return os::javaTimeMillis() - _end_of_last_safepoint; 168230487Sglebius } 169230487Sglebius static long end_of_last_safepoint() { 170230487Sglebius return _end_of_last_safepoint; 171230487Sglebius } 172230487Sglebius static bool is_cleanup_needed(); 173230487Sglebius static void do_cleanup_tasks(); 174230481Sglebius 175230481Sglebius // Debugging 176230481Sglebius static void print_state() PRODUCT_RETURN; 177230481Sglebius static void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(1, 2) PRODUCT_RETURN; 178230481Sglebius 179230487Sglebius static void deferred_initialize_stat(); 180230487Sglebius static void print_stat_on_exit(); 181230481Sglebius inline static void inc_vmop_coalesced_count() { _coalesced_vmop_count++; } 182230481Sglebius 183230481Sglebius static void set_is_at_safepoint() { _state = _synchronized; } 184230481Sglebius static void set_is_not_at_safepoint() { _state = _not_synchronized; } 185230481Sglebius 186230481Sglebius // Assembly support 187230481Sglebius static address address_of_state() { return (address)&_state; } 188230481Sglebius 18952419Sjulian static address safepoint_counter_addr() { return (address)&_safepoint_counter; } 19052419Sjulian}; 19152419Sjulian 19252419Sjulian// State class for a thread suspended at a safepoint 19352419Sjulianclass ThreadSafepointState: public CHeapObj<mtInternal> { 19483366Sjulian public: 19552419Sjulian // These states are maintained by VM thread while threads are being brought 19652419Sjulian // to a safepoint. After SafepointSynchronize::end(), they are reset to 197164033Srwatson // _running. 19852419Sjulian enum suspend_type { 199164033Srwatson _running = 0, // Thread state not yet determined (i.e., not at a safepoint yet) 200164033Srwatson _at_safepoint = 1, // Thread at a safepoint (f.ex., when blocked on a lock) 201164033Srwatson _call_back = 2 // Keep executing and wait for callback (if thread is in interpreted or vm) 20252419Sjulian }; 20352419Sjulian private: 20452419Sjulian volatile bool _at_poll_safepoint; // At polling page safepoint (NOT a poll return safepoint) 20552419Sjulian // Thread has called back the safepoint code (for debugging) 20652419Sjulian bool _has_called_back; 207157370Srwatson 20852419Sjulian JavaThread * _thread; 20952419Sjulian volatile suspend_type _type; 21052419Sjulian JavaThreadState _orig_thread_state; 21152419Sjulian 212157370Srwatson 213151975Sglebius public: 21452419Sjulian ThreadSafepointState(JavaThread *thread); 21552419Sjulian 21652419Sjulian // examine/roll-forward/restart 21752419Sjulian void examine_state_of_thread(); 21883366Sjulian void roll_forward(suspend_type type); 21952419Sjulian void restart(); 22052419Sjulian 221147774Sglebius // Query 22252419Sjulian JavaThread* thread() const { return _thread; } 22370700Sjulian suspend_type type() const { return _type; } 22452419Sjulian bool is_running() const { return (_type==_running); } 225146317Sglebius JavaThreadState orig_thread_state() const { return _orig_thread_state; } 22670700Sjulian 22752419Sjulian // Support for safepoint timeout (debugging) 228172806Smav bool has_called_back() const { return _has_called_back; } 22952419Sjulian void set_has_called_back(bool val) { _has_called_back = val; } 23052419Sjulian bool is_at_poll_safepoint() { return _at_poll_safepoint; } 23152419Sjulian void set_at_poll_safepoint(bool val) { _at_poll_safepoint = val; } 23252419Sjulian 23352419Sjulian void handle_polling_page_exception(); 23452419Sjulian 235163463Sglebius // debugging 23652419Sjulian void print_on(outputStream* st) const; 23752419Sjulian void print() const { print_on(tty); } 23852419Sjulian 23952419Sjulian // Initialize 24052419Sjulian static void create(JavaThread *thread); 241163463Sglebius static void destroy(JavaThread *thread); 242163463Sglebius 243163463Sglebius void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) { 244163463Sglebius if (ShowSafepointMsgs) { 24552419Sjulian va_list ap; 246163463Sglebius va_start(ap, format); 24752419Sjulian tty->vprint_cr(format, ap); 24852419Sjulian va_end(ap); 24952419Sjulian } 250163463Sglebius } 251163463Sglebius}; 252163463Sglebius 253163463Sglebius 25452419Sjulian 25552419Sjulian#endif // SHARE_VM_RUNTIME_SAFEPOINT_HPP 25652419Sjulian