src/hotspot/share/gc/cms/cmsOopClosures.hpp
branchaefimov-dns-client-branch
changeset 59099 fcdb8e7ead8f
parent 58984 15e026239a6c
parent 59075 355f4f42dda5
child 59100 b92aac38b046
equal deleted inserted replaced
58984:15e026239a6c 59099:fcdb8e7ead8f
     1 /*
       
     2  * Copyright (c) 2007, 2019, 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  */
       
    24 
       
    25 #ifndef SHARE_GC_CMS_CMSOOPCLOSURES_HPP
       
    26 #define SHARE_GC_CMS_CMSOOPCLOSURES_HPP
       
    27 
       
    28 #include "gc/shared/genOopClosures.hpp"
       
    29 #include "gc/shared/taskqueue.hpp"
       
    30 #include "memory/iterator.hpp"
       
    31 
       
    32 /////////////////////////////////////////////////////////////////
       
    33 // Closures used by ConcurrentMarkSweepGeneration's collector
       
    34 /////////////////////////////////////////////////////////////////
       
    35 class ConcurrentMarkSweepGeneration;
       
    36 class CMSBitMap;
       
    37 class CMSMarkStack;
       
    38 class CMSCollector;
       
    39 class MarkFromRootsClosure;
       
    40 class ParMarkFromRootsClosure;
       
    41 
       
    42 class Mutex;
       
    43 
       
    44 // Decode the oop and call do_oop on it.
       
    45 #define DO_OOP_WORK_DEFN                             \
       
    46   void do_oop(oop obj);                              \
       
    47   template <class T> inline void do_oop_work(T* p);
       
    48 
       
    49 // TODO: This duplication of the MetadataVisitingOopIterateClosure class is only needed
       
    50 //       because some CMS OopClosures derive from OopsInGenClosure. It would be
       
    51 //       good to get rid of them completely.
       
    52 class MetadataVisitingOopsInGenClosure: public OopsInGenClosure {
       
    53  public:
       
    54   virtual bool do_metadata() { return true; }
       
    55   virtual void do_klass(Klass* k);
       
    56   virtual void do_cld(ClassLoaderData* cld);
       
    57 };
       
    58 
       
    59 class MarkRefsIntoClosure: public MetadataVisitingOopsInGenClosure {
       
    60  private:
       
    61   const MemRegion _span;
       
    62   CMSBitMap*      _bitMap;
       
    63  protected:
       
    64   DO_OOP_WORK_DEFN
       
    65  public:
       
    66   MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
       
    67   virtual void do_oop(oop* p);
       
    68   virtual void do_oop(narrowOop* p);
       
    69 };
       
    70 
       
    71 class ParMarkRefsIntoClosure: public MetadataVisitingOopsInGenClosure {
       
    72  private:
       
    73   const MemRegion _span;
       
    74   CMSBitMap*      _bitMap;
       
    75  protected:
       
    76   DO_OOP_WORK_DEFN
       
    77  public:
       
    78   ParMarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
       
    79   virtual void do_oop(oop* p);
       
    80   virtual void do_oop(narrowOop* p);
       
    81 };
       
    82 
       
    83 // A variant of the above used in certain kinds of CMS
       
    84 // marking verification.
       
    85 class MarkRefsIntoVerifyClosure: public MetadataVisitingOopsInGenClosure {
       
    86  private:
       
    87   const MemRegion _span;
       
    88   CMSBitMap*      _verification_bm;
       
    89   CMSBitMap*      _cms_bm;
       
    90  protected:
       
    91   DO_OOP_WORK_DEFN
       
    92  public:
       
    93   MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,
       
    94                             CMSBitMap* cms_bm);
       
    95   virtual void do_oop(oop* p);
       
    96   virtual void do_oop(narrowOop* p);
       
    97 };
       
    98 
       
    99 // The non-parallel version (the parallel version appears further below).
       
   100 class PushAndMarkClosure: public MetadataVisitingOopIterateClosure {
       
   101  private:
       
   102   CMSCollector* _collector;
       
   103   MemRegion     _span;
       
   104   CMSBitMap*    _bit_map;
       
   105   CMSBitMap*    _mod_union_table;
       
   106   CMSMarkStack* _mark_stack;
       
   107   bool          _concurrent_precleaning;
       
   108  protected:
       
   109   DO_OOP_WORK_DEFN
       
   110  public:
       
   111   PushAndMarkClosure(CMSCollector* collector,
       
   112                      MemRegion span,
       
   113                      ReferenceDiscoverer* rd,
       
   114                      CMSBitMap* bit_map,
       
   115                      CMSBitMap* mod_union_table,
       
   116                      CMSMarkStack* mark_stack,
       
   117                      bool concurrent_precleaning);
       
   118   virtual void do_oop(oop* p);
       
   119   virtual void do_oop(narrowOop* p);
       
   120 };
       
   121 
       
   122 // In the parallel case, the bit map and the
       
   123 // reference processor are currently all shared. Access to
       
   124 // these shared mutable structures must use appropriate
       
   125 // synchronization (for instance, via CAS). The marking stack
       
   126 // used in the non-parallel case above is here replaced with
       
   127 // an OopTaskQueue structure to allow efficient work stealing.
       
   128 class ParPushAndMarkClosure: public MetadataVisitingOopIterateClosure {
       
   129  private:
       
   130   CMSCollector* _collector;
       
   131   MemRegion     _span;
       
   132   CMSBitMap*    _bit_map;
       
   133   OopTaskQueue* _work_queue;
       
   134  protected:
       
   135   DO_OOP_WORK_DEFN
       
   136  public:
       
   137   ParPushAndMarkClosure(CMSCollector* collector,
       
   138                         MemRegion span,
       
   139                         ReferenceDiscoverer* rd,
       
   140                         CMSBitMap* bit_map,
       
   141                         OopTaskQueue* work_queue);
       
   142   virtual void do_oop(oop* p);
       
   143   virtual void do_oop(narrowOop* p);
       
   144 };
       
   145 
       
   146 // The non-parallel version (the parallel version appears further below).
       
   147 class MarkRefsIntoAndScanClosure: public MetadataVisitingOopsInGenClosure {
       
   148  private:
       
   149   MemRegion          _span;
       
   150   CMSBitMap*         _bit_map;
       
   151   CMSMarkStack*      _mark_stack;
       
   152   PushAndMarkClosure _pushAndMarkClosure;
       
   153   CMSCollector*      _collector;
       
   154   Mutex*             _freelistLock;
       
   155   bool               _yield;
       
   156   // Whether closure is being used for concurrent precleaning
       
   157   bool               _concurrent_precleaning;
       
   158  protected:
       
   159   DO_OOP_WORK_DEFN
       
   160  public:
       
   161   MarkRefsIntoAndScanClosure(MemRegion span,
       
   162                              ReferenceDiscoverer* rd,
       
   163                              CMSBitMap* bit_map,
       
   164                              CMSBitMap* mod_union_table,
       
   165                              CMSMarkStack* mark_stack,
       
   166                              CMSCollector* collector,
       
   167                              bool should_yield,
       
   168                              bool concurrent_precleaning);
       
   169   virtual void do_oop(oop* p);
       
   170   virtual void do_oop(narrowOop* p);
       
   171 
       
   172   void set_freelistLock(Mutex* m) {
       
   173     _freelistLock = m;
       
   174   }
       
   175 
       
   176  private:
       
   177   inline void do_yield_check();
       
   178   void do_yield_work();
       
   179   bool take_from_overflow_list();
       
   180 };
       
   181 
       
   182 // In this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit
       
   183 // stack and the bitMap are shared, so access needs to be suitably
       
   184 // synchronized. An OopTaskQueue structure, supporting efficient
       
   185 // work stealing, replaces a CMSMarkStack for storing grey objects.
       
   186 class ParMarkRefsIntoAndScanClosure: public MetadataVisitingOopsInGenClosure {
       
   187  private:
       
   188   MemRegion             _span;
       
   189   CMSBitMap*            _bit_map;
       
   190   OopTaskQueue*         _work_queue;
       
   191   const uint            _low_water_mark;
       
   192   ParPushAndMarkClosure _parPushAndMarkClosure;
       
   193  protected:
       
   194   DO_OOP_WORK_DEFN
       
   195  public:
       
   196   ParMarkRefsIntoAndScanClosure(CMSCollector* collector,
       
   197                                  MemRegion span,
       
   198                                  ReferenceDiscoverer* rd,
       
   199                                  CMSBitMap* bit_map,
       
   200                                  OopTaskQueue* work_queue);
       
   201   virtual void do_oop(oop* p);
       
   202   virtual void do_oop(narrowOop* p);
       
   203 
       
   204   void trim_queue(uint size);
       
   205 };
       
   206 
       
   207 // This closure is used during the concurrent marking phase
       
   208 // following the first checkpoint. Its use is buried in
       
   209 // the closure MarkFromRootsClosure.
       
   210 class PushOrMarkClosure: public MetadataVisitingOopIterateClosure {
       
   211  private:
       
   212   CMSCollector*   _collector;
       
   213   MemRegion       _span;
       
   214   CMSBitMap*      _bitMap;
       
   215   CMSMarkStack*   _markStack;
       
   216   HeapWord* const _finger;
       
   217   MarkFromRootsClosure* const
       
   218                   _parent;
       
   219  protected:
       
   220   DO_OOP_WORK_DEFN
       
   221  public:
       
   222   PushOrMarkClosure(CMSCollector* cms_collector,
       
   223                     MemRegion span,
       
   224                     CMSBitMap* bitMap,
       
   225                     CMSMarkStack* markStack,
       
   226                     HeapWord* finger,
       
   227                     MarkFromRootsClosure* parent);
       
   228   virtual void do_oop(oop* p);
       
   229   virtual void do_oop(narrowOop* p);
       
   230 
       
   231   // Deal with a stack overflow condition
       
   232   void handle_stack_overflow(HeapWord* lost);
       
   233  private:
       
   234   inline void do_yield_check();
       
   235 };
       
   236 
       
   237 // A parallel (MT) version of the above.
       
   238 // This closure is used during the concurrent marking phase
       
   239 // following the first checkpoint. Its use is buried in
       
   240 // the closure ParMarkFromRootsClosure.
       
   241 class ParPushOrMarkClosure: public MetadataVisitingOopIterateClosure {
       
   242  private:
       
   243   CMSCollector*                  _collector;
       
   244   MemRegion                      _whole_span;
       
   245   MemRegion                      _span;       // local chunk
       
   246   CMSBitMap*                     _bit_map;
       
   247   OopTaskQueue*                  _work_queue;
       
   248   CMSMarkStack*                  _overflow_stack;
       
   249   HeapWord*  const               _finger;
       
   250   HeapWord* volatile* const      _global_finger_addr;
       
   251   ParMarkFromRootsClosure* const _parent;
       
   252  protected:
       
   253   DO_OOP_WORK_DEFN
       
   254  public:
       
   255   ParPushOrMarkClosure(CMSCollector* cms_collector,
       
   256                        MemRegion span,
       
   257                        CMSBitMap* bit_map,
       
   258                        OopTaskQueue* work_queue,
       
   259                        CMSMarkStack* mark_stack,
       
   260                        HeapWord* finger,
       
   261                        HeapWord* volatile* global_finger_addr,
       
   262                        ParMarkFromRootsClosure* parent);
       
   263   virtual void do_oop(oop* p);
       
   264   virtual void do_oop(narrowOop* p);
       
   265 
       
   266   // Deal with a stack overflow condition
       
   267   void handle_stack_overflow(HeapWord* lost);
       
   268  private:
       
   269   inline void do_yield_check();
       
   270 };
       
   271 
       
   272 // For objects in CMS generation, this closure marks
       
   273 // given objects (transitively) as being reachable/live.
       
   274 // This is currently used during the (weak) reference object
       
   275 // processing phase of the CMS final checkpoint step, as
       
   276 // well as during the concurrent precleaning of the discovered
       
   277 // reference lists.
       
   278 class CMSKeepAliveClosure: public MetadataVisitingOopIterateClosure {
       
   279  private:
       
   280   CMSCollector* _collector;
       
   281   const MemRegion _span;
       
   282   CMSMarkStack* _mark_stack;
       
   283   CMSBitMap*    _bit_map;
       
   284   bool          _concurrent_precleaning;
       
   285  protected:
       
   286   DO_OOP_WORK_DEFN
       
   287  public:
       
   288   CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
       
   289                       CMSBitMap* bit_map, CMSMarkStack* mark_stack,
       
   290                       bool cpc);
       
   291   bool    concurrent_precleaning() const { return _concurrent_precleaning; }
       
   292   virtual void do_oop(oop* p);
       
   293   virtual void do_oop(narrowOop* p);
       
   294 };
       
   295 
       
   296 class CMSInnerParMarkAndPushClosure: public MetadataVisitingOopIterateClosure {
       
   297  private:
       
   298   CMSCollector* _collector;
       
   299   MemRegion     _span;
       
   300   OopTaskQueue* _work_queue;
       
   301   CMSBitMap*    _bit_map;
       
   302  protected:
       
   303   DO_OOP_WORK_DEFN
       
   304  public:
       
   305   CMSInnerParMarkAndPushClosure(CMSCollector* collector,
       
   306                                 MemRegion span, CMSBitMap* bit_map,
       
   307                                 OopTaskQueue* work_queue);
       
   308   virtual void do_oop(oop* p);
       
   309   virtual void do_oop(narrowOop* p);
       
   310 };
       
   311 
       
   312 // A parallel (MT) version of the above, used when
       
   313 // reference processing is parallel; the only difference
       
   314 // is in the do_oop method.
       
   315 class CMSParKeepAliveClosure: public MetadataVisitingOopIterateClosure {
       
   316  private:
       
   317   MemRegion     _span;
       
   318   OopTaskQueue* _work_queue;
       
   319   CMSBitMap*    _bit_map;
       
   320   CMSInnerParMarkAndPushClosure
       
   321                 _mark_and_push;
       
   322   const uint    _low_water_mark;
       
   323   void trim_queue(uint max);
       
   324  protected:
       
   325   DO_OOP_WORK_DEFN
       
   326  public:
       
   327   CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span,
       
   328                          CMSBitMap* bit_map, OopTaskQueue* work_queue);
       
   329   virtual void do_oop(oop* p);
       
   330   virtual void do_oop(narrowOop* p);
       
   331 };
       
   332 
       
   333 #endif // SHARE_GC_CMS_CMSOOPCLOSURES_HPP