194f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi/* 294f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * Copyright (C) 2014 The Android Open Source Project 394f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * 494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * Licensed under the Apache License, Version 2.0 (the "License"); 594f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * you may not use this file except in compliance with the License. 694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * You may obtain a copy of the License at 794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * 894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * http://www.apache.org/licenses/LICENSE-2.0 994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * 1094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * Unless required by applicable law or agreed to in writing, software 1194f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * distributed under the License is distributed on an "AS IS" BASIS, 1294f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1394f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * See the License for the specific language governing permissions and 1494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi * limitations under the License. 1594f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi */ 1694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 1794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#ifndef ART_RUNTIME_GC_ROOT_H_ 1894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#define ART_RUNTIME_GC_ROOT_H_ 1994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 20bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier#include "base/macros.h" 2194f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "base/mutex.h" // For Locks::mutator_lock_. 22bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier#include "mirror/object_reference.h" 2394f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 2494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchinamespace art { 253f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchiclass ArtField; 263f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchiclass ArtMethod; 27c73cb64585f301c8bb3b03a0684f6baead99b7acAndreas Gampetemplate<class MirrorType> class ObjPtr; 2894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 29e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartiernamespace mirror { 30e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartierclass Object; 31e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier} // namespace mirror 32e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 33bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiertemplate <size_t kBufferSize> 34bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass BufferedRootVisitor; 35bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 364809d0a8a5fca85a67dd0588ead5dfbd0f1acf96Mathieu Chartier// Dependent on pointer size so that we don't have frames that are too big on 64 bit. 374809d0a8a5fca85a67dd0588ead5dfbd0f1acf96Mathieu Chartierstatic const size_t kDefaultBufferedRootCount = 1024 / sizeof(void*); 384809d0a8a5fca85a67dd0588ead5dfbd0f1acf96Mathieu Chartier 39e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartierenum RootType { 40e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootUnknown = 0, 41e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootJNIGlobal, 42e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootJNILocal, 43e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootJavaFrame, 44e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootNativeStack, 45e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootStickyClass, 46e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootThreadBlock, 47e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootMonitorUsed, 48e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootThreadObject, 49e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootInternedString, 501ed11b9ad5512cf464cb1686640df53201fa5297Man Cao kRootFinalizing, // used for HPROF's conversion to HprofHeapTag 51e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootDebugger, 521ed11b9ad5512cf464cb1686640df53201fa5297Man Cao kRootReferenceCleanup, // used for HPROF's conversion to HprofHeapTag 53e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootVMInternal, 54e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootJNIMonitor, 55e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier}; 56e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartierstd::ostream& operator<<(std::ostream& os, const RootType& root_type); 57e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 58d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier// Only used by hprof. thread_id_ and type_ are only used by hprof. 59e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartierclass RootInfo { 60e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier public: 61e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier // Thread id 0 is for non thread roots. 62e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier explicit RootInfo(RootType type, uint32_t thread_id = 0) 63e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier : type_(type), thread_id_(thread_id) { 64e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 65758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe RootInfo(const RootInfo&) = default; 66e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier virtual ~RootInfo() { 67e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 68e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier RootType GetType() const { 69e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier return type_; 70e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 71e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier uint32_t GetThreadId() const { 72e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier return thread_id_; 73e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 74e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier virtual void Describe(std::ostream& os) const { 75e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier os << "Type=" << type_ << " thread_id=" << thread_id_; 76e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 77bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier std::string ToString() const; 78e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 79e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier private: 80e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier const RootType type_; 81e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier const uint32_t thread_id_; 82e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier}; 83e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 84bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierinline std::ostream& operator<<(std::ostream& os, const RootInfo& root_info) { 85bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier root_info.Describe(os); 86bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier return os; 87bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier} 88bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 89585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe// Not all combinations of flags are valid. You may not visit all roots as well as the new roots 90585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe// (no logical reason to do this). You also may not start logging new roots and stop logging new 91585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe// roots (also no logical reason to do this). 92585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe// 93585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe// The precise flag ensures that more metadata is supplied. An example is vreg data for compiled 94585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe// method frames. 95585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampeenum VisitRootFlags : uint8_t { 96585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe kVisitRootFlagAllRoots = 0x1, 97585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe kVisitRootFlagNewRoots = 0x2, 98585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe kVisitRootFlagStartLoggingNewRoots = 0x4, 99585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe kVisitRootFlagStopLoggingNewRoots = 0x8, 100585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe kVisitRootFlagClearRootLog = 0x10, 101585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe kVisitRootFlagClassLoader = 0x20, 102585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe kVisitRootFlagPrecise = 0x80, 103585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe}; 104585da955bc8e5040705dcfd941b2131025ebcef8Andreas Gampe 105bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass RootVisitor { 106bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public: 107bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier virtual ~RootVisitor() { } 108bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 109d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier // Single root version, not overridable. 1109b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier ALWAYS_INLINE void VisitRoot(mirror::Object** root, const RootInfo& info) 111bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 1129b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier VisitRoots(&root, 1, info); 113bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 114bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 115d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier // Single root version, not overridable. 1169b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier ALWAYS_INLINE void VisitRootIfNonNull(mirror::Object** root, const RootInfo& info) 117bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 1189b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier if (*root != nullptr) { 1199b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier VisitRoot(root, info); 120bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 121bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 122bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 123bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier virtual void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info) 124bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) = 0; 125bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 126bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier virtual void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count, 127bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier const RootInfo& info) 128bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) = 0; 129bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 130bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 131bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// Only visits roots one at a time, doesn't handle updating roots. Used when performance isn't 132bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// critical. 133bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass SingleRootVisitor : public RootVisitor { 134bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private: 135bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info) OVERRIDE 136bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 137bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t i = 0; i < count; ++i) { 138bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(*roots[i], info); 139bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 140bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 141bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 142bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count, 143bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier const RootInfo& info) OVERRIDE 144bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 145bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t i = 0; i < count; ++i) { 146bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(roots[i]->AsMirrorPtr(), info); 147bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 148bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 149bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 150bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier virtual void VisitRoot(mirror::Object* root, const RootInfo& info) = 0; 151bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 152e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 1533f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchiclass GcRootSource { 1543f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi public: 1553f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi GcRootSource() 1563f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi : field_(nullptr), method_(nullptr) { 1573f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1583f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi explicit GcRootSource(ArtField* field) 1593f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi : field_(field), method_(nullptr) { 1603f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1613f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi explicit GcRootSource(ArtMethod* method) 1623f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi : field_(nullptr), method_(method) { 1633f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1643f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ArtField* GetArtField() const { 1653f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi return field_; 1663f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1673f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ArtMethod* GetArtMethod() const { 1683f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi return method_; 1693f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1703f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi bool HasArtField() const { 1713f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi return field_ != nullptr; 1723f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1733f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi bool HasArtMethod() const { 1743f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi return method_ != nullptr; 1753f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1763f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi 1773f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi private: 1783f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ArtField* const field_; 1793f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ArtMethod* const method_; 1803f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi 1813f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi DISALLOW_COPY_AND_ASSIGN(GcRootSource); 1823f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi}; 1833f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi 18494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchitemplate<class MirrorType> 1859e47bfa71d42df101aff9d156a1b296eaf6566a2Hiroshi Yamauchiclass GcRoot { 18694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi public: 18794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier> 1883f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ALWAYS_INLINE MirrorType* Read(GcRootSource* gc_root_source = nullptr) const 189bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_); 19094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 191bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(RootVisitor* visitor, const RootInfo& info) const 192bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 193eb175f70ef352ce0b9bcafdf06c5ac22b0ff626aMathieu Chartier DCHECK(!IsNull()); 194bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::CompressedReference<mirror::Object>* roots[1] = { &root_ }; 195bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor->VisitRoots(roots, 1u, info); 196eb175f70ef352ce0b9bcafdf06c5ac22b0ff626aMathieu Chartier DCHECK(!IsNull()); 19794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 19894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 199bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRootIfNonNull(RootVisitor* visitor, const RootInfo& info) const 200bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 201e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier if (!IsNull()) { 202bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(visitor, info); 203e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 204e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 205e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 206bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ALWAYS_INLINE mirror::CompressedReference<mirror::Object>* AddressWithoutBarrier() { 20794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi return &root_; 20894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 20994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 210bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ALWAYS_INLINE bool IsNull() const { 21194f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi // It's safe to null-check it without a read barrier. 212bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier return root_.IsNull(); 21394f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 21494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 21565975776f807d55c83af6cca1e447f8daa794413Mathieu Chartier ALWAYS_INLINE GcRoot() {} 2163398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier explicit ALWAYS_INLINE GcRoot(MirrorType* ref) 2173398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier REQUIRES_SHARED(Locks::mutator_lock_); 218c73cb64585f301c8bb3b03a0684f6baead99b7acAndreas Gampe explicit ALWAYS_INLINE GcRoot(ObjPtr<MirrorType> ref) 2193398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier REQUIRES_SHARED(Locks::mutator_lock_); 220bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 221bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private: 2220d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain // Root visitors take pointers to root_ and place them in CompressedReference** arrays. We use a 2239086b65b2ad35dd39a8afc62d535be8217208d08Mathieu Chartier // CompressedReference<mirror::Object> here since it violates strict aliasing requirements to 2249086b65b2ad35dd39a8afc62d535be8217208d08Mathieu Chartier // cast CompressedReference<MirrorType>* to CompressedReference<mirror::Object>*. 225bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mutable mirror::CompressedReference<mirror::Object> root_; 226bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 227bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <size_t kBufferSize> friend class BufferedRootVisitor; 228bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 229bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 230bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// Simple data structure for buffered root visiting to avoid virtual dispatch overhead. Currently 231bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// only for CompressedReferences since these are more common than the Object** roots which are only 232bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// for thread local roots. 233bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiertemplate <size_t kBufferSize> 234bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass BufferedRootVisitor { 235bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public: 236bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier BufferedRootVisitor(RootVisitor* visitor, const RootInfo& root_info) 237bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier : visitor_(visitor), root_info_(root_info), buffer_pos_(0) { 238bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 239bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 240bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ~BufferedRootVisitor() { 241bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier Flush(); 242bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 243bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 244bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <class MirrorType> 245bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ALWAYS_INLINE void VisitRootIfNonNull(GcRoot<MirrorType>& root) 246bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 247bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (!root.IsNull()) { 248bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(root); 249bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 250bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 251bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 252bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <class MirrorType> 253bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<MirrorType>* root) 254bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 255bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (!root->IsNull()) { 256bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(root); 257bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 258bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 259bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 260bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <class MirrorType> 261bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe void VisitRoot(GcRoot<MirrorType>& root) REQUIRES_SHARED(Locks::mutator_lock_) { 262bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(root.AddressWithoutBarrier()); 263bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 264bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 265bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <class MirrorType> 266bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(mirror::CompressedReference<MirrorType>* root) 267bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 268bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (UNLIKELY(buffer_pos_ >= kBufferSize)) { 269bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier Flush(); 270bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 271bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier roots_[buffer_pos_++] = root; 27294f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 27394f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 274bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe void Flush() REQUIRES_SHARED(Locks::mutator_lock_) { 275bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor_->VisitRoots(roots_, buffer_pos_, root_info_); 276bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier buffer_pos_ = 0; 27794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 27894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 27994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi private: 280bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootVisitor* const visitor_; 281bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootInfo root_info_; 282bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::CompressedReference<mirror::Object>* roots_[kBufferSize]; 283bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier size_t buffer_pos_; 28494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi}; 28594f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 28658c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartierclass UnbufferedRootVisitor { 28758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier public: 28858c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier UnbufferedRootVisitor(RootVisitor* visitor, const RootInfo& root_info) 28958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier : visitor_(visitor), root_info_(root_info) {} 29058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 29158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier template <class MirrorType> 29258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier ALWAYS_INLINE void VisitRootIfNonNull(GcRoot<MirrorType>& root) const 29358c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier REQUIRES_SHARED(Locks::mutator_lock_) { 29458c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier if (!root.IsNull()) { 29558c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier VisitRoot(root); 29658c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 29758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 29858c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 29958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier template <class MirrorType> 30058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<MirrorType>* root) const 30158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier REQUIRES_SHARED(Locks::mutator_lock_) { 30258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier if (!root->IsNull()) { 30358c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier VisitRoot(root); 30458c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 30558c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 30658c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 30758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier template <class MirrorType> 30858c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier void VisitRoot(GcRoot<MirrorType>& root) const REQUIRES_SHARED(Locks::mutator_lock_) { 30958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier VisitRoot(root.AddressWithoutBarrier()); 31058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 31158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 31258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier template <class MirrorType> 31358c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier void VisitRoot(mirror::CompressedReference<MirrorType>* root) const 31458c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier REQUIRES_SHARED(Locks::mutator_lock_) { 31558c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier visitor_->VisitRoots(&root, 1, root_info_); 31658c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 31758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 31858c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier private: 31958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier RootVisitor* const visitor_; 32058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier RootInfo root_info_; 32158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier}; 32258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 32394f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi} // namespace art 32494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 32594f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#endif // ART_RUNTIME_GC_ROOT_H_ 326