xref: /aosp_15_r20/art/runtime/gc_root.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_GC_ROOT_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_ROOT_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "base/locks.h"       // For Locks::mutator_lock_.
21*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
22*795d594fSAndroid Build Coastguard Worker #include "mirror/object_reference.h"
23*795d594fSAndroid Build Coastguard Worker #include "read_barrier_option.h"
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
26*795d594fSAndroid Build Coastguard Worker class ArtField;
27*795d594fSAndroid Build Coastguard Worker class ArtMethod;
28*795d594fSAndroid Build Coastguard Worker template<class MirrorType> class ObjPtr;
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker namespace mirror {
31*795d594fSAndroid Build Coastguard Worker class Object;
32*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker template <size_t kBufferSize>
35*795d594fSAndroid Build Coastguard Worker class BufferedRootVisitor;
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker // Dependent on pointer size so that we don't have frames that are too big on 64 bit.
38*795d594fSAndroid Build Coastguard Worker static const size_t kDefaultBufferedRootCount = 1024 / sizeof(void*);
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker enum RootType {
41*795d594fSAndroid Build Coastguard Worker   kRootUnknown = 0,
42*795d594fSAndroid Build Coastguard Worker   kRootJNIGlobal,
43*795d594fSAndroid Build Coastguard Worker   kRootJNILocal,
44*795d594fSAndroid Build Coastguard Worker   kRootJavaFrame,
45*795d594fSAndroid Build Coastguard Worker   kRootNativeStack,
46*795d594fSAndroid Build Coastguard Worker   kRootStickyClass,
47*795d594fSAndroid Build Coastguard Worker   kRootThreadBlock,
48*795d594fSAndroid Build Coastguard Worker   kRootMonitorUsed,
49*795d594fSAndroid Build Coastguard Worker   kRootThreadObject,
50*795d594fSAndroid Build Coastguard Worker   kRootInternedString,
51*795d594fSAndroid Build Coastguard Worker   kRootFinalizing,  // used for HPROF's conversion to HprofHeapTag
52*795d594fSAndroid Build Coastguard Worker   kRootDebugger,
53*795d594fSAndroid Build Coastguard Worker   kRootReferenceCleanup,  // used for HPROF's conversion to HprofHeapTag
54*795d594fSAndroid Build Coastguard Worker   kRootVMInternal,
55*795d594fSAndroid Build Coastguard Worker   kRootJNIMonitor,
56*795d594fSAndroid Build Coastguard Worker };
57*795d594fSAndroid Build Coastguard Worker EXPORT std::ostream& operator<<(std::ostream& os, RootType root_type);
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker // Only used by hprof. thread_id_ and type_ are only used by hprof.
60*795d594fSAndroid Build Coastguard Worker class RootInfo {
61*795d594fSAndroid Build Coastguard Worker  public:
62*795d594fSAndroid Build Coastguard Worker   // Thread id 0 is for non thread roots.
63*795d594fSAndroid Build Coastguard Worker   explicit RootInfo(RootType type, uint32_t thread_id = 0)
type_(type)64*795d594fSAndroid Build Coastguard Worker      : type_(type), thread_id_(thread_id) {
65*795d594fSAndroid Build Coastguard Worker   }
66*795d594fSAndroid Build Coastguard Worker   RootInfo(const RootInfo&) = default;
~RootInfo()67*795d594fSAndroid Build Coastguard Worker   virtual ~RootInfo() {
68*795d594fSAndroid Build Coastguard Worker   }
GetType()69*795d594fSAndroid Build Coastguard Worker   RootType GetType() const {
70*795d594fSAndroid Build Coastguard Worker     return type_;
71*795d594fSAndroid Build Coastguard Worker   }
GetThreadId()72*795d594fSAndroid Build Coastguard Worker   uint32_t GetThreadId() const {
73*795d594fSAndroid Build Coastguard Worker     return thread_id_;
74*795d594fSAndroid Build Coastguard Worker   }
Describe(std::ostream & os)75*795d594fSAndroid Build Coastguard Worker   virtual void Describe(std::ostream& os) const {
76*795d594fSAndroid Build Coastguard Worker     os << "Type=" << type_ << " thread_id=" << thread_id_;
77*795d594fSAndroid Build Coastguard Worker   }
78*795d594fSAndroid Build Coastguard Worker   std::string ToString() const;
79*795d594fSAndroid Build Coastguard Worker 
80*795d594fSAndroid Build Coastguard Worker  private:
81*795d594fSAndroid Build Coastguard Worker   const RootType type_;
82*795d594fSAndroid Build Coastguard Worker   const uint32_t thread_id_;
83*795d594fSAndroid Build Coastguard Worker };
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker inline std::ostream& operator<<(std::ostream& os, const RootInfo& root_info) {
86*795d594fSAndroid Build Coastguard Worker   root_info.Describe(os);
87*795d594fSAndroid Build Coastguard Worker   return os;
88*795d594fSAndroid Build Coastguard Worker }
89*795d594fSAndroid Build Coastguard Worker 
90*795d594fSAndroid Build Coastguard Worker // Not all combinations of flags are valid. You may not visit all roots as well as the new roots
91*795d594fSAndroid Build Coastguard Worker // (no logical reason to do this). You also may not start logging new roots and stop logging new
92*795d594fSAndroid Build Coastguard Worker // roots (also no logical reason to do this).
93*795d594fSAndroid Build Coastguard Worker //
94*795d594fSAndroid Build Coastguard Worker // The precise flag ensures that more metadata is supplied. An example is vreg data for compiled
95*795d594fSAndroid Build Coastguard Worker // method frames.
96*795d594fSAndroid Build Coastguard Worker enum VisitRootFlags : uint8_t {
97*795d594fSAndroid Build Coastguard Worker   kVisitRootFlagAllRoots = (1 << 0),
98*795d594fSAndroid Build Coastguard Worker   kVisitRootFlagNewRoots = (1 << 1),
99*795d594fSAndroid Build Coastguard Worker   kVisitRootFlagStartLoggingNewRoots = (1 << 2),
100*795d594fSAndroid Build Coastguard Worker   kVisitRootFlagStopLoggingNewRoots = (1 << 3),
101*795d594fSAndroid Build Coastguard Worker   kVisitRootFlagClearRootLog = (1 << 4),
102*795d594fSAndroid Build Coastguard Worker   kVisitRootFlagClassLoader = (1 << 5),
103*795d594fSAndroid Build Coastguard Worker   // There is no (1 << 6).
104*795d594fSAndroid Build Coastguard Worker   kVisitRootFlagPrecise = (1 << 7),
105*795d594fSAndroid Build Coastguard Worker };
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker class RootVisitor {
108*795d594fSAndroid Build Coastguard Worker  public:
~RootVisitor()109*795d594fSAndroid Build Coastguard Worker   virtual ~RootVisitor() { }
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker   // Single root version, not overridable.
VisitRoot(mirror::Object ** root,const RootInfo & info)112*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitRoot(mirror::Object** root, const RootInfo& info)
113*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
114*795d594fSAndroid Build Coastguard Worker     VisitRoots(&root, 1, info);
115*795d594fSAndroid Build Coastguard Worker   }
116*795d594fSAndroid Build Coastguard Worker 
117*795d594fSAndroid Build Coastguard Worker   // Single root version, not overridable.
VisitRootIfNonNull(mirror::Object ** root,const RootInfo & info)118*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitRootIfNonNull(mirror::Object** root, const RootInfo& info)
119*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
120*795d594fSAndroid Build Coastguard Worker     if (*root != nullptr) {
121*795d594fSAndroid Build Coastguard Worker       VisitRoot(root, info);
122*795d594fSAndroid Build Coastguard Worker     }
123*795d594fSAndroid Build Coastguard Worker   }
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker   virtual void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info)
126*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker   virtual void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count,
129*795d594fSAndroid Build Coastguard Worker                           const RootInfo& info)
130*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
131*795d594fSAndroid Build Coastguard Worker };
132*795d594fSAndroid Build Coastguard Worker 
133*795d594fSAndroid Build Coastguard Worker // Only visits roots one at a time, doesn't handle updating roots. Used when performance isn't
134*795d594fSAndroid Build Coastguard Worker // critical.
135*795d594fSAndroid Build Coastguard Worker class SingleRootVisitor : public RootVisitor {
136*795d594fSAndroid Build Coastguard Worker  private:
VisitRoots(mirror::Object *** roots,size_t count,const RootInfo & info)137*795d594fSAndroid Build Coastguard Worker   void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info) override
138*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
139*795d594fSAndroid Build Coastguard Worker     for (size_t i = 0; i < count; ++i) {
140*795d594fSAndroid Build Coastguard Worker       VisitRoot(*roots[i], info);
141*795d594fSAndroid Build Coastguard Worker     }
142*795d594fSAndroid Build Coastguard Worker   }
143*795d594fSAndroid Build Coastguard Worker 
VisitRoots(mirror::CompressedReference<mirror::Object> ** roots,size_t count,const RootInfo & info)144*795d594fSAndroid Build Coastguard Worker   void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count,
145*795d594fSAndroid Build Coastguard Worker                           const RootInfo& info) override
146*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
147*795d594fSAndroid Build Coastguard Worker     for (size_t i = 0; i < count; ++i) {
148*795d594fSAndroid Build Coastguard Worker       VisitRoot(roots[i]->AsMirrorPtr(), info);
149*795d594fSAndroid Build Coastguard Worker     }
150*795d594fSAndroid Build Coastguard Worker   }
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker   virtual void VisitRoot(mirror::Object* root, const RootInfo& info) = 0;
153*795d594fSAndroid Build Coastguard Worker };
154*795d594fSAndroid Build Coastguard Worker 
155*795d594fSAndroid Build Coastguard Worker class GcRootSource {
156*795d594fSAndroid Build Coastguard Worker  public:
GcRootSource()157*795d594fSAndroid Build Coastguard Worker   GcRootSource()
158*795d594fSAndroid Build Coastguard Worker       : field_(nullptr), method_(nullptr) {
159*795d594fSAndroid Build Coastguard Worker   }
GcRootSource(ArtField * field)160*795d594fSAndroid Build Coastguard Worker   explicit GcRootSource(ArtField* field)
161*795d594fSAndroid Build Coastguard Worker       : field_(field), method_(nullptr) {
162*795d594fSAndroid Build Coastguard Worker   }
GcRootSource(ArtMethod * method)163*795d594fSAndroid Build Coastguard Worker   explicit GcRootSource(ArtMethod* method)
164*795d594fSAndroid Build Coastguard Worker       : field_(nullptr), method_(method) {
165*795d594fSAndroid Build Coastguard Worker   }
GetArtField()166*795d594fSAndroid Build Coastguard Worker   ArtField* GetArtField() const {
167*795d594fSAndroid Build Coastguard Worker     return field_;
168*795d594fSAndroid Build Coastguard Worker   }
GetArtMethod()169*795d594fSAndroid Build Coastguard Worker   ArtMethod* GetArtMethod() const {
170*795d594fSAndroid Build Coastguard Worker     return method_;
171*795d594fSAndroid Build Coastguard Worker   }
HasArtField()172*795d594fSAndroid Build Coastguard Worker   bool HasArtField() const {
173*795d594fSAndroid Build Coastguard Worker     return field_ != nullptr;
174*795d594fSAndroid Build Coastguard Worker   }
HasArtMethod()175*795d594fSAndroid Build Coastguard Worker   bool HasArtMethod() const {
176*795d594fSAndroid Build Coastguard Worker     return method_ != nullptr;
177*795d594fSAndroid Build Coastguard Worker   }
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker  private:
180*795d594fSAndroid Build Coastguard Worker   ArtField* const field_;
181*795d594fSAndroid Build Coastguard Worker   ArtMethod* const method_;
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(GcRootSource);
184*795d594fSAndroid Build Coastguard Worker };
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker // A small CompressedReference wrapper class that makes it harder to forget about read barriers.
187*795d594fSAndroid Build Coastguard Worker // Used for references that are roots for an object graph, whether or not they are actually traced
188*795d594fSAndroid Build Coastguard Worker // from. Requires an explicit VisitRoots call for tracing. See also Handle (implicitly traced by a
189*795d594fSAndroid Build Coastguard Worker // GC) and StackReference (traced explicitly, but not as the result of a read barrier).
190*795d594fSAndroid Build Coastguard Worker template<class MirrorType>
191*795d594fSAndroid Build Coastguard Worker class GcRoot {
192*795d594fSAndroid Build Coastguard Worker  public:
193*795d594fSAndroid Build Coastguard Worker   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
194*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE MirrorType* Read(GcRootSource* gc_root_source = nullptr) const
195*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
196*795d594fSAndroid Build Coastguard Worker 
197*795d594fSAndroid Build Coastguard Worker   // TODO: This is often called repeatedly from functions to process an explicit array of roots.
198*795d594fSAndroid Build Coastguard Worker   // And it calls a function that takes an array of roots. By processing a single root at a time
199*795d594fSAndroid Build Coastguard Worker   // here and turning it into a 1-element array, do we lose performance? Or does the compiler
200*795d594fSAndroid Build Coastguard Worker   // eliminate the extra work?
VisitRoot(RootVisitor * visitor,const RootInfo & info)201*795d594fSAndroid Build Coastguard Worker   void VisitRoot(RootVisitor* visitor, const RootInfo& info) const
202*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
203*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsNull());
204*795d594fSAndroid Build Coastguard Worker     mirror::CompressedReference<mirror::Object>* roots[1] = { &root_ };
205*795d594fSAndroid Build Coastguard Worker     visitor->VisitRoots(roots, 1u, info);
206*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsNull());
207*795d594fSAndroid Build Coastguard Worker   }
208*795d594fSAndroid Build Coastguard Worker 
VisitRootIfNonNull(RootVisitor * visitor,const RootInfo & info)209*795d594fSAndroid Build Coastguard Worker   void VisitRootIfNonNull(RootVisitor* visitor, const RootInfo& info) const
210*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
211*795d594fSAndroid Build Coastguard Worker     if (!IsNull()) {
212*795d594fSAndroid Build Coastguard Worker       VisitRoot(visitor, info);
213*795d594fSAndroid Build Coastguard Worker     }
214*795d594fSAndroid Build Coastguard Worker   }
215*795d594fSAndroid Build Coastguard Worker 
AddressWithoutBarrier()216*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE mirror::CompressedReference<mirror::Object>* AddressWithoutBarrier() {
217*795d594fSAndroid Build Coastguard Worker     return &root_;
218*795d594fSAndroid Build Coastguard Worker   }
219*795d594fSAndroid Build Coastguard Worker 
IsNull()220*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool IsNull() const {
221*795d594fSAndroid Build Coastguard Worker     // It's safe to null-check it without a read barrier.
222*795d594fSAndroid Build Coastguard Worker     return root_.IsNull();
223*795d594fSAndroid Build Coastguard Worker   }
224*795d594fSAndroid Build Coastguard Worker 
GcRoot()225*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE GcRoot() : GcRoot(nullptr) {}
GcRoot(std::nullptr_t)226*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE GcRoot(std::nullptr_t) : root_() {
227*795d594fSAndroid Build Coastguard Worker     DCHECK(IsNull());
228*795d594fSAndroid Build Coastguard Worker   }
229*795d594fSAndroid Build Coastguard Worker   explicit ALWAYS_INLINE GcRoot(mirror::CompressedReference<mirror::Object> ref)
230*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
231*795d594fSAndroid Build Coastguard Worker   explicit ALWAYS_INLINE GcRoot(MirrorType* ref)
232*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
233*795d594fSAndroid Build Coastguard Worker   explicit ALWAYS_INLINE GcRoot(ObjPtr<MirrorType> ref)
234*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
235*795d594fSAndroid Build Coastguard Worker 
236*795d594fSAndroid Build Coastguard Worker  private:
237*795d594fSAndroid Build Coastguard Worker   // Root visitors take pointers to root_ and place them in CompressedReference** arrays. We use a
238*795d594fSAndroid Build Coastguard Worker   // CompressedReference<mirror::Object> here since it violates strict aliasing requirements to
239*795d594fSAndroid Build Coastguard Worker   // cast CompressedReference<MirrorType>* to CompressedReference<mirror::Object>*.
240*795d594fSAndroid Build Coastguard Worker   mutable mirror::CompressedReference<mirror::Object> root_;
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   template <size_t kBufferSize> friend class BufferedRootVisitor;
243*795d594fSAndroid Build Coastguard Worker };
244*795d594fSAndroid Build Coastguard Worker 
245*795d594fSAndroid Build Coastguard Worker // Simple data structure for buffered root visiting to avoid virtual dispatch overhead. Currently
246*795d594fSAndroid Build Coastguard Worker // only for CompressedReferences since these are more common than the Object** roots which are only
247*795d594fSAndroid Build Coastguard Worker // for thread local roots.
248*795d594fSAndroid Build Coastguard Worker template <size_t kBufferSize>
249*795d594fSAndroid Build Coastguard Worker class BufferedRootVisitor {
250*795d594fSAndroid Build Coastguard Worker  public:
BufferedRootVisitor(RootVisitor * visitor,const RootInfo & root_info)251*795d594fSAndroid Build Coastguard Worker   BufferedRootVisitor(RootVisitor* visitor, const RootInfo& root_info)
252*795d594fSAndroid Build Coastguard Worker       : visitor_(visitor), root_info_(root_info), buffer_pos_(0) {
253*795d594fSAndroid Build Coastguard Worker   }
254*795d594fSAndroid Build Coastguard Worker 
~BufferedRootVisitor()255*795d594fSAndroid Build Coastguard Worker   ~BufferedRootVisitor() {
256*795d594fSAndroid Build Coastguard Worker     Flush();
257*795d594fSAndroid Build Coastguard Worker   }
258*795d594fSAndroid Build Coastguard Worker 
259*795d594fSAndroid Build Coastguard Worker   template <class MirrorType>
VisitRootIfNonNull(GcRoot<MirrorType> & root)260*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitRootIfNonNull(GcRoot<MirrorType>& root)
261*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
262*795d594fSAndroid Build Coastguard Worker     if (!root.IsNull()) {
263*795d594fSAndroid Build Coastguard Worker       VisitRoot(root);
264*795d594fSAndroid Build Coastguard Worker     }
265*795d594fSAndroid Build Coastguard Worker   }
266*795d594fSAndroid Build Coastguard Worker 
267*795d594fSAndroid Build Coastguard Worker   template <class MirrorType>
VisitRootIfNonNull(mirror::CompressedReference<MirrorType> * root)268*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<MirrorType>* root)
269*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
270*795d594fSAndroid Build Coastguard Worker     if (!root->IsNull()) {
271*795d594fSAndroid Build Coastguard Worker       VisitRoot(root);
272*795d594fSAndroid Build Coastguard Worker     }
273*795d594fSAndroid Build Coastguard Worker   }
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker   template <class MirrorType>
VisitRoot(GcRoot<MirrorType> & root)276*795d594fSAndroid Build Coastguard Worker   void VisitRoot(GcRoot<MirrorType>& root) REQUIRES_SHARED(Locks::mutator_lock_) {
277*795d594fSAndroid Build Coastguard Worker     VisitRoot(root.AddressWithoutBarrier());
278*795d594fSAndroid Build Coastguard Worker   }
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker   template <class MirrorType>
VisitRoot(mirror::CompressedReference<MirrorType> * root)281*795d594fSAndroid Build Coastguard Worker   void VisitRoot(mirror::CompressedReference<MirrorType>* root)
282*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
283*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(buffer_pos_ >= kBufferSize)) {
284*795d594fSAndroid Build Coastguard Worker       Flush();
285*795d594fSAndroid Build Coastguard Worker     }
286*795d594fSAndroid Build Coastguard Worker     roots_[buffer_pos_++] = root;
287*795d594fSAndroid Build Coastguard Worker   }
288*795d594fSAndroid Build Coastguard Worker 
Flush()289*795d594fSAndroid Build Coastguard Worker   void Flush() REQUIRES_SHARED(Locks::mutator_lock_) {
290*795d594fSAndroid Build Coastguard Worker     visitor_->VisitRoots(roots_, buffer_pos_, root_info_);
291*795d594fSAndroid Build Coastguard Worker     buffer_pos_ = 0;
292*795d594fSAndroid Build Coastguard Worker   }
293*795d594fSAndroid Build Coastguard Worker 
294*795d594fSAndroid Build Coastguard Worker  private:
295*795d594fSAndroid Build Coastguard Worker   RootVisitor* const visitor_;
296*795d594fSAndroid Build Coastguard Worker   RootInfo root_info_;
297*795d594fSAndroid Build Coastguard Worker   mirror::CompressedReference<mirror::Object>* roots_[kBufferSize];
298*795d594fSAndroid Build Coastguard Worker   size_t buffer_pos_;
299*795d594fSAndroid Build Coastguard Worker };
300*795d594fSAndroid Build Coastguard Worker 
301*795d594fSAndroid Build Coastguard Worker class UnbufferedRootVisitor {
302*795d594fSAndroid Build Coastguard Worker  public:
UnbufferedRootVisitor(RootVisitor * visitor,const RootInfo & root_info)303*795d594fSAndroid Build Coastguard Worker   UnbufferedRootVisitor(RootVisitor* visitor, const RootInfo& root_info)
304*795d594fSAndroid Build Coastguard Worker       : visitor_(visitor), root_info_(root_info) {}
305*795d594fSAndroid Build Coastguard Worker 
306*795d594fSAndroid Build Coastguard Worker   template <class MirrorType>
VisitRootIfNonNull(GcRoot<MirrorType> & root)307*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitRootIfNonNull(GcRoot<MirrorType>& root) const
308*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
309*795d594fSAndroid Build Coastguard Worker     if (!root.IsNull()) {
310*795d594fSAndroid Build Coastguard Worker       VisitRoot(root);
311*795d594fSAndroid Build Coastguard Worker     }
312*795d594fSAndroid Build Coastguard Worker   }
313*795d594fSAndroid Build Coastguard Worker 
314*795d594fSAndroid Build Coastguard Worker   template <class MirrorType>
VisitRootIfNonNull(mirror::CompressedReference<MirrorType> * root)315*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<MirrorType>* root) const
316*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
317*795d594fSAndroid Build Coastguard Worker     if (!root->IsNull()) {
318*795d594fSAndroid Build Coastguard Worker       VisitRoot(root);
319*795d594fSAndroid Build Coastguard Worker     }
320*795d594fSAndroid Build Coastguard Worker   }
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker   template <class MirrorType>
VisitRoot(GcRoot<MirrorType> & root)323*795d594fSAndroid Build Coastguard Worker   void VisitRoot(GcRoot<MirrorType>& root) const REQUIRES_SHARED(Locks::mutator_lock_) {
324*795d594fSAndroid Build Coastguard Worker     VisitRoot(root.AddressWithoutBarrier());
325*795d594fSAndroid Build Coastguard Worker   }
326*795d594fSAndroid Build Coastguard Worker 
327*795d594fSAndroid Build Coastguard Worker   template <class MirrorType>
VisitRoot(mirror::CompressedReference<MirrorType> * root)328*795d594fSAndroid Build Coastguard Worker   void VisitRoot(mirror::CompressedReference<MirrorType>* root) const
329*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
330*795d594fSAndroid Build Coastguard Worker     visitor_->VisitRoots(&root, 1, root_info_);
331*795d594fSAndroid Build Coastguard Worker   }
332*795d594fSAndroid Build Coastguard Worker 
333*795d594fSAndroid Build Coastguard Worker  private:
334*795d594fSAndroid Build Coastguard Worker   RootVisitor* const visitor_;
335*795d594fSAndroid Build Coastguard Worker   RootInfo root_info_;
336*795d594fSAndroid Build Coastguard Worker };
337*795d594fSAndroid Build Coastguard Worker 
338*795d594fSAndroid Build Coastguard Worker }  // namespace art
339*795d594fSAndroid Build Coastguard Worker 
340*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_GC_ROOT_H_
341