1 /*
   2  * Copyright (c) 2015, 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_VM_GC_G1_G1SCAVENGECLOSURES_HPP
  26 #define SHARE_VM_GC_G1_G1SCAVENGECLOSURES_HPP
  27 
  28 #include "gc/g1/bufferingOopClosure.hpp"
  29 #include "gc/g1/g1CodeBlobClosure.hpp"
  30 #include "gc/g1/g1OopClosures.hpp"
  31 #include "gc/g1/g1RootClosures.hpp"
  32 
  33 class G1CollectedHeap;
  34 class G1ParScanThreadState;
  35 
  36 // Simple holder object for a complete set of closures used by the G1 evacuation code.
  37 template <G1Mark Mark>
  38 class G1SharedClosures VALUE_OBJ_CLASS_SPEC {
  39 public:
  40   G1ParCopyClosure<G1BarrierNone, Mark> _oops;
  41   G1ParCopyClosure<G1BarrierKlass, Mark> _oop_in_klass;
  42   G1KlassScanClosure _klass_in_cld_closure;
  43   CLDToKlassAndOopClosure _clds;
  44   G1CodeBlobClosure _codeblobs;
  45   BufferingOopClosure _buffered_oops;
  46 
  47   G1SharedClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss, bool process_only_dirty_klasses, bool must_claim_cld) :
  48     _oops(g1h, pss),
  49     _oop_in_klass(g1h, pss),
  50     _klass_in_cld_closure(&_oop_in_klass, process_only_dirty_klasses),
  51     _clds(&_klass_in_cld_closure, &_oops, must_claim_cld),
  52     _codeblobs(&_oops),
  53     _buffered_oops(&_oops) {}
  54 };
  55 
  56 class G1EvacuationClosures : public G1EvacuationRootClosures {
  57   G1SharedClosures<G1MarkNone> _closures;
  58 
  59 public:
  60   G1EvacuationClosures(G1CollectedHeap* g1h,
  61                        G1ParScanThreadState* pss,
  62                        bool gcs_are_young) :
  63       _closures(g1h, pss, gcs_are_young, /* must_claim_cld */ false) {}
  64 
  65   OopClosure* weak_oops()   { return &_closures._buffered_oops; }
  66   OopClosure* strong_oops() { return &_closures._buffered_oops; }
  67 
  68   CLDClosure* weak_clds()             { return &_closures._clds; }
  69   CLDClosure* strong_clds()           { return &_closures._clds; }
  70   CLDClosure* thread_root_clds()      { return NULL; }
  71   CLDClosure* second_pass_weak_clds() { return NULL; }
  72 
  73   CodeBlobClosure* strong_codeblobs()      { return &_closures._codeblobs; }
  74   CodeBlobClosure* weak_codeblobs()        { return &_closures._codeblobs; }
  75   CodeBlobClosure* thread_root_codeblobs() { return &_closures._codeblobs; }
  76 
  77   void flush() { _closures._buffered_oops.done(); }
  78   double closure_app_seconds() { return _closures._buffered_oops.closure_app_seconds(); }
  79 
  80   virtual OopClosure* raw_weak_oops() { return &_closures._oops; }
  81   virtual OopClosure* raw_strong_oops() { return &_closures._oops; }
  82 };
  83 
  84 // Closures used during initial mark.
  85 // The treatment of "weak" roots is selectable through the template parameter,
  86 // this is usually used to control unloading of classes and interned strings.
  87 template <G1Mark MarkWeak>
  88 class G1InitalMarkClosures : public G1EvacuationRootClosures {
  89   G1SharedClosures<G1MarkFromRoot> _strong;
  90   G1SharedClosures<MarkWeak>       _weak;
  91 
  92   // Filter method to help with returning the appropriate closures
  93   // depending on the class template parameter.
  94   template <G1Mark Mark, typename T>
  95   T* null_if(T* t) {
  96     if (Mark == MarkWeak) {
  97       return NULL;
  98     }
  99     return t;
 100   }
 101 
 102 public:
 103   G1InitalMarkClosures(G1CollectedHeap* g1h,
 104                        G1ParScanThreadState* pss) :
 105       _strong(g1h, pss, /* process_only_dirty_klasses */ false, /* must_claim_cld */ true),
 106       _weak(g1h, pss, /* process_only_dirty_klasses */ false, /* must_claim_cld */ true) {}
 107 
 108   OopClosure* weak_oops()   { return &_weak._buffered_oops; }
 109   OopClosure* strong_oops() { return &_strong._buffered_oops; }
 110 
 111   // If MarkWeak is G1MarkPromotedFromRoot then the weak CLDs must be processed in a second pass.
 112   CLDClosure* weak_clds()             { return null_if<G1MarkPromotedFromRoot>(&_weak._clds); }
 113   CLDClosure* strong_clds()           { return &_strong._clds; }
 114 
 115   // If MarkWeak is G1MarkFromRoot then all CLDs are processed by the weak and strong variants
 116   // return a NULL closure for the following specialized versions in that case.
 117   CLDClosure* thread_root_clds()      { return null_if<G1MarkFromRoot>(&_strong._clds); }
 118   CLDClosure* second_pass_weak_clds() { return null_if<G1MarkFromRoot>(&_weak._clds); }
 119 
 120   CodeBlobClosure* strong_codeblobs()      { return &_strong._codeblobs; }
 121   CodeBlobClosure* weak_codeblobs()        { return &_weak._codeblobs; }
 122   CodeBlobClosure* thread_root_codeblobs() { return &_strong._codeblobs; }
 123 
 124   void flush() {
 125     _strong._buffered_oops.done();
 126     _weak._buffered_oops.done();
 127   }
 128 
 129   double closure_app_seconds() {
 130     return _strong._buffered_oops.closure_app_seconds() +
 131            _weak._buffered_oops.closure_app_seconds();
 132   }
 133 
 134   virtual OopClosure* raw_weak_oops() { return &_weak._oops; }
 135   virtual OopClosure* raw_strong_oops() { return &_strong._oops; }
 136 };
 137 
 138 #endif // SHARE_VM_GC_G1_G1SCAVENGECLOSURES_HPP