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