hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp
changeset 1 489c9b5090e2
child 360 21d113ecbf6a
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     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  */
       
    24 
       
    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;
       
    38 
       
    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 };
       
    56 
       
    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 };
       
    77 
       
    78 
       
    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);
       
    98 
       
    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 };
       
   110 
       
   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);
       
   131 
       
   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 };
       
   143 
       
   144 
       
   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   }
       
   176 
       
   177  private:
       
   178   inline void do_yield_check();
       
   179   void do_yield_work();
       
   180   bool take_from_overflow_list();
       
   181 };
       
   182 
       
   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 };
       
   209 
       
   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 };
       
   241 
       
   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 };
       
   279 
       
   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) { }
       
   296 
       
   297   void do_oop(oop* p);
       
   298   void do_oop_nv(oop* p) { CMSKeepAliveClosure::do_oop(p); }
       
   299 };
       
   300 
       
   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 };
       
   317 
       
   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 };