1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_GC_ROOT_H_ 18 #define ART_RUNTIME_GC_ROOT_H_ 19 20 #include "base/macros.h" 21 #include "base/mutex.h" // For Locks::mutator_lock_. 22 23 namespace art { 24 25 namespace mirror { 26 class Object; 27 } // namespace mirror 28 29 enum RootType { 30 kRootUnknown = 0, 31 kRootJNIGlobal, 32 kRootJNILocal, 33 kRootJavaFrame, 34 kRootNativeStack, 35 kRootStickyClass, 36 kRootThreadBlock, 37 kRootMonitorUsed, 38 kRootThreadObject, 39 kRootInternedString, 40 kRootDebugger, 41 kRootVMInternal, 42 kRootJNIMonitor, 43 }; 44 std::ostream& operator<<(std::ostream& os, const RootType& root_type); 45 46 class RootInfo { 47 public: 48 // Thread id 0 is for non thread roots. 49 explicit RootInfo(RootType type, uint32_t thread_id = 0) type_(type)50 : type_(type), thread_id_(thread_id) { 51 } ~RootInfo()52 virtual ~RootInfo() { 53 } GetType()54 RootType GetType() const { 55 return type_; 56 } GetThreadId()57 uint32_t GetThreadId() const { 58 return thread_id_; 59 } Describe(std::ostream & os)60 virtual void Describe(std::ostream& os) const { 61 os << "Type=" << type_ << " thread_id=" << thread_id_; 62 } 63 64 private: 65 const RootType type_; 66 const uint32_t thread_id_; 67 }; 68 69 // Returns the new address of the object, returns root if it has not moved. tid and root_type are 70 // only used by hprof. 71 typedef void (RootCallback)(mirror::Object** root, void* arg, const RootInfo& root_info); 72 73 template<class MirrorType> 74 class PACKED(4) GcRoot { 75 public: 76 template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier> 77 ALWAYS_INLINE MirrorType* Read() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 78 VisitRoot(RootCallback * callback,void * arg,const RootInfo & info)79 void VisitRoot(RootCallback* callback, void* arg, const RootInfo& info) const { 80 DCHECK(!IsNull()); 81 callback(reinterpret_cast<mirror::Object**>(&root_), arg, info); 82 DCHECK(!IsNull()); 83 } 84 VisitRootIfNonNull(RootCallback * callback,void * arg,const RootInfo & info)85 void VisitRootIfNonNull(RootCallback* callback, void* arg, const RootInfo& info) const { 86 if (!IsNull()) { 87 VisitRoot(callback, arg, info); 88 } 89 } 90 91 // This is only used by IrtIterator. AddressWithoutBarrier()92 ALWAYS_INLINE MirrorType** AddressWithoutBarrier() { 93 return &root_; 94 } 95 IsNull()96 bool IsNull() const { 97 // It's safe to null-check it without a read barrier. 98 return root_ == nullptr; 99 } 100 root_(nullptr)101 ALWAYS_INLINE explicit GcRoot<MirrorType>() : root_(nullptr) { 102 } 103 104 ALWAYS_INLINE explicit GcRoot<MirrorType>(MirrorType* ref) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)105 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : root_(ref) { 106 } 107 108 private: 109 mutable MirrorType* root_; 110 }; 111 112 } // namespace art 113 114 #endif // ART_RUNTIME_GC_ROOT_H_ 115