1b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier/*
2b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * Copyright (C) 2008 The Android Open Source Project
3b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier *
4b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License");
5b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * you may not use this file except in compliance with the License.
6b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * You may obtain a copy of the License at
7b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier *
8b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier *      http://www.apache.org/licenses/LICENSE-2.0
9b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier *
10b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * Unless required by applicable law or agreed to in writing, software
11b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS,
12b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * See the License for the specific language governing permissions and
14b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * limitations under the License.
15b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier */
16b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <limits.h>
21700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <stdint.h>
22700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory>
23700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <set>
24700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <vector>
25700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers
26719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "base/mutex.h"
272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "globals.h"
2883c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier#include "object_callbacks.h"
29b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
30b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartiernamespace art {
311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  class Object;
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
35576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogersclass MemMap;
36b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
371d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc {
381d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace accounting {
391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
40a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertemplate<size_t kAlignment>
41b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartierclass SpaceBitmap {
42b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier public:
432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  typedef void ScanCallback(mirror::Object* obj, void* finger, void* arg);
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  typedef void SweepCallback(size_t ptr_count, mirror::Object** ptrs, void* arg);
45b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
4631e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier  // Initialize a space bitmap so that it points to a bitmap large enough to cover a heap at
47b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // heap_begin of heap_capacity bytes, where objects are guaranteed to be kAlignment-aligned.
48b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  static SpaceBitmap* Create(const std::string& name, byte* heap_begin, size_t heap_capacity);
49b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
5031e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier  // Initialize a space bitmap using the provided mem_map as the live bits. Takes ownership of the
5131e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier  // mem map. The address range covered starts at heap_begin and is of size equal to heap_capacity.
5231e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier  // Objects are kAlignement-aligned.
5331e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier  static SpaceBitmap* CreateFromMemMap(const std::string& name, MemMap* mem_map,
5431e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier                                       byte* heap_begin, size_t heap_capacity);
5531e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier
5622d5e735f403c57525fe868304c7123f0ce66399Ian Rogers  ~SpaceBitmap();
57b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
58b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // <offset> is the difference from .base to a pointer address.
59b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // <index> is the index of .bits that contains the bit representing
60b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  //         <offset>.
61be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers  static constexpr size_t OffsetToIndex(size_t offset) {
621d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return offset / kAlignment / kBitsPerWord;
63b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
64b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
656f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  template<typename T>
66be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers  static constexpr T IndexToOffset(T index) {
676f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier    return static_cast<T>(index * kAlignment * kBitsPerWord);
68b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
69b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
70cb8aea4bd5e77857c713edeb62bffcb1f7f06a39Andreas Gampe  // Bits are packed in the obvious way.
71be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers  static constexpr uword OffsetToMask(uintptr_t offset) {
72cb8aea4bd5e77857c713edeb62bffcb1f7f06a39Andreas Gampe    return (static_cast<size_t>(1)) << ((offset / kAlignment) % kBitsPerWord);
73b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
74b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
75a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  bool Set(const mirror::Object* obj) ALWAYS_INLINE {
76a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier    return Modify<true>(obj);
77b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
78b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
79a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  bool Clear(const mirror::Object* obj) ALWAYS_INLINE {
80a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier    return Modify<false>(obj);
8102b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  }
8202b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier
8302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  // Returns true if the object was previously marked.
842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  bool AtomicTestAndSet(const mirror::Object* obj);
85b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
861d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Fill the bitmap with zeroes.  Returns the bitmap's memory to the system as a side-effect.
87b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  void Clear();
88b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  bool Test(const mirror::Object* obj) const;
90b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
91506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  // Return true iff <obj> is within the range of pointers that this bitmap could potentially cover,
92506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  // even if a bit has not been set for it.
93506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  bool HasAddress(const void* obj) const {
94506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    // If obj < heap_begin_ then offset underflows to some very large value past the end of the
95506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    // bitmap.
96cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee    const uintptr_t offset = reinterpret_cast<uintptr_t>(obj) - heap_begin_;
97506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    const size_t index = OffsetToIndex(offset);
98506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    return index < bitmap_size_ / kWordSize;
99506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  }
100b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
10183c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier  void VisitRange(uintptr_t base, uintptr_t max, ObjectCallback* callback, void* arg) const;
102b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
103b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  class ClearVisitor {
104b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier   public:
105b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    explicit ClearVisitor(SpaceBitmap* const bitmap)
106b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier        : bitmap_(bitmap) {
107b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
108b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
109df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom    void operator()(mirror::Object* obj) const {
110b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier      bitmap_->Clear(obj);
111b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
112b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier   private:
113b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    SpaceBitmap* const bitmap_;
114b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  };
115b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
116b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  template <typename Visitor>
117b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  void VisitRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const {
118df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom    for (; visit_begin < visit_end; visit_begin += kAlignment) {
1192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      visitor(reinterpret_cast<mirror::Object*>(visit_begin));
120b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
121b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
122b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
123e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier  // Visit the live objects in the range [visit_begin, visit_end).
124e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier  // TODO: Use lock annotations when clang is fixed.
125e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier  // EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
126184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier  template <typename Visitor>
127184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier  void VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const
128e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier      NO_THREAD_SAFETY_ANALYSIS;
129b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
130a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // Visits set bits in address order.  The callback is not permitted to change the bitmap bits or
131a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // max during the traversal.
13283c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier  void Walk(ObjectCallback* callback, void* arg)
133b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
134b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
135a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // Visits set bits with an in order traversal.  The callback is not permitted to change the bitmap
136a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // bits or max during the traversal.
13783c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier  void InOrderWalk(ObjectCallback* callback, void* arg)
1382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
139b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
140a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // Walk through the bitmaps in increasing address order, and find the object pointers that
141a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // correspond to garbage objects.  Call <callback> zero or more times with lists of these object
142a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // pointers. The callback is not permitted to increase the max of either bitmap.
143184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier  static void SweepWalk(const SpaceBitmap& live, const SpaceBitmap& mark, uintptr_t base,
144184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier                        uintptr_t max, SweepCallback* thunk, void* arg);
145b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
146357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier  void CopyFrom(SpaceBitmap* source_bitmap);
147357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
148cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Starting address of our internal storage.
149cb8aea4bd5e77857c713edeb62bffcb1f7f06a39Andreas Gampe  uword* Begin() {
150cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return bitmap_begin_;
151cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
152cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
153cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Size of our internal storage
154cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  size_t Size() const {
155cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return bitmap_size_;
156cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
157cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
158cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Size in bytes of the memory that the bitmaps spans.
1596f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  uint64_t HeapSize() const {
1606f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier    return IndexToOffset<uint64_t>(Size() / kWordSize);
161cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
162cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
163dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  uintptr_t HeapBegin() const {
164cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return heap_begin_;
165cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
166cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
167dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  // The maximum address which the bitmap can span. (HeapBegin() <= object < HeapLimit()).
1686f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  uint64_t HeapLimit() const {
1696f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier    return static_cast<uint64_t>(HeapBegin()) + HeapSize();
170dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  }
171dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier
172dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  // Set the max address which can covered by the bitmap.
173dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  void SetHeapLimit(uintptr_t new_end);
174cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
175a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  std::string GetName() const {
176a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier    return name_;
177a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  }
178a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier
179a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  void SetName(const std::string& name) {
180a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier    name_ = name;
181a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  }
182357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
183576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers  std::string Dump() const;
1841d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const void* GetObjectWordAddress(const mirror::Object* obj) const {
18602b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
18702b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    const uintptr_t offset = addr - heap_begin_;
18802b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    const size_t index = OffsetToIndex(offset);
18902b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    return &bitmap_begin_[index];
19002b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  }
1910cd7ec2dcd8d7ba30bf3ca420b40dac52849876cBrian Carlstrom
192b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier private:
193b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
194b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // however, we document that this is expected on heap_end_
195cb8aea4bd5e77857c713edeb62bffcb1f7f06a39Andreas Gampe  SpaceBitmap(const std::string& name, MemMap* mem_map, uword* bitmap_begin, size_t bitmap_size,
196bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier              const void* heap_begin);
197b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
19873d1e17b3afc7d5e56184f90bf819dc64956448aMathieu Chartier  // Helper function for computing bitmap size based on a 64 bit capacity.
19973d1e17b3afc7d5e56184f90bf819dc64956448aMathieu Chartier  static size_t ComputeBitmapSize(uint64_t capacity);
20073d1e17b3afc7d5e56184f90bf819dc64956448aMathieu Chartier
201a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  template<bool kSetBit>
202a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  bool Modify(const mirror::Object* obj);
203a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier
204a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // For an unvisited object, visit it then all its children found via fields.
205a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  static void WalkFieldsInOrder(SpaceBitmap* visited, ObjectCallback* callback, mirror::Object* obj,
206a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier                                void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
207a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // Walk instance fields of the given Class. Separate function to allow recursion on the super
208a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // class.
209a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  static void WalkInstanceFields(SpaceBitmap<kAlignment>* visited, ObjectCallback* callback,
210a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier                                 mirror::Object* obj, mirror::Class* klass, void* arg)
211a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
212b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
213b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Backing storage for bitmap.
214700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<MemMap> mem_map_;
215b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
216b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // This bitmap itself, word sized for efficiency in scanning.
217cb8aea4bd5e77857c713edeb62bffcb1f7f06a39Andreas Gampe  uword* const bitmap_begin_;
218b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
219b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Size of this bitmap.
220cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  size_t bitmap_size_;
221b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
222b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // The base address of the heap, which corresponds to the word containing the first bit in the
223b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // bitmap.
224b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  const uintptr_t heap_begin_;
225b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
226b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Name of this bitmap.
227b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  std::string name_;
228b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier};
229b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
230a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertypedef SpaceBitmap<kObjectAlignment> ContinuousSpaceBitmap;
231a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertypedef SpaceBitmap<kLargeObjectAlignment> LargeObjectBitmap;
232a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier
233a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertemplate<size_t kAlignment>
234a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartierstd::ostream& operator << (std::ostream& stream, const SpaceBitmap<kAlignment>& bitmap);
235357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
2361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace accounting
2371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
238b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier}  // namespace art
239b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
240fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
241