1 /*
2  * Copyright (c) 2001, 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_SHARED_GENOOPCLOSURES_HPP
26 #define SHARE_GC_SHARED_GENOOPCLOSURES_HPP
27 
28 #include "memory/iterator.hpp"
29 #include "oops/oop.hpp"
30 
31 class Generation;
32 class CardTableRS;
33 class CardTableBarrierSet;
34 class DefNewGeneration;
35 class KlassRemSet;
36 
37 // Closure for iterating roots from a particular generation
38 // Note: all classes deriving from this MUST call this do_barrier
39 // method at the end of their own do_oop method!
40 // Note: no do_oop defined, this is an abstract class.
41 
42 class OopsInGenClosure : public OopIterateClosure {
43  private:
44   Generation*  _orig_gen;     // generation originally set in ctor
45   Generation*  _gen;          // generation being scanned
46 
47  protected:
48   // Some subtypes need access.
49   HeapWord*    _gen_boundary; // start of generation
50   CardTableRS* _rs;           // remembered set
51 
52   // For assertions
generation()53   Generation* generation() { return _gen; }
rs()54   CardTableRS* rs() { return _rs; }
55 
56   // Derived classes that modify oops so that they might be old-to-young
57   // pointers must call the method below.
58   template <class T> void do_barrier(T* p);
59 
60   // Version for use by closures that may be called in parallel code.
61   template <class T> void par_do_barrier(T* p);
62 
63  public:
OopsInGenClosure()64   OopsInGenClosure() : OopIterateClosure(NULL),
65     _orig_gen(NULL), _gen(NULL), _gen_boundary(NULL), _rs(NULL) {};
66 
67   OopsInGenClosure(Generation* gen);
68   void set_generation(Generation* gen);
69 
reset_generation()70   void reset_generation() { _gen = _orig_gen; }
71 
72   // Problem with static closures: must have _gen_boundary set at some point,
73   // but cannot do this until after the heap is initialized.
set_orig_generation(Generation * gen)74   void set_orig_generation(Generation* gen) {
75     _orig_gen = gen;
76     set_generation(gen);
77   }
78 
gen_boundary()79   HeapWord* gen_boundary() { return _gen_boundary; }
80 
81 };
82 
83 class BasicOopsInGenClosure: public OopsInGenClosure {
84  public:
BasicOopsInGenClosure()85   BasicOopsInGenClosure() : OopsInGenClosure() {}
86   BasicOopsInGenClosure(Generation* gen);
87 
do_metadata()88   virtual bool do_metadata() { return false; }
do_klass(Klass * k)89   virtual void do_klass(Klass* k) { ShouldNotReachHere(); }
do_cld(ClassLoaderData * cld)90   virtual void do_cld(ClassLoaderData* cld) { ShouldNotReachHere(); }
91 };
92 
93 // Super class for scan closures. It contains code to dirty scanned class loader data.
94 class OopsInClassLoaderDataOrGenClosure: public BasicOopsInGenClosure {
95   ClassLoaderData* _scanned_cld;
96  public:
OopsInClassLoaderDataOrGenClosure(Generation * g)97   OopsInClassLoaderDataOrGenClosure(Generation* g) : BasicOopsInGenClosure(g), _scanned_cld(NULL) {}
set_scanned_cld(ClassLoaderData * cld)98   void set_scanned_cld(ClassLoaderData* cld) {
99     assert(cld == NULL || _scanned_cld == NULL, "Must be");
100     _scanned_cld = cld;
101   }
is_scanning_a_cld()102   bool is_scanning_a_cld() { return _scanned_cld != NULL; }
103   void do_cld_barrier();
104 };
105 
106 #if INCLUDE_SERIALGC
107 
108 // Closure for scanning DefNewGeneration.
109 //
110 // This closure will perform barrier store calls for ALL
111 // pointers in scanned oops.
112 class ScanClosure: public OopsInClassLoaderDataOrGenClosure {
113  private:
114   DefNewGeneration* _g;
115   HeapWord*         _boundary;
116   bool              _gc_barrier;
117   template <class T> inline void do_oop_work(T* p);
118  public:
119   ScanClosure(DefNewGeneration* g, bool gc_barrier);
120   virtual void do_oop(oop* p);
121   virtual void do_oop(narrowOop* p);
122 };
123 
124 // Closure for scanning DefNewGeneration.
125 //
126 // This closure only performs barrier store calls on
127 // pointers into the DefNewGeneration. This is less
128 // precise, but faster, than a ScanClosure
129 class FastScanClosure: public OopsInClassLoaderDataOrGenClosure {
130  protected:
131   DefNewGeneration* _g;
132   HeapWord*         _boundary;
133   bool              _gc_barrier;
134   template <class T> inline void do_oop_work(T* p);
135  public:
136   FastScanClosure(DefNewGeneration* g, bool gc_barrier);
137   virtual void do_oop(oop* p);
138   virtual void do_oop(narrowOop* p);
139 };
140 
141 #endif // INCLUDE_SERIALGC
142 
143 class CLDScanClosure: public CLDClosure {
144   OopsInClassLoaderDataOrGenClosure*   _scavenge_closure;
145   // true if the the modified oops state should be saved.
146   bool                                 _accumulate_modified_oops;
147  public:
CLDScanClosure(OopsInClassLoaderDataOrGenClosure * scavenge_closure,bool accumulate_modified_oops)148   CLDScanClosure(OopsInClassLoaderDataOrGenClosure* scavenge_closure,
149                  bool accumulate_modified_oops) :
150        _scavenge_closure(scavenge_closure), _accumulate_modified_oops(accumulate_modified_oops) {}
151   void do_cld(ClassLoaderData* cld);
152 };
153 
154 class FilteringClosure: public OopIterateClosure {
155  private:
156   HeapWord*   _boundary;
157   OopIterateClosure* _cl;
158  protected:
159   template <class T> inline void do_oop_work(T* p);
160  public:
FilteringClosure(HeapWord * boundary,OopIterateClosure * cl)161   FilteringClosure(HeapWord* boundary, OopIterateClosure* cl) :
162     OopIterateClosure(cl->ref_discoverer()), _boundary(boundary),
163     _cl(cl) {}
164   virtual void do_oop(oop* p);
165   virtual void do_oop(narrowOop* p);
do_metadata()166   virtual bool do_metadata()            { assert(!_cl->do_metadata(), "assumption broken, must change to 'return _cl->do_metadata()'"); return false; }
do_klass(Klass *)167   virtual void do_klass(Klass*)         { ShouldNotReachHere(); }
do_cld(ClassLoaderData *)168   virtual void do_cld(ClassLoaderData*) { ShouldNotReachHere(); }
169 };
170 
171 #if INCLUDE_SERIALGC
172 
173 // Closure for scanning DefNewGeneration's weak references.
174 // NOTE: very much like ScanClosure but not derived from
175 //  OopsInGenClosure -- weak references are processed all
176 //  at once, with no notion of which generation they were in.
177 class ScanWeakRefClosure: public OopClosure {
178  protected:
179   DefNewGeneration* _g;
180   HeapWord*         _boundary;
181   template <class T> inline void do_oop_work(T* p);
182  public:
183   ScanWeakRefClosure(DefNewGeneration* g);
184   virtual void do_oop(oop* p);
185   virtual void do_oop(narrowOop* p);
186 };
187 
188 #endif // INCLUDE_SERIALGC
189 
190 #endif // SHARE_GC_SHARED_GENOOPCLOSURES_HPP
191