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