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