src/share/vm/memory/gcLocker.hpp

Sun, 25 Sep 2011 16:03:29 -0700

author
never
date
Sun, 25 Sep 2011 16:03:29 -0700
changeset 3156
f08d439fab8c
parent 2314
f95d63e2154a
child 3494
1a2723f7ad8e
permissions
-rw-r--r--

7089790: integrate bsd-port changes
Reviewed-by: kvn, twisti, jrose
Contributed-by: Kurt Miller <kurt@intricatesoftware.com>, Greg Lewis <glewis@eyesbeyond.com>, Jung-uk Kim <jkim@freebsd.org>, Christos Zoulas <christos@zoulas.com>, Landon Fuller <landonf@plausible.coop>, The FreeBSD Foundation <board@freebsdfoundation.org>, Michael Franz <mvfranz@gmail.com>, Roger Hoover <rhoover@apple.com>, Alexander Strange <astrange@apple.com>

     1 /*
     2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_MEMORY_GCLOCKER_HPP
    26 #define SHARE_VM_MEMORY_GCLOCKER_HPP
    28 #include "gc_interface/collectedHeap.hpp"
    29 #include "memory/genCollectedHeap.hpp"
    30 #include "memory/universe.hpp"
    31 #include "oops/oop.hpp"
    32 #ifdef TARGET_OS_FAMILY_linux
    33 # include "os_linux.inline.hpp"
    34 # include "thread_linux.inline.hpp"
    35 #endif
    36 #ifdef TARGET_OS_FAMILY_solaris
    37 # include "os_solaris.inline.hpp"
    38 # include "thread_solaris.inline.hpp"
    39 #endif
    40 #ifdef TARGET_OS_FAMILY_windows
    41 # include "os_windows.inline.hpp"
    42 # include "thread_windows.inline.hpp"
    43 #endif
    44 #ifdef TARGET_OS_FAMILY_bsd
    45 # include "os_bsd.inline.hpp"
    46 # include "thread_bsd.inline.hpp"
    47 #endif
    49 // The direct lock/unlock calls do not force a collection if an unlock
    50 // decrements the count to zero. Avoid calling these if at all possible.
    52 class GC_locker: public AllStatic {
    53  private:
    54   static volatile jint _jni_lock_count;  // number of jni active instances
    55   static volatile jint _lock_count;      // number of other active instances
    56   static volatile bool _needs_gc;        // heap is filling, we need a GC
    57                                          // note: bool is typedef'd as jint
    58   static volatile bool _doing_gc;        // unlock_critical() is doing a GC
    60   // Accessors
    61   static bool is_jni_active() {
    62     return _jni_lock_count > 0;
    63   }
    65   static void set_needs_gc() {
    66     assert(SafepointSynchronize::is_at_safepoint(),
    67       "needs_gc is only set at a safepoint");
    68     _needs_gc = true;
    69   }
    71   static void clear_needs_gc() {
    72     assert_lock_strong(JNICritical_lock);
    73     _needs_gc = false;
    74   }
    76   static void jni_lock() {
    77     Atomic::inc(&_jni_lock_count);
    78     CHECK_UNHANDLED_OOPS_ONLY(
    79       if (CheckUnhandledOops) { Thread::current()->_gc_locked_out_count++; })
    80     assert(Universe::heap() == NULL || !Universe::heap()->is_gc_active(),
    81            "locking failed");
    82   }
    84   static void jni_unlock() {
    85     Atomic::dec(&_jni_lock_count);
    86     CHECK_UNHANDLED_OOPS_ONLY(
    87       if (CheckUnhandledOops) { Thread::current()->_gc_locked_out_count--; })
    88   }
    90   static void jni_lock_slow();
    91   static void jni_unlock_slow();
    93  public:
    94   // Accessors
    95   static bool is_active();
    96   static bool needs_gc()       { return _needs_gc;                        }
    97   // Shorthand
    98   static bool is_active_and_needs_gc() { return is_active() && needs_gc();}
   100   // Calls set_needs_gc() if is_active() is true. Returns is_active().
   101   static bool check_active_before_gc();
   103   // Stalls the caller (who should not be in a jni critical section)
   104   // until needs_gc() clears. Note however that needs_gc() may be
   105   // set at a subsequent safepoint and/or cleared under the
   106   // JNICritical_lock, so the caller may not safely assert upon
   107   // return from this method that "!needs_gc()" since that is
   108   // not a stable predicate.
   109   static void stall_until_clear();
   111   // Non-structured GC locking: currently needed for JNI. Use with care!
   112   static void lock();
   113   static void unlock();
   115   // The following two methods are used for JNI critical regions.
   116   // If we find that we failed to perform a GC because the GC_locker
   117   // was active, arrange for one as soon as possible by allowing
   118   // all threads in critical regions to complete, but not allowing
   119   // other critical regions to be entered. The reasons for that are:
   120   // 1) a GC request won't be starved by overlapping JNI critical
   121   //    region activities, which can cause unnecessary OutOfMemory errors.
   122   // 2) even if allocation requests can still be satisfied before GC locker
   123   //    becomes inactive, for example, in tenured generation possibly with
   124   //    heap expansion, those allocations can trigger lots of safepointing
   125   //    attempts (ineffective GC attempts) and require Heap_lock which
   126   //    slow down allocations tremendously.
   127   //
   128   // Note that critical regions can be nested in a single thread, so
   129   // we must allow threads already in critical regions to continue.
   130   //
   131   // JNI critical regions are the only participants in this scheme
   132   // because they are, by spec, well bounded while in a critical region.
   133   //
   134   // Each of the following two method is split into a fast path and a slow
   135   // path. JNICritical_lock is only grabbed in the slow path.
   136   // _needs_gc is initially false and every java thread will go
   137   // through the fast path (which does the same thing as the slow path
   138   // when _needs_gc is false). When GC happens at a safepoint,
   139   // GC_locker::is_active() is checked. Since there is no safepoint in the
   140   // fast path of lock_critical() and unlock_critical(), there is no race
   141   // condition between the fast path and GC. After _needs_gc is set at a
   142   // safepoint, every thread will go through the slow path after the safepoint.
   143   // Since after a safepoint, each of the following two methods is either
   144   // entered from the method entry and falls into the slow path, or is
   145   // resumed from the safepoints in the method, which only exist in the slow
   146   // path. So when _needs_gc is set, the slow path is always taken, till
   147   // _needs_gc is cleared.
   148   static void lock_critical(JavaThread* thread);
   149   static void unlock_critical(JavaThread* thread);
   150 };
   153 // A No_GC_Verifier object can be placed in methods where one assumes that
   154 // no garbage collection will occur. The destructor will verify this property
   155 // unless the constructor is called with argument false (not verifygc).
   156 //
   157 // The check will only be done in debug mode and if verifygc true.
   159 class No_GC_Verifier: public StackObj {
   160  friend class Pause_No_GC_Verifier;
   162  protected:
   163   bool _verifygc;
   164   unsigned int _old_invocations;
   166  public:
   167 #ifdef ASSERT
   168   No_GC_Verifier(bool verifygc = true);
   169   ~No_GC_Verifier();
   170 #else
   171   No_GC_Verifier(bool verifygc = true) {}
   172   ~No_GC_Verifier() {}
   173 #endif
   174 };
   176 // A Pause_No_GC_Verifier is used to temporarily pause the behavior
   177 // of a No_GC_Verifier object. If we are not in debug mode or if the
   178 // No_GC_Verifier object has a _verifygc value of false, then there
   179 // is nothing to do.
   181 class Pause_No_GC_Verifier: public StackObj {
   182  private:
   183   No_GC_Verifier * _ngcv;
   185  public:
   186 #ifdef ASSERT
   187   Pause_No_GC_Verifier(No_GC_Verifier * ngcv);
   188   ~Pause_No_GC_Verifier();
   189 #else
   190   Pause_No_GC_Verifier(No_GC_Verifier * ngcv) {}
   191   ~Pause_No_GC_Verifier() {}
   192 #endif
   193 };
   196 // A No_Safepoint_Verifier object will throw an assertion failure if
   197 // the current thread passes a possible safepoint while this object is
   198 // instantiated. A safepoint, will either be: an oop allocation, blocking
   199 // on a Mutex or JavaLock, or executing a VM operation.
   200 //
   201 // If StrictSafepointChecks is turned off, it degrades into a No_GC_Verifier
   202 //
   203 class No_Safepoint_Verifier : public No_GC_Verifier {
   204  friend class Pause_No_Safepoint_Verifier;
   206  private:
   207   bool _activated;
   208   Thread *_thread;
   209  public:
   210 #ifdef ASSERT
   211   No_Safepoint_Verifier(bool activated = true, bool verifygc = true ) :
   212     No_GC_Verifier(verifygc),
   213     _activated(activated) {
   214     _thread = Thread::current();
   215     if (_activated) {
   216       _thread->_allow_allocation_count++;
   217       _thread->_allow_safepoint_count++;
   218     }
   219   }
   221   ~No_Safepoint_Verifier() {
   222     if (_activated) {
   223       _thread->_allow_allocation_count--;
   224       _thread->_allow_safepoint_count--;
   225     }
   226   }
   227 #else
   228   No_Safepoint_Verifier(bool activated = true, bool verifygc = true) : No_GC_Verifier(verifygc){}
   229   ~No_Safepoint_Verifier() {}
   230 #endif
   231 };
   233 // A Pause_No_Safepoint_Verifier is used to temporarily pause the
   234 // behavior of a No_Safepoint_Verifier object. If we are not in debug
   235 // mode then there is nothing to do. If the No_Safepoint_Verifier
   236 // object has an _activated value of false, then there is nothing to
   237 // do for safepoint and allocation checking, but there may still be
   238 // something to do for the underlying No_GC_Verifier object.
   240 class Pause_No_Safepoint_Verifier : public Pause_No_GC_Verifier {
   241  private:
   242   No_Safepoint_Verifier * _nsv;
   244  public:
   245 #ifdef ASSERT
   246   Pause_No_Safepoint_Verifier(No_Safepoint_Verifier * nsv)
   247     : Pause_No_GC_Verifier(nsv) {
   249     _nsv = nsv;
   250     if (_nsv->_activated) {
   251       _nsv->_thread->_allow_allocation_count--;
   252       _nsv->_thread->_allow_safepoint_count--;
   253     }
   254   }
   256   ~Pause_No_Safepoint_Verifier() {
   257     if (_nsv->_activated) {
   258       _nsv->_thread->_allow_allocation_count++;
   259       _nsv->_thread->_allow_safepoint_count++;
   260     }
   261   }
   262 #else
   263   Pause_No_Safepoint_Verifier(No_Safepoint_Verifier * nsv)
   264     : Pause_No_GC_Verifier(nsv) {}
   265   ~Pause_No_Safepoint_Verifier() {}
   266 #endif
   267 };
   269 // A SkipGCALot object is used to elide the usual effect of gc-a-lot
   270 // over a section of execution by a thread. Currently, it's used only to
   271 // prevent re-entrant calls to GC.
   272 class SkipGCALot : public StackObj {
   273   private:
   274    bool _saved;
   275    Thread* _t;
   277   public:
   278 #ifdef ASSERT
   279     SkipGCALot(Thread* t) : _t(t) {
   280       _saved = _t->skip_gcalot();
   281       _t->set_skip_gcalot(true);
   282     }
   284     ~SkipGCALot() {
   285       assert(_t->skip_gcalot(), "Save-restore protocol invariant");
   286       _t->set_skip_gcalot(_saved);
   287     }
   288 #else
   289     SkipGCALot(Thread* t) { }
   290     ~SkipGCALot() { }
   291 #endif
   292 };
   294 // JRT_LEAF currently can be called from either _thread_in_Java or
   295 // _thread_in_native mode. In _thread_in_native, it is ok
   296 // for another thread to trigger GC. The rest of the JRT_LEAF
   297 // rules apply.
   298 class JRT_Leaf_Verifier : public No_Safepoint_Verifier {
   299   static bool should_verify_GC();
   300  public:
   301 #ifdef ASSERT
   302   JRT_Leaf_Verifier();
   303   ~JRT_Leaf_Verifier();
   304 #else
   305   JRT_Leaf_Verifier() {}
   306   ~JRT_Leaf_Verifier() {}
   307 #endif
   308 };
   310 // A No_Alloc_Verifier object can be placed in methods where one assumes that
   311 // no allocation will occur. The destructor will verify this property
   312 // unless the constructor is called with argument false (not activated).
   313 //
   314 // The check will only be done in debug mode and if activated.
   315 // Note: this only makes sense at safepoints (otherwise, other threads may
   316 // allocate concurrently.)
   318 class No_Alloc_Verifier : public StackObj {
   319  private:
   320   bool  _activated;
   322  public:
   323 #ifdef ASSERT
   324   No_Alloc_Verifier(bool activated = true) {
   325     _activated = activated;
   326     if (_activated) Thread::current()->_allow_allocation_count++;
   327   }
   329   ~No_Alloc_Verifier() {
   330     if (_activated) Thread::current()->_allow_allocation_count--;
   331   }
   332 #else
   333   No_Alloc_Verifier(bool activated = true) {}
   334   ~No_Alloc_Verifier() {}
   335 #endif
   336 };
   338 #endif // SHARE_VM_MEMORY_GCLOCKER_HPP

mercurial