src/hotspot/share/gc/shared/gcLocker.hpp
changeset 49594 898ef81cbc0e
parent 47216 71c04702a3d5
child 53244 9807daeb47c4
equal deleted inserted replaced
49593:4dd58ecc9912 49594:898ef81cbc0e
    23  */
    23  */
    24 
    24 
    25 #ifndef SHARE_VM_GC_SHARED_GCLOCKER_HPP
    25 #ifndef SHARE_VM_GC_SHARED_GCLOCKER_HPP
    26 #define SHARE_VM_GC_SHARED_GCLOCKER_HPP
    26 #define SHARE_VM_GC_SHARED_GCLOCKER_HPP
    27 
    27 
    28 #include "gc/shared/collectedHeap.hpp"
    28 #include "memory/allocation.hpp"
    29 #include "gc/shared/genCollectedHeap.hpp"
    29 #include "utilities/globalDefinitions.hpp"
    30 #include "memory/universe.hpp"
    30 #include "utilities/macros.hpp"
    31 #include "oops/oop.hpp"
    31 
       
    32 class JavaThread;
    32 
    33 
    33 // The direct lock/unlock calls do not force a collection if an unlock
    34 // The direct lock/unlock calls do not force a collection if an unlock
    34 // decrements the count to zero. Avoid calling these if at all possible.
    35 // decrements the count to zero. Avoid calling these if at all possible.
    35 
    36 
    36 class GCLocker: public AllStatic {
    37 class GCLocker: public AllStatic {
    63     verify_critical_count();
    64     verify_critical_count();
    64     return _jni_lock_count > 0;
    65     return _jni_lock_count > 0;
    65   }
    66   }
    66 
    67 
    67   static void log_debug_jni(const char* msg);
    68   static void log_debug_jni(const char* msg);
       
    69 
       
    70   static bool is_at_safepoint();
       
    71 
    68  public:
    72  public:
    69   // Accessors
    73   // Accessors
    70   static bool is_active() {
    74   static bool is_active() {
    71     assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
    75     assert(GCLocker::is_at_safepoint(), "only read at safepoint");
    72     return is_active_internal();
    76     return is_active_internal();
    73   }
    77   }
    74   static bool needs_gc()       { return _needs_gc;                        }
    78   static bool needs_gc()       { return _needs_gc;                        }
    75 
    79 
    76   // Shorthand
    80   // Shorthand
   133   // after the safepoint.  Since after a safepoint, each of the
   137   // after the safepoint.  Since after a safepoint, each of the
   134   // following two methods is either entered from the method entry and
   138   // following two methods is either entered from the method entry and
   135   // falls into the slow path, or is resumed from the safepoints in
   139   // falls into the slow path, or is resumed from the safepoints in
   136   // the method, which only exist in the slow path. So when _needs_gc
   140   // the method, which only exist in the slow path. So when _needs_gc
   137   // is set, the slow path is always taken, till _needs_gc is cleared.
   141   // is set, the slow path is always taken, till _needs_gc is cleared.
   138   static void lock_critical(JavaThread* thread);
   142   inline static void lock_critical(JavaThread* thread);
   139   static void unlock_critical(JavaThread* thread);
   143   inline static void unlock_critical(JavaThread* thread);
   140 
   144 
   141   static address needs_gc_address() { return (address) &_needs_gc; }
   145   static address needs_gc_address() { return (address) &_needs_gc; }
   142 };
   146 };
   143 
   147 
   144 
       
   145 // A NoGCVerifier object can be placed in methods where one assumes that
       
   146 // no garbage collection will occur. The destructor will verify this property
       
   147 // unless the constructor is called with argument false (not verifygc).
       
   148 //
       
   149 // The check will only be done in debug mode and if verifygc true.
       
   150 
       
   151 class NoGCVerifier: public StackObj {
       
   152  friend class PauseNoGCVerifier;
       
   153 
       
   154  protected:
       
   155   bool _verifygc;
       
   156   unsigned int _old_invocations;
       
   157 
       
   158  public:
       
   159 #ifdef ASSERT
       
   160   NoGCVerifier(bool verifygc = true);
       
   161   ~NoGCVerifier();
       
   162 #else
       
   163   NoGCVerifier(bool verifygc = true) {}
       
   164   ~NoGCVerifier() {}
       
   165 #endif
       
   166 };
       
   167 
       
   168 // A PauseNoGCVerifier is used to temporarily pause the behavior
       
   169 // of a NoGCVerifier object. If we are not in debug mode or if the
       
   170 // NoGCVerifier object has a _verifygc value of false, then there
       
   171 // is nothing to do.
       
   172 
       
   173 class PauseNoGCVerifier: public StackObj {
       
   174  private:
       
   175   NoGCVerifier * _ngcv;
       
   176 
       
   177  public:
       
   178 #ifdef ASSERT
       
   179   PauseNoGCVerifier(NoGCVerifier * ngcv);
       
   180   ~PauseNoGCVerifier();
       
   181 #else
       
   182   PauseNoGCVerifier(NoGCVerifier * ngcv) {}
       
   183   ~PauseNoGCVerifier() {}
       
   184 #endif
       
   185 };
       
   186 
       
   187 
       
   188 // A NoSafepointVerifier object will throw an assertion failure if
       
   189 // the current thread passes a possible safepoint while this object is
       
   190 // instantiated. A safepoint, will either be: an oop allocation, blocking
       
   191 // on a Mutex or JavaLock, or executing a VM operation.
       
   192 //
       
   193 // If StrictSafepointChecks is turned off, it degrades into a NoGCVerifier
       
   194 //
       
   195 class NoSafepointVerifier : public NoGCVerifier {
       
   196  friend class PauseNoSafepointVerifier;
       
   197 
       
   198  private:
       
   199   bool _activated;
       
   200   Thread *_thread;
       
   201  public:
       
   202 #ifdef ASSERT
       
   203   NoSafepointVerifier(bool activated = true, bool verifygc = true ) :
       
   204     NoGCVerifier(verifygc),
       
   205     _activated(activated) {
       
   206     _thread = Thread::current();
       
   207     if (_activated) {
       
   208       _thread->_allow_allocation_count++;
       
   209       _thread->_allow_safepoint_count++;
       
   210     }
       
   211   }
       
   212 
       
   213   ~NoSafepointVerifier() {
       
   214     if (_activated) {
       
   215       _thread->_allow_allocation_count--;
       
   216       _thread->_allow_safepoint_count--;
       
   217     }
       
   218   }
       
   219 #else
       
   220   NoSafepointVerifier(bool activated = true, bool verifygc = true) : NoGCVerifier(verifygc){}
       
   221   ~NoSafepointVerifier() {}
       
   222 #endif
       
   223 };
       
   224 
       
   225 // A PauseNoSafepointVerifier is used to temporarily pause the
       
   226 // behavior of a NoSafepointVerifier object. If we are not in debug
       
   227 // mode then there is nothing to do. If the NoSafepointVerifier
       
   228 // object has an _activated value of false, then there is nothing to
       
   229 // do for safepoint and allocation checking, but there may still be
       
   230 // something to do for the underlying NoGCVerifier object.
       
   231 
       
   232 class PauseNoSafepointVerifier : public PauseNoGCVerifier {
       
   233  private:
       
   234   NoSafepointVerifier * _nsv;
       
   235 
       
   236  public:
       
   237 #ifdef ASSERT
       
   238   PauseNoSafepointVerifier(NoSafepointVerifier * nsv)
       
   239     : PauseNoGCVerifier(nsv) {
       
   240 
       
   241     _nsv = nsv;
       
   242     if (_nsv->_activated) {
       
   243       _nsv->_thread->_allow_allocation_count--;
       
   244       _nsv->_thread->_allow_safepoint_count--;
       
   245     }
       
   246   }
       
   247 
       
   248   ~PauseNoSafepointVerifier() {
       
   249     if (_nsv->_activated) {
       
   250       _nsv->_thread->_allow_allocation_count++;
       
   251       _nsv->_thread->_allow_safepoint_count++;
       
   252     }
       
   253   }
       
   254 #else
       
   255   PauseNoSafepointVerifier(NoSafepointVerifier * nsv)
       
   256     : PauseNoGCVerifier(nsv) {}
       
   257   ~PauseNoSafepointVerifier() {}
       
   258 #endif
       
   259 };
       
   260 
       
   261 // A SkipGCALot object is used to elide the usual effect of gc-a-lot
       
   262 // over a section of execution by a thread. Currently, it's used only to
       
   263 // prevent re-entrant calls to GC.
       
   264 class SkipGCALot : public StackObj {
       
   265   private:
       
   266    bool _saved;
       
   267    Thread* _t;
       
   268 
       
   269   public:
       
   270 #ifdef ASSERT
       
   271     SkipGCALot(Thread* t) : _t(t) {
       
   272       _saved = _t->skip_gcalot();
       
   273       _t->set_skip_gcalot(true);
       
   274     }
       
   275 
       
   276     ~SkipGCALot() {
       
   277       assert(_t->skip_gcalot(), "Save-restore protocol invariant");
       
   278       _t->set_skip_gcalot(_saved);
       
   279     }
       
   280 #else
       
   281     SkipGCALot(Thread* t) { }
       
   282     ~SkipGCALot() { }
       
   283 #endif
       
   284 };
       
   285 
       
   286 // JRT_LEAF currently can be called from either _thread_in_Java or
       
   287 // _thread_in_native mode. In _thread_in_native, it is ok
       
   288 // for another thread to trigger GC. The rest of the JRT_LEAF
       
   289 // rules apply.
       
   290 class JRTLeafVerifier : public NoSafepointVerifier {
       
   291   static bool should_verify_GC();
       
   292  public:
       
   293 #ifdef ASSERT
       
   294   JRTLeafVerifier();
       
   295   ~JRTLeafVerifier();
       
   296 #else
       
   297   JRTLeafVerifier() {}
       
   298   ~JRTLeafVerifier() {}
       
   299 #endif
       
   300 };
       
   301 
       
   302 // A NoAllocVerifier object can be placed in methods where one assumes that
       
   303 // no allocation will occur. The destructor will verify this property
       
   304 // unless the constructor is called with argument false (not activated).
       
   305 //
       
   306 // The check will only be done in debug mode and if activated.
       
   307 // Note: this only makes sense at safepoints (otherwise, other threads may
       
   308 // allocate concurrently.)
       
   309 
       
   310 class NoAllocVerifier : public StackObj {
       
   311  private:
       
   312   bool  _activated;
       
   313 
       
   314  public:
       
   315 #ifdef ASSERT
       
   316   NoAllocVerifier(bool activated = true) {
       
   317     _activated = activated;
       
   318     if (_activated) Thread::current()->_allow_allocation_count++;
       
   319   }
       
   320 
       
   321   ~NoAllocVerifier() {
       
   322     if (_activated) Thread::current()->_allow_allocation_count--;
       
   323   }
       
   324 #else
       
   325   NoAllocVerifier(bool activated = true) {}
       
   326   ~NoAllocVerifier() {}
       
   327 #endif
       
   328 };
       
   329 
       
   330 #endif // SHARE_VM_GC_SHARED_GCLOCKER_HPP
   148 #endif // SHARE_VM_GC_SHARED_GCLOCKER_HPP