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"
28b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
29b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartiernamespace art {
301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
322ffb703bf431d74326c88266b4ddaf225eb3c6adIgor Murashkinclass Class;
332ffb703bf431d74326c88266b4ddaf225eb3c6adIgor Murashkinclass 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.
4813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  static SpaceBitmap* Create(const std::string& name, uint8_t* 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,
5413735955f39b3b304c37d2b2840663c131262c18Ian Rogers                                       uint8_t* heap_begin, size_t heap_capacity);
5531e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier
5622d5e735f403c57525fe868304c7123f0ce66399Ian Rogers  ~SpaceBitmap();
57b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
588f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Return the bitmap word index corresponding to memory offset (relative to
598f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // `HeapBegin()`) `offset`.
608f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // See also SpaceBitmap::OffsetBitIndex.
618f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  //
62b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // <offset> is the difference from .base to a pointer address.
63b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // <index> is the index of .bits that contains the bit representing
64b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  //         <offset>.
65be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers  static constexpr size_t OffsetToIndex(size_t offset) {
6613735955f39b3b304c37d2b2840663c131262c18Ian Rogers    return offset / kAlignment / kBitsPerIntPtrT;
67b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
68b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
698f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Return the memory offset (relative to `HeapBegin()`) corresponding to
708f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // bitmap word index `index`.
716f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  template<typename T>
72be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers  static constexpr T IndexToOffset(T index) {
7313735955f39b3b304c37d2b2840663c131262c18Ian Rogers    return static_cast<T>(index * kAlignment * kBitsPerIntPtrT);
74b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
75b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
768f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Return the bit within the bitmap word index corresponding to
778f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // memory offset (relative to `HeapBegin()`) `offset`.
788f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // See also SpaceBitmap::OffsetToIndex.
797ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier  ALWAYS_INLINE static constexpr uintptr_t OffsetBitIndex(uintptr_t offset) {
807ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier    return (offset / kAlignment) % kBitsPerIntPtrT;
817ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier  }
827ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier
838f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Return the word-wide bit mask corresponding to `OffsetBitIndex(offset)`.
84cb8aea4bd5e77857c713edeb62bffcb1f7f06a39Andreas Gampe  // Bits are packed in the obvious way.
8513735955f39b3b304c37d2b2840663c131262c18Ian Rogers  static constexpr uintptr_t OffsetToMask(uintptr_t offset) {
867ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier    return static_cast<size_t>(1) << OffsetBitIndex(offset);
87b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
88b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
898f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Set the bit corresponding to `obj` in the bitmap and return the previous value of that bit.
90a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  bool Set(const mirror::Object* obj) ALWAYS_INLINE {
91a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier    return Modify<true>(obj);
92b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
93b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
948f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Clear the bit corresponding to `obj` in the bitmap and return the previous value of that bit.
95a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  bool Clear(const mirror::Object* obj) ALWAYS_INLINE {
96a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier    return Modify<false>(obj);
9702b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  }
9802b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier
9902b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  // Returns true if the object was previously marked.
1002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  bool AtomicTestAndSet(const mirror::Object* obj);
101b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Fill the bitmap with zeroes.  Returns the bitmap's memory to the system as a side-effect.
103b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  void Clear();
104b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
1058f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Clear a range covered by the bitmap using madvise if possible.
1067ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier  void ClearRange(const mirror::Object* begin, const mirror::Object* end);
1077ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier
1088f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Test whether `obj` is part of the bitmap (i.e. return whether the bit
1098f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // corresponding to `obj` has been set in the bitmap).
1108f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  //
1118f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Precondition: `obj` is within the range of pointers that this bitmap could
1128f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // potentially cover (i.e. `this->HasAddress(obj)` is true)
1132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  bool Test(const mirror::Object* obj) const;
114b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
115506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  // Return true iff <obj> is within the range of pointers that this bitmap could potentially cover,
116506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  // even if a bit has not been set for it.
117506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  bool HasAddress(const void* obj) const {
118506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    // If obj < heap_begin_ then offset underflows to some very large value past the end of the
119506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    // bitmap.
120cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee    const uintptr_t offset = reinterpret_cast<uintptr_t>(obj) - heap_begin_;
121506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    const size_t index = OffsetToIndex(offset);
12213735955f39b3b304c37d2b2840663c131262c18Ian Rogers    return index < bitmap_size_ / sizeof(intptr_t);
123506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  }
124b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
125b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  class ClearVisitor {
126b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier   public:
127b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    explicit ClearVisitor(SpaceBitmap* const bitmap)
128b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier        : bitmap_(bitmap) {
129b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
130b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
131df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom    void operator()(mirror::Object* obj) const {
132b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier      bitmap_->Clear(obj);
133b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
134b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier   private:
135b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    SpaceBitmap* const bitmap_;
136b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  };
137b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
138b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  template <typename Visitor>
139b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  void VisitRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const {
140df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom    for (; visit_begin < visit_end; visit_begin += kAlignment) {
1412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      visitor(reinterpret_cast<mirror::Object*>(visit_begin));
142b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
143b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
144b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
145e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier  // Visit the live objects in the range [visit_begin, visit_end).
146e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier  // TODO: Use lock annotations when clang is fixed.
147bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  // REQUIRES(Locks::heap_bitmap_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
148184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier  template <typename Visitor>
149351c44765279142d15333e2ae02b8a423d195b1bAndreas Gampe  void VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end, Visitor&& visitor) const
150e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier      NO_THREAD_SAFETY_ANALYSIS;
151b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
152a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // Visits set bits in address order.  The callback is not permitted to change the bitmap bits or
153a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // max during the traversal.
1540c18338ebae6b3597c882887f8354b64abb5e90fAndreas Gampe  template <typename Visitor>
1550c18338ebae6b3597c882887f8354b64abb5e90fAndreas Gampe  void Walk(Visitor&& visitor)
1560c18338ebae6b3597c882887f8354b64abb5e90fAndreas Gampe      REQUIRES_SHARED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
157b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
158a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // Walk through the bitmaps in increasing address order, and find the object pointers that
159a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // correspond to garbage objects.  Call <callback> zero or more times with lists of these object
160a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  // pointers. The callback is not permitted to increase the max of either bitmap.
161184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier  static void SweepWalk(const SpaceBitmap& live, const SpaceBitmap& mark, uintptr_t base,
162184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier                        uintptr_t max, SweepCallback* thunk, void* arg);
163b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
164357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier  void CopyFrom(SpaceBitmap* source_bitmap);
165357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
166cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Starting address of our internal storage.
167c381c36aacf977f7e314e6a91e47b31b04639f62Mathieu Chartier  Atomic<uintptr_t>* Begin() {
168cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return bitmap_begin_;
169cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
170cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
171cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Size of our internal storage
172cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  size_t Size() const {
173cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return bitmap_size_;
174cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
175cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
176cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Size in bytes of the memory that the bitmaps spans.
1776f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  uint64_t HeapSize() const {
17813735955f39b3b304c37d2b2840663c131262c18Ian Rogers    return IndexToOffset<uint64_t>(Size() / sizeof(intptr_t));
179cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
180cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
181379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier  void SetHeapSize(size_t bytes) {
182379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier    // TODO: Un-map the end of the mem map.
1832a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier    heap_limit_ = heap_begin_ + bytes;
184379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier    bitmap_size_ = OffsetToIndex(bytes) * sizeof(intptr_t);
185379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier    CHECK_EQ(HeapSize(), bytes);
186379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier  }
187379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier
188dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  uintptr_t HeapBegin() const {
189cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return heap_begin_;
190cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
191cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
192dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  // The maximum address which the bitmap can span. (HeapBegin() <= object < HeapLimit()).
1936f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  uint64_t HeapLimit() const {
1942a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier    return heap_limit_;
195dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  }
196dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier
197dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  // Set the max address which can covered by the bitmap.
198dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  void SetHeapLimit(uintptr_t new_end);
199cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
200a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  std::string GetName() const {
201a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier    return name_;
202a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  }
203a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier
204a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  void SetName(const std::string& name) {
205a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier    name_ = name;
206a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  }
207357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
208576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers  std::string Dump() const;
2091d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
210d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier  // Helper function for computing bitmap size based on a 64 bit capacity.
211d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier  static size_t ComputeBitmapSize(uint64_t capacity);
212d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier  static size_t ComputeHeapSize(uint64_t bitmap_bytes);
213d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier
214b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier private:
215b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
216b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // however, we document that this is expected on heap_end_
2172a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier  SpaceBitmap(const std::string& name,
2182a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier              MemMap* mem_map,
2192a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier              uintptr_t* bitmap_begin,
2202a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier              size_t bitmap_size,
2212a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier              const void* heap_begin,
2222a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier              size_t heap_capacity);
223b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
2248f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // Change the value of the bit corresponding to `obj` in the bitmap
2258f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain  // to `kSetBit` and return the previous value of that bit.
226a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  template<bool kSetBit>
227a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  bool Modify(const mirror::Object* obj);
228a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier
229b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Backing storage for bitmap.
230700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<MemMap> mem_map_;
231b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
232b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // This bitmap itself, word sized for efficiency in scanning.
233c381c36aacf977f7e314e6a91e47b31b04639f62Mathieu Chartier  Atomic<uintptr_t>* const bitmap_begin_;
234b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
235b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Size of this bitmap.
236cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  size_t bitmap_size_;
237b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
2382a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier  // The start address of the memory covered by the bitmap, which corresponds to the word
2392a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier  // containing the first bit in the bitmap.
240b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  const uintptr_t heap_begin_;
241b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
2422a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier  // The end address of the memory covered by the bitmap. This may not be on a word boundary.
2432a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier  uintptr_t heap_limit_;
2442a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier
245b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Name of this bitmap.
246b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  std::string name_;
247b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier};
248b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
249a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertypedef SpaceBitmap<kObjectAlignment> ContinuousSpaceBitmap;
250a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertypedef SpaceBitmap<kLargeObjectAlignment> LargeObjectBitmap;
251a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier
252a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertemplate<size_t kAlignment>
253a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartierstd::ostream& operator << (std::ostream& stream, const SpaceBitmap<kAlignment>& bitmap);
254357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
2551d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace accounting
2561d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
257b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier}  // namespace art
258b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
259fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
260