gc_root.h revision 65975776f807d55c83af6cca1e447f8daa794413
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; 2794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 28e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartiernamespace mirror { 29e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartierclass Object; 30e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier} // namespace mirror 31e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 32bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiertemplate <size_t kBufferSize> 33bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass BufferedRootVisitor; 34bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 354809d0a8a5fca85a67dd0588ead5dfbd0f1acf96Mathieu Chartier// Dependent on pointer size so that we don't have frames that are too big on 64 bit. 364809d0a8a5fca85a67dd0588ead5dfbd0f1acf96Mathieu Chartierstatic const size_t kDefaultBufferedRootCount = 1024 / sizeof(void*); 374809d0a8a5fca85a67dd0588ead5dfbd0f1acf96Mathieu Chartier 38e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartierenum RootType { 39e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootUnknown = 0, 40e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootJNIGlobal, 41e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootJNILocal, 42e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootJavaFrame, 43e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootNativeStack, 44e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootStickyClass, 45e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootThreadBlock, 46e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootMonitorUsed, 47e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootThreadObject, 48e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootInternedString, 491ed11b9ad5512cf464cb1686640df53201fa5297Man Cao kRootFinalizing, // used for HPROF's conversion to HprofHeapTag 50e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootDebugger, 511ed11b9ad5512cf464cb1686640df53201fa5297Man Cao kRootReferenceCleanup, // used for HPROF's conversion to HprofHeapTag 52e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootVMInternal, 53e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier kRootJNIMonitor, 54e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier}; 55e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartierstd::ostream& operator<<(std::ostream& os, const RootType& root_type); 56e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 57d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier// Only used by hprof. thread_id_ and type_ are only used by hprof. 58e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartierclass RootInfo { 59e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier public: 60e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier // Thread id 0 is for non thread roots. 61e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier explicit RootInfo(RootType type, uint32_t thread_id = 0) 62e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier : type_(type), thread_id_(thread_id) { 63e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 64758a801b66c134361a7b43f7e83f85d1fb800c4cAndreas Gampe RootInfo(const RootInfo&) = default; 65e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier virtual ~RootInfo() { 66e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 67e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier RootType GetType() const { 68e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier return type_; 69e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 70e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier uint32_t GetThreadId() const { 71e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier return thread_id_; 72e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 73e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier virtual void Describe(std::ostream& os) const { 74e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier os << "Type=" << type_ << " thread_id=" << thread_id_; 75e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 76bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier std::string ToString() const; 77e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 78e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier private: 79e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier const RootType type_; 80e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier const uint32_t thread_id_; 81e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier}; 82e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 83bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierinline std::ostream& operator<<(std::ostream& os, const RootInfo& root_info) { 84bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier root_info.Describe(os); 85bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier return os; 86bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier} 87bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 88bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass RootVisitor { 89bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public: 90bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier virtual ~RootVisitor() { } 91bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 92d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier // Single root version, not overridable. 939b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier ALWAYS_INLINE void VisitRoot(mirror::Object** root, const RootInfo& info) 9490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 959b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier VisitRoots(&root, 1, info); 96bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 97bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 98d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier // Single root version, not overridable. 999b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier ALWAYS_INLINE void VisitRootIfNonNull(mirror::Object** root, const RootInfo& info) 10090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1019b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier if (*root != nullptr) { 1029b1c71ec77d92d63f1c2183b0cd3588727b2c265Mathieu Chartier VisitRoot(root, info); 103bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 104bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 105bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 106bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier virtual void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info) 10790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) = 0; 108bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 109bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier virtual void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count, 110bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier const RootInfo& info) 11190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) = 0; 112bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 113bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 114bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// Only visits roots one at a time, doesn't handle updating roots. Used when performance isn't 115bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// critical. 116bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass SingleRootVisitor : public RootVisitor { 117bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private: 118bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info) OVERRIDE 11990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 120bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t i = 0; i < count; ++i) { 121bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(*roots[i], info); 122bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 123bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 124bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 125bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count, 126bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier const RootInfo& info) OVERRIDE 12790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 128bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t i = 0; i < count; ++i) { 129bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(roots[i]->AsMirrorPtr(), info); 130bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 131bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 132bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 133bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier virtual void VisitRoot(mirror::Object* root, const RootInfo& info) = 0; 134bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 135e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 1363f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchiclass GcRootSource { 1373f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi public: 1383f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi GcRootSource() 1393f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi : field_(nullptr), method_(nullptr) { 1403f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1413f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi explicit GcRootSource(ArtField* field) 1423f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi : field_(field), method_(nullptr) { 1433f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1443f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi explicit GcRootSource(ArtMethod* method) 1453f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi : field_(nullptr), method_(method) { 1463f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1473f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ArtField* GetArtField() const { 1483f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi return field_; 1493f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1503f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ArtMethod* GetArtMethod() const { 1513f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi return method_; 1523f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1533f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi bool HasArtField() const { 1543f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi return field_ != nullptr; 1553f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1563f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi bool HasArtMethod() const { 1573f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi return method_ != nullptr; 1583f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi } 1593f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi 1603f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi private: 1613f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ArtField* const field_; 1623f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ArtMethod* const method_; 1633f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi 1643f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi DISALLOW_COPY_AND_ASSIGN(GcRootSource); 1653f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi}; 1663f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi 16794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchitemplate<class MirrorType> 1689e47bfa71d42df101aff9d156a1b296eaf6566a2Hiroshi Yamauchiclass GcRoot { 16994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi public: 17094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier> 1713f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi ALWAYS_INLINE MirrorType* Read(GcRootSource* gc_root_source = nullptr) const 17290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 17394f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 174bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(RootVisitor* visitor, const RootInfo& info) const 17590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 176eb175f70ef352ce0b9bcafdf06c5ac22b0ff626aMathieu Chartier DCHECK(!IsNull()); 177bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::CompressedReference<mirror::Object>* roots[1] = { &root_ }; 178bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor->VisitRoots(roots, 1u, info); 179eb175f70ef352ce0b9bcafdf06c5ac22b0ff626aMathieu Chartier DCHECK(!IsNull()); 18094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 18194f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 182bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRootIfNonNull(RootVisitor* visitor, const RootInfo& info) const 18390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 184e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier if (!IsNull()) { 185bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(visitor, info); 186e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 187e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier } 188e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier 189bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ALWAYS_INLINE mirror::CompressedReference<mirror::Object>* AddressWithoutBarrier() { 19094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi return &root_; 19194f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 19294f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 193bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ALWAYS_INLINE bool IsNull() const { 19494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi // It's safe to null-check it without a read barrier. 195bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier return root_.IsNull(); 19694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 19794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 19865975776f807d55c83af6cca1e447f8daa794413Mathieu Chartier ALWAYS_INLINE GcRoot() {} 19965975776f807d55c83af6cca1e447f8daa794413Mathieu Chartier explicit ALWAYS_INLINE GcRoot(MirrorType* ref) SHARED_REQUIRES(Locks::mutator_lock_); 200bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 201bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private: 2020d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain // Root visitors take pointers to root_ and place them in CompressedReference** arrays. We use a 2039086b65b2ad35dd39a8afc62d535be8217208d08Mathieu Chartier // CompressedReference<mirror::Object> here since it violates strict aliasing requirements to 2049086b65b2ad35dd39a8afc62d535be8217208d08Mathieu Chartier // cast CompressedReference<MirrorType>* to CompressedReference<mirror::Object>*. 205bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mutable mirror::CompressedReference<mirror::Object> root_; 206bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 207bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <size_t kBufferSize> friend class BufferedRootVisitor; 208bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 209bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 210bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// Simple data structure for buffered root visiting to avoid virtual dispatch overhead. Currently 211bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// only for CompressedReferences since these are more common than the Object** roots which are only 212bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier// for thread local roots. 213bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiertemplate <size_t kBufferSize> 214bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass BufferedRootVisitor { 215bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public: 216bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier BufferedRootVisitor(RootVisitor* visitor, const RootInfo& root_info) 217bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier : visitor_(visitor), root_info_(root_info), buffer_pos_(0) { 218bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 219bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 220bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ~BufferedRootVisitor() { 221bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier Flush(); 222bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 223bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 224bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <class MirrorType> 225bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ALWAYS_INLINE void VisitRootIfNonNull(GcRoot<MirrorType>& root) 22690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 227bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (!root.IsNull()) { 228bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(root); 229bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 230bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 231bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 232bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <class MirrorType> 233bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<MirrorType>* root) 23490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 235bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (!root->IsNull()) { 236bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(root); 237bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 238bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 239bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 240bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <class MirrorType> 24190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void VisitRoot(GcRoot<MirrorType>& root) SHARED_REQUIRES(Locks::mutator_lock_) { 242bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VisitRoot(root.AddressWithoutBarrier()); 243bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 244bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 245bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier template <class MirrorType> 246bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(mirror::CompressedReference<MirrorType>* root) 24790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 248bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (UNLIKELY(buffer_pos_ >= kBufferSize)) { 249bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier Flush(); 250bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 251bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier roots_[buffer_pos_++] = root; 25294f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 25394f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 25490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void Flush() SHARED_REQUIRES(Locks::mutator_lock_) { 255bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor_->VisitRoots(roots_, buffer_pos_, root_info_); 256bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier buffer_pos_ = 0; 25794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi } 25894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 25994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi private: 260bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootVisitor* const visitor_; 261bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootInfo root_info_; 262bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::CompressedReference<mirror::Object>* roots_[kBufferSize]; 263bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier size_t buffer_pos_; 26494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi}; 26594f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 26694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi} // namespace art 26794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi 26894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#endif // ART_RUNTIME_GC_ROOT_H_ 269