1 /*
   2  * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP
  25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP
  26 
  27 #include "memory/iterator.hpp"
  28 #include "gc_implementation/shenandoah/shenandoahTaskqueue.hpp"
  29 
  30 class ShenandoahHeap;
  31 class ShenandoahStrDedupQueue;
  32 class ShenandoahMarkingContext;
  33 class ShenandoahTraversalGC;
  34 class OopClosure;
  35 
  36 enum UpdateRefsMode {
  37   NONE,       // No reference updating
  38   RESOLVE,    // Only a read-barrier (no reference updating)
  39   SIMPLE,     // Reference updating using simple store
  40   CONCURRENT  // Reference updating using CAS
  41 };
  42 
  43 enum StringDedupMode {
  44   NO_DEDUP,      // Do not do anything for String deduplication
  45   ENQUEUE_DEDUP  // Enqueue candidate Strings for deduplication
  46 };
  47 
  48 class ShenandoahMarkRefsSuperClosure : public MetadataAwareOopClosure {
  49 private:
  50   ShenandoahObjToScanQueue* _queue;
  51   ShenandoahStrDedupQueue*  _dedup_queue;
  52   ShenandoahHeap* _heap;
  53   ShenandoahMarkingContext* const _mark_context;
  54 
  55 public:
  56   ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp);
  57   ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp);
  58 
  59   template <class T, UpdateRefsMode UPDATE_MODE, StringDedupMode STRING_DEDUP>
  60   void work(T *p);
  61 };
  62 
  63 class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkRefsSuperClosure {
  64 public:
  65   ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
  66           ShenandoahMarkRefsSuperClosure(q, rp) {};
  67 
  68   template <class T>
  69   inline void do_oop_nv(T* p)       { work<T, CONCURRENT, NO_DEDUP>(p); }
  70   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
  71   virtual void do_oop(oop* p)       { do_oop_nv(p); }
  72   inline bool do_metadata_nv()      { return false; }
  73   virtual bool do_metadata()        { return false; }
  74 };
  75 
  76 class ShenandoahMarkUpdateRefsDedupClosure : public ShenandoahMarkRefsSuperClosure {
  77 public:
  78   ShenandoahMarkUpdateRefsDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
  79           ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
  80 
  81   template <class T>
  82   inline void do_oop_nv(T* p)       { work<T, CONCURRENT, ENQUEUE_DEDUP>(p); }
  83   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
  84   virtual void do_oop(oop* p)       { do_oop_nv(p); }
  85   inline bool do_metadata_nv()      { return false; }
  86   virtual bool do_metadata()        { return false; }
  87 };
  88 
  89 class ShenandoahMarkUpdateRefsMetadataClosure : public ShenandoahMarkRefsSuperClosure {
  90 public:
  91   ShenandoahMarkUpdateRefsMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
  92     ShenandoahMarkRefsSuperClosure(q, rp) {};
  93 
  94   template <class T>
  95   inline void do_oop_nv(T* p)       { work<T, CONCURRENT, NO_DEDUP>(p); }
  96   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
  97   virtual void do_oop(oop* p)       { do_oop_nv(p); }
  98   inline bool do_metadata_nv()      { return true; }
  99   virtual bool do_metadata()        { return true; }
 100 };
 101 
 102 class ShenandoahMarkUpdateRefsMetadataDedupClosure : public ShenandoahMarkRefsSuperClosure {
 103 public:
 104   ShenandoahMarkUpdateRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
 105   ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
 106 
 107   template <class T>
 108   inline void do_oop_nv(T* p)       { work<T, CONCURRENT, ENQUEUE_DEDUP>(p); }
 109   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 110   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 111   inline bool do_metadata_nv()      { return true; }
 112   virtual bool do_metadata()        { return true; }
 113 };
 114 
 115 class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure {
 116 public:
 117   ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 118     ShenandoahMarkRefsSuperClosure(q, rp) {};
 119 
 120   template <class T>
 121   inline void do_oop_nv(T* p)       { work<T, NONE, NO_DEDUP>(p); }
 122   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 123   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 124   inline bool do_metadata_nv()      { return false; }
 125   virtual bool do_metadata()        { return false; }
 126 };
 127 
 128 class ShenandoahMarkRefsDedupClosure : public ShenandoahMarkRefsSuperClosure {
 129 public:
 130   ShenandoahMarkRefsDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
 131     ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
 132 
 133   template <class T>
 134   inline void do_oop_nv(T* p)       { work<T, NONE, ENQUEUE_DEDUP>(p); }
 135   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 136   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 137   inline bool do_metadata_nv()      { return false; }
 138   virtual bool do_metadata()        { return false; }
 139 };
 140 
 141 class ShenandoahMarkResolveRefsClosure : public ShenandoahMarkRefsSuperClosure {
 142 public:
 143   ShenandoahMarkResolveRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 144     ShenandoahMarkRefsSuperClosure(q, rp) {};
 145 
 146   template <class T>
 147   inline void do_oop_nv(T* p)       { work<T, RESOLVE, NO_DEDUP>(p); }
 148   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 149   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 150   inline bool do_metadata_nv()      { return false; }
 151   virtual bool do_metadata()        { return false; }
 152 };
 153 
 154 class ShenandoahMarkResolveRefsDedupClosure : public ShenandoahMarkRefsSuperClosure {
 155 public:
 156   ShenandoahMarkResolveRefsDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
 157     ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
 158 
 159   template <class T>
 160   inline void do_oop_nv(T* p)       { work<T, RESOLVE, ENQUEUE_DEDUP>(p); }
 161   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 162   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 163   inline bool do_metadata_nv()      { return false; }
 164   virtual bool do_metadata()        { return false; }
 165 };
 166 
 167 class ShenandoahMarkRefsMetadataClosure : public ShenandoahMarkRefsSuperClosure {
 168 public:
 169   ShenandoahMarkRefsMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 170     ShenandoahMarkRefsSuperClosure(q, rp) {};
 171 
 172   template <class T>
 173   inline void do_oop_nv(T* p)       { work<T, NONE, NO_DEDUP>(p); }
 174   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 175   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 176   inline bool do_metadata_nv()      { return true; }
 177   virtual bool do_metadata()        { return true; }
 178 };
 179 
 180 class ShenandoahMarkRefsMetadataDedupClosure : public ShenandoahMarkRefsSuperClosure {
 181 public:
 182   ShenandoahMarkRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
 183     ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
 184 
 185   template <class T>
 186   inline void do_oop_nv(T* p)       { work<T, NONE, ENQUEUE_DEDUP>(p); }
 187   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 188   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 189   inline bool do_metadata_nv()      { return true; }
 190   virtual bool do_metadata()        { return true; }
 191 };
 192 
 193 class ShenandoahUpdateHeapRefsClosure : public ExtendedOopClosure {
 194 private:
 195   ShenandoahHeap* _heap;
 196 public:
 197   ShenandoahUpdateHeapRefsClosure();
 198 
 199   template <class T>
 200   void do_oop_nv(T* p);
 201 
 202   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 203   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 204 };
 205 
 206 class ShenandoahTraversalSuperClosure : public MetadataAwareOopClosure {
 207 private:
 208   ShenandoahTraversalGC* const _traversal_gc;
 209   ShenandoahStrDedupQueue* const _dedup_queue;
 210   Thread* const _thread;
 211   ShenandoahObjToScanQueue* const _queue;
 212   ShenandoahMarkingContext* const _mark_context;
 213 protected:
 214   ShenandoahTraversalSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq = NULL);
 215 
 216   template <class T, bool STRING_DEDUP, bool DEGEN, bool ATOMIC_UPDATE>
 217   void work(T* p);
 218 
 219 };
 220 
 221 class ShenandoahTraversalRootsClosure : public ShenandoahTraversalSuperClosure {
 222 private:
 223   template <class T>
 224   inline void do_oop_work(T* p)     { work<T, false, false, false>(p); }
 225 
 226 public:
 227   ShenandoahTraversalRootsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 228     ShenandoahTraversalSuperClosure(q, rp) {}
 229 
 230   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 231   virtual void do_oop(oop* p)       { do_oop_work(p); }
 232 
 233   virtual bool do_metadata()        { return false; }
 234 };
 235 
 236 class ShenandoahTraversalClosure : public ShenandoahTraversalSuperClosure {
 237 private:
 238   template <class T>
 239   inline void do_oop_work(T* p)     { work<T, false, false, true>(p); }
 240 
 241 public:
 242   ShenandoahTraversalClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 243     ShenandoahTraversalSuperClosure(q, rp) {}
 244 
 245   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 246   virtual void do_oop(oop* p)       { do_oop_work(p); }
 247 
 248   virtual bool do_metadata()        { return false; }
 249 };
 250 
 251 class ShenandoahTraversalMetadataClosure : public ShenandoahTraversalSuperClosure {
 252 private:
 253   template <class T>
 254   inline void do_oop_work(T* p)     { work<T, false, false, true>(p); }
 255 
 256 public:
 257   ShenandoahTraversalMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 258     ShenandoahTraversalSuperClosure(q, rp) {}
 259 
 260   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 261   virtual void do_oop(oop* p)       { do_oop_work(p); }
 262 
 263   virtual bool do_metadata()        { return true; }
 264 };
 265 
 266 class ShenandoahTraversalDedupClosure : public ShenandoahTraversalSuperClosure {
 267 private:
 268   template <class T>
 269   inline void do_oop_work(T* p)     { work<T, true, false, true>(p); }
 270 
 271 public:
 272   ShenandoahTraversalDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 273     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 274 
 275   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 276   virtual void do_oop(oop* p)       { do_oop_work(p); }
 277 
 278   virtual bool do_metadata()        { return false; }
 279 };
 280 
 281 class ShenandoahTraversalMetadataDedupClosure : public ShenandoahTraversalSuperClosure {
 282 private:
 283   template <class T>
 284   inline void do_oop_work(T* p)     { work<T, true, false, true>(p); }
 285 
 286 public:
 287   ShenandoahTraversalMetadataDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 288     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 289 
 290   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 291   virtual void do_oop(oop* p)       { do_oop_work(p); }
 292 
 293   virtual bool do_metadata()        { return true; }
 294 };
 295 
 296 class ShenandoahTraversalDegenClosure : public ShenandoahTraversalSuperClosure {
 297 private:
 298   template <class T>
 299   inline void do_oop_work(T* p)     { work<T, false, true, false>(p); }
 300 
 301 public:
 302   ShenandoahTraversalDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 303     ShenandoahTraversalSuperClosure(q, rp) {}
 304 
 305   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 306   virtual void do_oop(oop* p)       { do_oop_work(p); }
 307 
 308   virtual bool do_metadata()        { return false; }
 309 };
 310 
 311 class ShenandoahTraversalMetadataDegenClosure : public ShenandoahTraversalSuperClosure {
 312 private:
 313   template <class T>
 314   inline void do_oop_work(T* p)     { work<T, false, true, false>(p); }
 315 
 316 public:
 317   ShenandoahTraversalMetadataDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 318     ShenandoahTraversalSuperClosure(q, rp) {}
 319 
 320   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 321   virtual void do_oop(oop* p)       { do_oop_work(p); }
 322 
 323   virtual bool do_metadata()        { return true; }
 324 };
 325 
 326 class ShenandoahTraversalDedupDegenClosure : public ShenandoahTraversalSuperClosure {
 327 private:
 328   template <class T>
 329   inline void do_oop_work(T* p)     { work<T, true, true, false>(p); }
 330 
 331 public:
 332   ShenandoahTraversalDedupDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 333     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 334 
 335   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 336   virtual void do_oop(oop* p)       { do_oop_work(p); }
 337 
 338   virtual bool do_metadata()        { return false; }
 339 };
 340 
 341 class ShenandoahTraversalMetadataDedupDegenClosure : public ShenandoahTraversalSuperClosure {
 342 private:
 343   template <class T>
 344   inline void do_oop_work(T* p)     { work<T, true, true, false>(p); }
 345 
 346 public:
 347   ShenandoahTraversalMetadataDedupDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 348     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 349 
 350   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 351   virtual void do_oop(oop* p)       { do_oop_work(p); }
 352 
 353   virtual bool do_metadata()        { return true; }
 354 };
 355 
 356 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP