src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp

Fri, 09 May 2008 08:55:13 -0700

author
dcubed
date
Fri, 09 May 2008 08:55:13 -0700
changeset 587
c70a245cad3a
parent 435
a61af66fc99e
child 548
ba764ed4b6f2
permissions
-rw-r--r--

6670684: 4/5 SA command universe did not print out CMS space information
Summary: Forward port of Yumin's fix for 6670684 from HSX-11; Yumin verified the port was correct.
Reviewed-by: dcubed

     1 /*
     2  * Copyright (c) 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 /////////////////////////////////////////////////////////////////
    26 // Closures used by ConcurrentMarkSweepGeneration's collector
    27 /////////////////////////////////////////////////////////////////
    28 class ConcurrentMarkSweepGeneration;
    29 class CMSBitMap;
    30 class CMSMarkStack;
    31 class CMSCollector;
    32 template<class E> class GenericTaskQueue;
    33 typedef GenericTaskQueue<oop> OopTaskQueue;
    34 template<class E> class GenericTaskQueueSet;
    35 typedef GenericTaskQueueSet<oop> OopTaskQueueSet;
    36 class MarkFromRootsClosure;
    37 class Par_MarkFromRootsClosure;
    39 class MarkRefsIntoClosure: public OopsInGenClosure {
    40   const MemRegion    _span;
    41   CMSBitMap*         _bitMap;
    42   const bool         _should_do_nmethods;
    43  public:
    44   MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap,
    45                       bool should_do_nmethods);
    46   void do_oop(oop* p);
    47   void do_oop_nv(oop* p) { MarkRefsIntoClosure::do_oop(p); }
    48   bool do_header() { return true; }
    49   virtual const bool do_nmethods() const {
    50     return _should_do_nmethods;
    51   }
    52   Prefetch::style prefetch_style() {
    53     return Prefetch::do_read;
    54   }
    55 };
    57 // A variant of the above used in certain kinds of CMS
    58 // marking verification.
    59 class MarkRefsIntoVerifyClosure: public OopsInGenClosure {
    60   const MemRegion    _span;
    61   CMSBitMap*         _verification_bm;
    62   CMSBitMap*         _cms_bm;
    63   const bool         _should_do_nmethods;
    64  public:
    65   MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,
    66                             CMSBitMap* cms_bm, bool should_do_nmethods);
    67   void do_oop(oop* p);
    68   void do_oop_nv(oop* p) { MarkRefsIntoVerifyClosure::do_oop(p); }
    69   bool do_header() { return true; }
    70   virtual const bool do_nmethods() const {
    71     return _should_do_nmethods;
    72   }
    73   Prefetch::style prefetch_style() {
    74     return Prefetch::do_read;
    75   }
    76 };
    79 // The non-parallel version (the parallel version appears further below).
    80 class PushAndMarkClosure: public OopClosure {
    81   CMSCollector*    _collector;
    82   MemRegion        _span;
    83   CMSBitMap*       _bit_map;
    84   CMSBitMap*       _mod_union_table;
    85   CMSMarkStack*    _mark_stack;
    86   CMSMarkStack*    _revisit_stack;
    87   bool             _concurrent_precleaning;
    88   bool     const   _should_remember_klasses;
    89  public:
    90   PushAndMarkClosure(CMSCollector* collector,
    91                      MemRegion span,
    92                      ReferenceProcessor* rp,
    93                      CMSBitMap* bit_map,
    94                      CMSBitMap* mod_union_table,
    95                      CMSMarkStack*  mark_stack,
    96                      CMSMarkStack*  revisit_stack,
    97                      bool           concurrent_precleaning);
    99   void do_oop(oop* p);
   100   void do_oop_nv(oop* p)  { PushAndMarkClosure::do_oop(p); }
   101   bool do_header() { return true; }
   102   Prefetch::style prefetch_style() {
   103     return Prefetch::do_read;
   104   }
   105   const bool should_remember_klasses() const {
   106     return _should_remember_klasses;
   107   }
   108   void remember_klass(Klass* k);
   109 };
   111 // In the parallel case, the revisit stack, the bit map and the
   112 // reference processor are currently all shared. Access to
   113 // these shared mutable structures must use appropriate
   114 // synchronization (for instance, via CAS). The marking stack
   115 // used in the non-parallel case above is here replaced with
   116 // an OopTaskQueue structure to allow efficient work stealing.
   117 class Par_PushAndMarkClosure: public OopClosure {
   118   CMSCollector*    _collector;
   119   MemRegion        _span;
   120   CMSBitMap*       _bit_map;
   121   OopTaskQueue*    _work_queue;
   122   CMSMarkStack*    _revisit_stack;
   123   bool     const   _should_remember_klasses;
   124  public:
   125   Par_PushAndMarkClosure(CMSCollector* collector,
   126                          MemRegion span,
   127                          ReferenceProcessor* rp,
   128                          CMSBitMap* bit_map,
   129                          OopTaskQueue* work_queue,
   130                          CMSMarkStack* revisit_stack);
   132   void do_oop(oop* p);
   133   void do_oop_nv(oop* p)  { Par_PushAndMarkClosure::do_oop(p); }
   134   bool do_header() { return true; }
   135   Prefetch::style prefetch_style() {
   136     return Prefetch::do_read;
   137   }
   138   const bool should_remember_klasses() const {
   139     return _should_remember_klasses;
   140   }
   141   void remember_klass(Klass* k);
   142 };
   145 // The non-parallel version (the parallel version appears further below).
   146 class MarkRefsIntoAndScanClosure: public OopsInGenClosure {
   147   MemRegion                  _span;
   148   CMSBitMap*                 _bit_map;
   149   CMSMarkStack*              _mark_stack;
   150   PushAndMarkClosure         _pushAndMarkClosure;
   151   CMSCollector*              _collector;
   152   bool                       _yield;
   153   // Whether closure is being used for concurrent precleaning
   154   bool                       _concurrent_precleaning;
   155   Mutex*                     _freelistLock;
   156  public:
   157   MarkRefsIntoAndScanClosure(MemRegion span,
   158                              ReferenceProcessor* rp,
   159                              CMSBitMap* bit_map,
   160                              CMSBitMap* mod_union_table,
   161                              CMSMarkStack*  mark_stack,
   162                              CMSMarkStack*  revisit_stack,
   163                              CMSCollector* collector,
   164                              bool should_yield,
   165                              bool concurrent_precleaning);
   166   void do_oop(oop* p);
   167   void do_oop_nv(oop* p) { MarkRefsIntoAndScanClosure::do_oop(p); }
   168   bool do_header() { return true; }
   169   virtual const bool do_nmethods() const { return true; }
   170   Prefetch::style prefetch_style() {
   171     return Prefetch::do_read;
   172   }
   173   void set_freelistLock(Mutex* m) {
   174     _freelistLock = m;
   175   }
   177  private:
   178   inline void do_yield_check();
   179   void do_yield_work();
   180   bool take_from_overflow_list();
   181 };
   183 // Tn this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit
   184 // stack and the bitMap are shared, so access needs to be suitably
   185 // sycnhronized. An OopTaskQueue structure, supporting efficient
   186 // workstealing, replaces a CMSMarkStack for storing grey objects.
   187 class Par_MarkRefsIntoAndScanClosure: public OopsInGenClosure {
   188   MemRegion                      _span;
   189   CMSBitMap*                     _bit_map;
   190   OopTaskQueue*                  _work_queue;
   191   const uint                     _low_water_mark;
   192   Par_PushAndMarkClosure         _par_pushAndMarkClosure;
   193  public:
   194   Par_MarkRefsIntoAndScanClosure(CMSCollector* collector,
   195                                  MemRegion span,
   196                                  ReferenceProcessor* rp,
   197                                  CMSBitMap* bit_map,
   198                                  OopTaskQueue* work_queue,
   199                                  CMSMarkStack*  revisit_stack);
   200   void do_oop(oop* p);
   201   void do_oop_nv(oop* p) { Par_MarkRefsIntoAndScanClosure::do_oop(p); }
   202   bool do_header() { return true; }
   203   virtual const bool do_nmethods() const { return true; }
   204   Prefetch::style prefetch_style() {
   205     return Prefetch::do_read;
   206   }
   207   void trim_queue(uint size);
   208 };
   210 // This closure is used during the concurrent marking phase
   211 // following the first checkpoint. Its use is buried in
   212 // the closure MarkFromRootsClosure.
   213 class PushOrMarkClosure: public OopClosure {
   214   CMSCollector*    _collector;
   215   MemRegion        _span;
   216   CMSBitMap*       _bitMap;
   217   CMSMarkStack*    _markStack;
   218   CMSMarkStack*    _revisitStack;
   219   HeapWord* const  _finger;
   220   MarkFromRootsClosure* const _parent;
   221   bool                  const _should_remember_klasses;
   222  public:
   223   PushOrMarkClosure(CMSCollector* cms_collector,
   224                     MemRegion span,
   225                     CMSBitMap* bitMap,
   226                     CMSMarkStack*  markStack,
   227                     CMSMarkStack*  revisitStack,
   228                     HeapWord*      finger,
   229                     MarkFromRootsClosure* parent);
   230   void do_oop(oop* p);
   231   void do_oop_nv(oop* p)  { PushOrMarkClosure::do_oop(p); }
   232   const bool should_remember_klasses() const {
   233     return _should_remember_klasses;
   234   }
   235   void remember_klass(Klass* k);
   236   // Deal with a stack overflow condition
   237   void handle_stack_overflow(HeapWord* lost);
   238  private:
   239   inline void do_yield_check();
   240 };
   242 // A parallel (MT) version of the above.
   243 // This closure is used during the concurrent marking phase
   244 // following the first checkpoint. Its use is buried in
   245 // the closure Par_MarkFromRootsClosure.
   246 class Par_PushOrMarkClosure: public OopClosure {
   247   CMSCollector*    _collector;
   248   MemRegion        _whole_span;
   249   MemRegion        _span;        // local chunk
   250   CMSBitMap*       _bit_map;
   251   OopTaskQueue*    _work_queue;
   252   CMSMarkStack*    _overflow_stack;
   253   CMSMarkStack*    _revisit_stack;
   254   HeapWord*  const _finger;
   255   HeapWord** const _global_finger_addr;
   256   Par_MarkFromRootsClosure* const _parent;
   257   bool       const _should_remember_klasses;
   258  public:
   259   Par_PushOrMarkClosure(CMSCollector* cms_collector,
   260                     MemRegion span,
   261                     CMSBitMap* bit_map,
   262                     OopTaskQueue* work_queue,
   263                     CMSMarkStack*  mark_stack,
   264                     CMSMarkStack*  revisit_stack,
   265                     HeapWord*      finger,
   266                     HeapWord**     global_finger_addr,
   267                     Par_MarkFromRootsClosure* parent);
   268   void do_oop(oop* p);
   269   void do_oop_nv(oop* p)  { Par_PushOrMarkClosure::do_oop(p); }
   270   const bool should_remember_klasses() const {
   271     return _should_remember_klasses;
   272   }
   273   void remember_klass(Klass* k);
   274   // Deal with a stack overflow condition
   275   void handle_stack_overflow(HeapWord* lost);
   276  private:
   277   inline void do_yield_check();
   278 };
   280 // For objects in CMS generation, this closure marks
   281 // given objects (transitively) as being reachable/live.
   282 // This is currently used during the (weak) reference object
   283 // processing phase of the CMS final checkpoint step.
   284 class CMSKeepAliveClosure: public OopClosure {
   285   CMSCollector* _collector;
   286   MemRegion     _span;
   287   CMSMarkStack* _mark_stack;
   288   CMSBitMap*    _bit_map;
   289  public:
   290   CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
   291                       CMSBitMap* bit_map, CMSMarkStack* mark_stack):
   292     _collector(collector),
   293     _span(span),
   294     _bit_map(bit_map),
   295     _mark_stack(mark_stack) { }
   297   void do_oop(oop* p);
   298   void do_oop_nv(oop* p) { CMSKeepAliveClosure::do_oop(p); }
   299 };
   301 class CMSInnerParMarkAndPushClosure: public OopClosure {
   302   CMSCollector* _collector;
   303   MemRegion     _span;
   304   OopTaskQueue* _work_queue;
   305   CMSBitMap*    _bit_map;
   306  public:
   307   CMSInnerParMarkAndPushClosure(CMSCollector* collector,
   308                                 MemRegion span, CMSBitMap* bit_map,
   309                                 OopTaskQueue* work_queue):
   310     _collector(collector),
   311     _span(span),
   312     _bit_map(bit_map),
   313     _work_queue(work_queue) { }
   314   void do_oop(oop* p);
   315   void do_oop_nv(oop* p) { CMSInnerParMarkAndPushClosure::do_oop(p); }
   316 };
   318 // A parallel (MT) version of the above, used when
   319 // reference processing is parallel; the only difference
   320 // is in the do_oop method.
   321 class CMSParKeepAliveClosure: public OopClosure {
   322   CMSCollector* _collector;
   323   MemRegion     _span;
   324   OopTaskQueue* _work_queue;
   325   CMSBitMap*    _bit_map;
   326   CMSInnerParMarkAndPushClosure _mark_and_push;
   327   const uint    _low_water_mark;
   328   void trim_queue(uint max);
   329  public:
   330   CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span,
   331                          CMSBitMap* bit_map, OopTaskQueue* work_queue);
   332   void do_oop(oop* p);
   333   void do_oop_nv(oop* p) { CMSParKeepAliveClosure::do_oop(p); }
   334 };

mercurial