space_bitmap.h revision fc0e3219edc9a5bf81b166e82fd5db2796eb6a0d
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
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "locks.h"
212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "globals.h"
222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mem_map.h"
232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "UniquePtr.h"
24b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
25b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier#include <limits.h>
26e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier#include <set>
27b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier#include <stdint.h>
28b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier#include <vector>
29b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
30b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartiernamespace art {
311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  class Object;
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
35b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
361d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc {
371d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace accounting {
381d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
39b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartierclass SpaceBitmap {
40b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier public:
411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Alignment of objects within spaces.
42b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  static const size_t kAlignment = 8;
43b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  typedef void Callback(mirror::Object* obj, void* arg);
45b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  typedef void ScanCallback(mirror::Object* obj, void* finger, void* arg);
47b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  typedef void SweepCallback(size_t ptr_count, mirror::Object** ptrs, void* arg);
49b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
50b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Initialize a HeapBitmap so that it points to a bitmap large enough to cover a heap at
51b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // heap_begin of heap_capacity bytes, where objects are guaranteed to be kAlignment-aligned.
52b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  static SpaceBitmap* Create(const std::string& name, byte* heap_begin, size_t heap_capacity);
53b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
54b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  ~SpaceBitmap();
55b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
56b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // <offset> is the difference from .base to a pointer address.
57b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // <index> is the index of .bits that contains the bit representing
58b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  //         <offset>.
59b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  static size_t OffsetToIndex(size_t offset) {
601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return offset / kAlignment / kBitsPerWord;
61b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
62b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
63b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  static uintptr_t IndexToOffset(size_t index) {
64b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    return static_cast<uintptr_t>(index * kAlignment * kBitsPerWord);
65b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
66b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
67b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Pack the bits in backwards so they come out in address order when using CLZ.
68b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  static word OffsetToMask(uintptr_t offset_) {
69dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier    return static_cast<uintptr_t>(kWordHighBitMask) >> ((offset_ / kAlignment) % kBitsPerWord);
70b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
71b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  inline bool Set(const mirror::Object* obj) {
7302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    return Modify(obj, true);
74b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
75b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  inline bool Clear(const mirror::Object* obj) {
7702b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    return Modify(obj, false);
7802b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  }
7902b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier
8002b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  // Returns true if the object was previously marked.
812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  bool AtomicTestAndSet(const mirror::Object* obj);
82b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
831d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Fill the bitmap with zeroes.  Returns the bitmap's memory to the system as a side-effect.
84b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  void Clear();
85b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  bool Test(const mirror::Object* obj) const;
87b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
88506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  // Return true iff <obj> is within the range of pointers that this bitmap could potentially cover,
89506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  // even if a bit has not been set for it.
90506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  bool HasAddress(const void* obj) const {
91506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    // If obj < heap_begin_ then offset underflows to some very large value past the end of the
92506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    // bitmap.
93cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee    const uintptr_t offset = reinterpret_cast<uintptr_t>(obj) - heap_begin_;
94506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    const size_t index = OffsetToIndex(offset);
95506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers    return index < bitmap_size_ / kWordSize;
96506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers  }
97b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
98b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  void VisitRange(uintptr_t base, uintptr_t max, Callback* visitor, void* arg) const;
99b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
100b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  class ClearVisitor {
101b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier   public:
102b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    explicit ClearVisitor(SpaceBitmap* const bitmap)
103b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier        : bitmap_(bitmap) {
104b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
105b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
1062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    void operator ()(mirror::Object* obj) const {
107b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier      bitmap_->Clear(obj);
108b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
109b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier   private:
110b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    SpaceBitmap* const bitmap_;
111b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  };
112b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
113b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  template <typename Visitor>
114b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  void VisitRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const {
115b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    for (; visit_begin < visit_end; visit_begin += kAlignment ) {
1162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      visitor(reinterpret_cast<mirror::Object*>(visit_begin));
117b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier    }
118b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  }
119b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
120357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier  template <typename Visitor, typename FingerVisitor>
121357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier  void VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end,
122357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier                        const Visitor& visitor, const FingerVisitor& finger_visitor) const
1232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
1242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
125b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
126357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier  void Walk(Callback* callback, void* arg)
127b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
128b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
12900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void InOrderWalk(Callback* callback, void* arg)
1302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
131b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
132b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  static void SweepWalk(const SpaceBitmap& live,
133b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier                        const SpaceBitmap& mark,
134b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier                        uintptr_t base, uintptr_t max,
135b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier                        SweepCallback* thunk, void* arg);
136b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
137357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier  void CopyFrom(SpaceBitmap* source_bitmap);
138357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
139cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Starting address of our internal storage.
140cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  word* Begin() {
141cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return bitmap_begin_;
142cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
143cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
144cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Size of our internal storage
145cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  size_t Size() const {
146cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return bitmap_size_;
147cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
148cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
149cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  // Size in bytes of the memory that the bitmaps spans.
150cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  size_t HeapSize() const {
151cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return IndexToOffset(Size() / kWordSize);
152cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
153cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
154dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  uintptr_t HeapBegin() const {
155cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier    return heap_begin_;
156cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  }
157cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
158dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  // The maximum address which the bitmap can span. (HeapBegin() <= object < HeapLimit()).
159dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  uintptr_t HeapLimit() const {
160dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier    return HeapBegin() + static_cast<uintptr_t>(HeapSize());
161dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  }
162dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier
163dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  // Set the max address which can covered by the bitmap.
164dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier  void SetHeapLimit(uintptr_t new_end);
165cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier
166357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier  std::string GetName() const;
167357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier  void SetName(const std::string& name);
168357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
1691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  std::string Dump() const;
1701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const void* GetObjectWordAddress(const mirror::Object* obj) const {
17202b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
17302b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    const uintptr_t offset = addr - heap_begin_;
17402b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    const size_t index = OffsetToIndex(offset);
17502b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier    return &bitmap_begin_[index];
17602b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier  }
177b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier private:
178b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
179b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // however, we document that this is expected on heap_end_
180b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  SpaceBitmap(const std::string& name, MemMap* mem_map, word* bitmap_begin, size_t bitmap_size, const void* heap_begin)
181b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier      : mem_map_(mem_map), bitmap_begin_(bitmap_begin), bitmap_size_(bitmap_size),
182357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier        heap_begin_(reinterpret_cast<uintptr_t>(heap_begin)),
183b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier        name_(name) {}
184b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
1852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  bool Modify(const mirror::Object* obj, bool do_set);
186b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
187b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Backing storage for bitmap.
188b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  UniquePtr<MemMap> mem_map_;
189b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
190b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // This bitmap itself, word sized for efficiency in scanning.
191b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  word* const bitmap_begin_;
192b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
193b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Size of this bitmap.
194cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier  size_t bitmap_size_;
195b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
196b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // The base address of the heap, which corresponds to the word containing the first bit in the
197b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // bitmap.
198b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  const uintptr_t heap_begin_;
199b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
200b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  // Name of this bitmap.
201b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier  std::string name_;
202b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier};
203b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
204e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier// Like a bitmap except it keeps track of objects using sets.
205e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartierclass SpaceSetMap {
206e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier public:
2072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  typedef std::set<const mirror::Object*> Objects;
208e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
209e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  bool IsEmpty() const {
210e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    return contained_.empty();
211e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  }
212e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
2132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  inline void Set(const mirror::Object* obj) {
214e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    contained_.insert(obj);
215e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  }
216e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
2172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  inline void Clear(const mirror::Object* obj) {
218e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    Objects::iterator found = contained_.find(obj);
219e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    if (found != contained_.end()) {
220e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier      contained_.erase(found);
221e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    }
222e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  }
223e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
224e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  void Clear() {
225e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    contained_.clear();
226e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  }
227e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
2282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  inline bool Test(const mirror::Object* obj) const {
229e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    return contained_.find(obj) != contained_.end();
230e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  }
231e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
232e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  std::string GetName() const;
233e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  void SetName(const std::string& name);
234e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
235e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  void Walk(SpaceBitmap::Callback* callback, void* arg)
236e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier      SHARED_LOCKS_REQUIRED(GlobalSynchronization::heap_bitmap_lock_);
237e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
238e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  void CopyFrom(const SpaceSetMap& space_set);
239e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
240e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  template <typename Visitor>
241e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  void Visit(const Visitor& visitor) NO_THREAD_SAFETY_ANALYSIS {
242e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    for (Objects::iterator it = contained_.begin(); it != contained_.end(); ++it) {
243e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier      visitor(*it);
244e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    }
245e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  }
246e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
2471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  SpaceSetMap(const std::string& name) : name_(name) {}
2481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  ~SpaceSetMap() {}
249e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
250e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  Objects& GetObjects() {
251e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier    return contained_;
252e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  }
253e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
254e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier private:
255e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  std::string name_;
256e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier  Objects contained_;
257e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier};
258e0f0cb3d855cb5e926452b5e1ec8457adc4e454eMathieu Chartier
259357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartierstd::ostream& operator << (std::ostream& stream, const SpaceBitmap& bitmap);
260357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier
2611d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace accounting
2621d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
263b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier}  // namespace art
264b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier
265fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
266