1 /*
   2  * Copyright (c) 2015, Red Hat, Inc. and/or its affiliates.
   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 "gc/shenandoah/shenandoahTaskqueue.hpp"
  28 
  29 class ShenandoahHeap;
  30 class ShenandoahStrDedupQueue;
  31 
  32 enum UpdateRefsMode {
  33   NONE,       // No reference updating
  34   RESOLVE,    // Only a read-barrier (no reference updating)
  35   SIMPLE,     // Reference updating using simple store
  36   CONCURRENT  // Reference updating using CAS
  37 };
  38 
  39 class ShenandoahMarkRefsSuperClosure : public MetadataAwareOopClosure {
  40 private:
  41   ShenandoahObjToScanQueue* _queue;
  42   ShenandoahStrDedupQueue*  _dedup_queue;
  43   ShenandoahHeap* _heap;
  44 public:
  45   ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp);
  46   ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp);
  47 
  48   template <class T, UpdateRefsMode UPDATE_MODE, bool STRING_DEDUP>
  49   void work(T *p);
  50 
  51   inline void set_base_object(oop obj) { /* Not needed */ }
  52 };
  53 
  54 class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkRefsSuperClosure {
  55 public:
  56   ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
  57           ShenandoahMarkRefsSuperClosure(q, rp) {};
  58 
  59   template <class T>
  60   inline void do_oop_nv(T* p)       { work<T, CONCURRENT, false /* string dedup */>(p); }
  61   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
  62   virtual void do_oop(oop* p)       { do_oop_nv(p); }
  63   inline bool do_metadata_nv()      { return false; }
  64   virtual bool do_metadata()        { return false; }
  65 };
  66 
  67 class ShenandoahMarkUpdateRefsDedupClosure : public ShenandoahMarkRefsSuperClosure {
  68 public:
  69   ShenandoahMarkUpdateRefsDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
  70           ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
  71 
  72   template <class T>
  73   inline void do_oop_nv(T* p)       { work<T, CONCURRENT, true /* string dedup */>(p); }
  74   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
  75   virtual void do_oop(oop* p)       { do_oop_nv(p); }
  76   inline bool do_metadata_nv()      { return false; }
  77   virtual bool do_metadata()        { return false; }
  78 };
  79 
  80 class ShenandoahMarkUpdateRefsMetadataClosure : public ShenandoahMarkRefsSuperClosure {
  81 public:
  82   ShenandoahMarkUpdateRefsMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
  83     ShenandoahMarkRefsSuperClosure(q, rp) {};
  84 
  85   template <class T>
  86   inline void do_oop_nv(T* p)       { work<T, CONCURRENT, false /* string dedup */>(p); }
  87   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
  88   virtual void do_oop(oop* p)       { do_oop_nv(p); }
  89   inline bool do_metadata_nv()      { return true; }
  90   virtual bool do_metadata()        { return true; }
  91 };
  92 
  93 class ShenandoahMarkUpdateRefsMetadataDedupClosure : public ShenandoahMarkRefsSuperClosure {
  94 public:
  95   ShenandoahMarkUpdateRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
  96   ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
  97 
  98   template <class T>
  99   inline void do_oop_nv(T* p)       { work<T, CONCURRENT, true /* string dedup */>(p); }
 100   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 101   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 102   inline bool do_metadata_nv()      { return true; }
 103   virtual bool do_metadata()        { return true; }
 104 };
 105 
 106 class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure {
 107 public:
 108   ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 109     ShenandoahMarkRefsSuperClosure(q, rp) {};
 110 
 111   template <class T>
 112   inline void do_oop_nv(T* p)       { work<T, NONE, false /* string dedup */>(p); }
 113   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 114   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 115   inline bool do_metadata_nv()      { return false; }
 116   virtual bool do_metadata()        { return false; }
 117 };
 118 
 119 class ShenandoahMarkRefsDedupClosure : public ShenandoahMarkRefsSuperClosure {
 120 public:
 121   ShenandoahMarkRefsDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
 122     ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
 123 
 124   template <class T>
 125   inline void do_oop_nv(T* p)       { work<T, NONE, true /* string dedup */>(p); }
 126   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 127   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 128   inline bool do_metadata_nv()      { return false; }
 129   virtual bool do_metadata()        { return false; }
 130 };
 131 
 132 class ShenandoahMarkResolveRefsClosure : public ShenandoahMarkRefsSuperClosure {
 133 public:
 134   ShenandoahMarkResolveRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 135     ShenandoahMarkRefsSuperClosure(q, rp) {};
 136 
 137   template <class T>
 138   inline void do_oop_nv(T* p)       { work<T, RESOLVE, false /* string dedup */>(p); }
 139   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 140   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 141   inline bool do_metadata_nv()      { return false; }
 142   virtual bool do_metadata()        { return false; }
 143 };
 144 
 145 class ShenandoahMarkResolveRefsDedupClosure : public ShenandoahMarkRefsSuperClosure {
 146 public:
 147   ShenandoahMarkResolveRefsDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
 148     ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
 149 
 150   template <class T>
 151   inline void do_oop_nv(T* p)       { work<T, RESOLVE, true /* string dedup */>(p); }
 152   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 153   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 154   inline bool do_metadata_nv()      { return false; }
 155   virtual bool do_metadata()        { return false; }
 156 };
 157 
 158 class ShenandoahMarkRefsMetadataClosure : public ShenandoahMarkRefsSuperClosure {
 159 public:
 160   ShenandoahMarkRefsMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 161     ShenandoahMarkRefsSuperClosure(q, rp) {};
 162 
 163   template <class T>
 164   inline void do_oop_nv(T* p)       { work<T, NONE, false /* string dedup */>(p); }
 165   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 166   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 167   inline bool do_metadata_nv()      { return true; }
 168   virtual bool do_metadata()        { return true; }
 169 };
 170 
 171 class ShenandoahMarkRefsMetadataDedupClosure : public ShenandoahMarkRefsSuperClosure {
 172 public:
 173   ShenandoahMarkRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahStrDedupQueue* dq, ReferenceProcessor* rp) :
 174     ShenandoahMarkRefsSuperClosure(q, dq, rp) {};
 175 
 176   template <class T>
 177   inline void do_oop_nv(T* p)       { work<T, NONE, true /* string dedup */>(p); }
 178   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 179   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 180   inline bool do_metadata_nv()      { return true; }
 181   virtual bool do_metadata()        { return true; }
 182 };
 183 
 184 class ShenandoahUpdateHeapRefsSuperClosure : public ExtendedOopClosure {
 185 private:
 186   ShenandoahHeap* _heap;
 187 public:
 188   ShenandoahUpdateHeapRefsSuperClosure() :
 189     _heap(ShenandoahHeap::heap()) {}
 190 
 191   template <class T, bool UPDATE_MATRIX>
 192   void work(T *p);
 193 };
 194 
 195 class ShenandoahUpdateHeapRefsClosure : public ShenandoahUpdateHeapRefsSuperClosure {
 196 public:
 197   ShenandoahUpdateHeapRefsClosure() : ShenandoahUpdateHeapRefsSuperClosure() {}
 198 
 199   template <class T>
 200   inline  void do_oop_nv(T* p)      { work<T, false>(p); }
 201   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 202   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 203 };
 204 
 205 class ShenandoahUpdateHeapRefsMatrixClosure : public ShenandoahUpdateHeapRefsSuperClosure {
 206 public:
 207   ShenandoahUpdateHeapRefsMatrixClosure() : ShenandoahUpdateHeapRefsSuperClosure() {}
 208 
 209   template <class T>
 210   inline  void do_oop_nv(T* p)      { work<T, true>(p); }
 211   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 212   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 213 };
 214 
 215 class ShenandoahTraversalSuperClosure : public MetadataAwareOopClosure {
 216 private:
 217   ShenandoahTraversalGC* _traversal_gc;
 218   Thread* _thread;
 219   ShenandoahObjToScanQueue* _queue;
 220   ShenandoahStrDedupQueue*  _dedup_queue;
 221   oop _base_obj;
 222 protected:
 223   ShenandoahTraversalSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 224     MetadataAwareOopClosure(rp),
 225     _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 226     _thread(Thread::current()), _queue(q), _dedup_queue(NULL), _base_obj(NULL) {
 227   }
 228 
 229   ShenandoahTraversalSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 230     MetadataAwareOopClosure(rp),
 231     _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 232     _thread(Thread::current()), _queue(q), _dedup_queue(dq) {
 233   }
 234 
 235   template <class T, bool STRING_DEDUP, bool DEGEN, bool MATRIX>
 236   void work(T* p);
 237 
 238 public:
 239   inline void set_base_object(oop obj) {
 240     _base_obj = obj;
 241   }
 242 };
 243 
 244 class ShenandoahTraversalClosure : public ShenandoahTraversalSuperClosure {
 245 public:
 246   ShenandoahTraversalClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 247     ShenandoahTraversalSuperClosure(q, rp) {}
 248 
 249   template <class T>
 250   inline void do_oop_nv(T* p) { work<T, false, false, false>(p); }
 251 
 252   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 253   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 254 
 255   inline bool do_metadata_nv()      { return false; }
 256   virtual bool do_metadata()        { return false; }
 257 };
 258 
 259 class ShenandoahTraversalMetadataClosure : public ShenandoahTraversalSuperClosure {
 260 public:
 261   ShenandoahTraversalMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 262     ShenandoahTraversalSuperClosure(q, rp) {}
 263 
 264   template <class T>
 265   inline void do_oop_nv(T* p) { work<T, false, false, false>(p); }
 266 
 267   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 268   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 269 
 270   inline bool do_metadata_nv()      { return true; }
 271   virtual bool do_metadata()        { return true; }
 272 };
 273 
 274 class ShenandoahTraversalDedupClosure : public ShenandoahTraversalSuperClosure {
 275 public:
 276   ShenandoahTraversalDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 277     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 278 
 279   template <class T>
 280   inline void do_oop_nv(T* p) { work<T, true, false, false>(p); }
 281 
 282   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 283   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 284 
 285   inline bool do_metadata_nv()      { return false; }
 286   virtual bool do_metadata()        { return false; }
 287 };
 288 
 289 class ShenandoahTraversalMetadataDedupClosure : public ShenandoahTraversalSuperClosure {
 290 public:
 291   ShenandoahTraversalMetadataDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 292     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 293 
 294   template <class T>
 295   inline void do_oop_nv(T* p) { work<T, true, false, false>(p); }
 296 
 297   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 298   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 299 
 300   inline bool do_metadata_nv()      { return true; }
 301   virtual bool do_metadata()        { return true; }
 302 };
 303 
 304 class ShenandoahTraversalDegenClosure : public ShenandoahTraversalSuperClosure {
 305 public:
 306   ShenandoahTraversalDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 307     ShenandoahTraversalSuperClosure(q, rp) {}
 308 
 309   template <class T>
 310   inline void do_oop_nv(T* p) { work<T, false, true, false>(p); }
 311 
 312   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 313   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 314 
 315   inline bool do_metadata_nv()      { return false; }
 316   virtual bool do_metadata()        { return false; }
 317 };
 318 
 319 class ShenandoahTraversalMetadataDegenClosure : public ShenandoahTraversalSuperClosure {
 320 public:
 321   ShenandoahTraversalMetadataDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 322     ShenandoahTraversalSuperClosure(q, rp) {}
 323 
 324   template <class T>
 325   inline void do_oop_nv(T* p) { work<T, false, true, false>(p); }
 326 
 327   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 328   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 329 
 330   inline bool do_metadata_nv()      { return true; }
 331   virtual bool do_metadata()        { return true; }
 332 };
 333 
 334 class ShenandoahTraversalDedupDegenClosure : public ShenandoahTraversalSuperClosure {
 335 public:
 336   ShenandoahTraversalDedupDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 337     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 338 
 339   template <class T>
 340   inline void do_oop_nv(T* p) { work<T, true, true, false>(p); }
 341 
 342   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 343   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 344 
 345   inline bool do_metadata_nv()      { return false; }
 346   virtual bool do_metadata()        { return false; }
 347 };
 348 
 349 class ShenandoahTraversalMetadataDedupDegenClosure : public ShenandoahTraversalSuperClosure {
 350 public:
 351   ShenandoahTraversalMetadataDedupDegenClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 352     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 353 
 354   template <class T>
 355   inline void do_oop_nv(T* p) { work<T, true, true, false>(p); }
 356 
 357   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 358   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 359 
 360   inline bool do_metadata_nv()      { return true; }
 361   virtual bool do_metadata()        { return true; }
 362 };
 363 
 364 class ShenandoahTraversalMatrixClosure : public ShenandoahTraversalSuperClosure {
 365 public:
 366   ShenandoahTraversalMatrixClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 367     ShenandoahTraversalSuperClosure(q, rp) {}
 368 
 369   template <class T>
 370   inline void do_oop_nv(T* p) { work<T, false, false, true>(p); }
 371 
 372   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 373   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 374 
 375   inline bool do_metadata_nv()      { return false; }
 376   virtual bool do_metadata()        { return false; }
 377 };
 378 
 379 class ShenandoahTraversalMetadataMatrixClosure : public ShenandoahTraversalSuperClosure {
 380 public:
 381   ShenandoahTraversalMetadataMatrixClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 382     ShenandoahTraversalSuperClosure(q, rp) {}
 383 
 384   template <class T>
 385   inline void do_oop_nv(T* p) { work<T, false, false, true>(p); }
 386 
 387   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 388   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 389 
 390   inline bool do_metadata_nv()      { return true; }
 391   virtual bool do_metadata()        { return true; }
 392 };
 393 
 394 class ShenandoahTraversalDedupMatrixClosure : public ShenandoahTraversalSuperClosure {
 395 public:
 396   ShenandoahTraversalDedupMatrixClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 397     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 398 
 399   template <class T>
 400   inline void do_oop_nv(T* p) { work<T, true, false, true>(p); }
 401 
 402   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 403   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 404 
 405   inline bool do_metadata_nv()      { return false; }
 406   virtual bool do_metadata()        { return false; }
 407 };
 408 
 409 class ShenandoahTraversalMetadataDedupMatrixClosure : public ShenandoahTraversalSuperClosure {
 410 public:
 411   ShenandoahTraversalMetadataDedupMatrixClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 412     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 413 
 414   template <class T>
 415   inline void do_oop_nv(T* p) { work<T, true, false, true>(p); }
 416 
 417   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 418   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 419 
 420   inline bool do_metadata_nv()      { return true; }
 421   virtual bool do_metadata()        { return true; }
 422 };
 423 
 424 class ShenandoahTraversalDegenMatrixClosure : public ShenandoahTraversalSuperClosure {
 425 public:
 426   ShenandoahTraversalDegenMatrixClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 427     ShenandoahTraversalSuperClosure(q, rp) {}
 428 
 429   template <class T>
 430   inline void do_oop_nv(T* p) { work<T, false, true, true>(p); }
 431 
 432   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 433   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 434 
 435   inline bool do_metadata_nv()      { return false; }
 436   virtual bool do_metadata()        { return false; }
 437 };
 438 
 439 class ShenandoahTraversalMetadataDegenMatrixClosure : public ShenandoahTraversalSuperClosure {
 440 public:
 441   ShenandoahTraversalMetadataDegenMatrixClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) :
 442     ShenandoahTraversalSuperClosure(q, rp) {}
 443 
 444   template <class T>
 445   inline void do_oop_nv(T* p) { work<T, false, true, true>(p); }
 446 
 447   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 448   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 449 
 450   inline bool do_metadata_nv()      { return true; }
 451   virtual bool do_metadata()        { return true; }
 452 };
 453 
 454 class ShenandoahTraversalDedupDegenMatrixClosure : public ShenandoahTraversalSuperClosure {
 455 public:
 456   ShenandoahTraversalDedupDegenMatrixClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 457     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 458 
 459   template <class T>
 460   inline void do_oop_nv(T* p) { work<T, true, true, true>(p); }
 461 
 462   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 463   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 464 
 465   inline bool do_metadata_nv()      { return false; }
 466   virtual bool do_metadata()        { return false; }
 467 };
 468 
 469 class ShenandoahTraversalMetadataDedupDegenMatrixClosure : public ShenandoahTraversalSuperClosure {
 470 public:
 471   ShenandoahTraversalMetadataDedupDegenMatrixClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp, ShenandoahStrDedupQueue* dq) :
 472     ShenandoahTraversalSuperClosure(q, rp, dq) {}
 473 
 474   template <class T>
 475   inline void do_oop_nv(T* p) { work<T, true, true, true>(p); }
 476 
 477   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 478   virtual void do_oop(oop* p)       { do_oop_nv(p); }
 479 
 480   inline bool do_metadata_nv()      { return true; }
 481   virtual bool do_metadata()        { return true; }
 482 };
 483 
 484 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_HPP