blob: 6bc06d600d09c553f629632298bf4a017a4f568c [file] [log] [blame]
Mathieu Chartierb062fdd2012-07-03 09:51:48 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080017#ifndef ART_SRC_GC_SPACE_BITMAP_H_
18#define ART_SRC_GC_SPACE_BITMAP_H_
19
20#include "locks.h"
21#include "globals.h"
22#include "mem_map.h"
23#include "UniquePtr.h"
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070024
25#include <limits.h>
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -070026#include <set>
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070027#include <stdint.h>
28#include <vector>
29
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070030namespace art {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031namespace mirror {
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070032class Object;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080033} // namespace mirror
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070034
35class SpaceBitmap {
36 public:
37 static const size_t kAlignment = 8;
38
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080039 typedef void Callback(mirror::Object* obj, void* arg);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070040
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080041 typedef void ScanCallback(mirror::Object* obj, void* finger, void* arg);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070042
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043 typedef void SweepCallback(size_t ptr_count, mirror::Object** ptrs, void* arg);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070044
45 // Initialize a HeapBitmap so that it points to a bitmap large enough to cover a heap at
46 // heap_begin of heap_capacity bytes, where objects are guaranteed to be kAlignment-aligned.
47 static SpaceBitmap* Create(const std::string& name, byte* heap_begin, size_t heap_capacity);
48
49 ~SpaceBitmap();
50
51 // <offset> is the difference from .base to a pointer address.
52 // <index> is the index of .bits that contains the bit representing
53 // <offset>.
54 static size_t OffsetToIndex(size_t offset) {
55 return offset / kAlignment / kBitsPerWord;
56 }
57
58 static uintptr_t IndexToOffset(size_t index) {
59 return static_cast<uintptr_t>(index * kAlignment * kBitsPerWord);
60 }
61
62 // Pack the bits in backwards so they come out in address order when using CLZ.
63 static word OffsetToMask(uintptr_t offset_) {
Mathieu Chartierdcf8d722012-08-02 14:55:54 -070064 return static_cast<uintptr_t>(kWordHighBitMask) >> ((offset_ / kAlignment) % kBitsPerWord);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070065 }
66
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080067 inline bool Set(const mirror::Object* obj) {
Mathieu Chartier02b6a782012-10-26 13:51:26 -070068 return Modify(obj, true);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070069 }
70
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080071 inline bool Clear(const mirror::Object* obj) {
Mathieu Chartier02b6a782012-10-26 13:51:26 -070072 return Modify(obj, false);
73 }
74
75 // Returns true if the object was previously marked.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080076 bool AtomicTestAndSet(const mirror::Object* obj);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070077
78 void Clear();
79
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080080 bool Test(const mirror::Object* obj) const;
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070081
Ian Rogers506de0c2012-09-17 15:39:06 -070082 // Return true iff <obj> is within the range of pointers that this bitmap could potentially cover,
83 // even if a bit has not been set for it.
84 bool HasAddress(const void* obj) const {
85 // If obj < heap_begin_ then offset underflows to some very large value past the end of the
86 // bitmap.
buzbeecbd6d442012-11-17 14:11:25 -080087 const uintptr_t offset = reinterpret_cast<uintptr_t>(obj) - heap_begin_;
Ian Rogers506de0c2012-09-17 15:39:06 -070088 const size_t index = OffsetToIndex(offset);
89 return index < bitmap_size_ / kWordSize;
90 }
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070091
92 void VisitRange(uintptr_t base, uintptr_t max, Callback* visitor, void* arg) const;
93
94 class ClearVisitor {
95 public:
96 explicit ClearVisitor(SpaceBitmap* const bitmap)
97 : bitmap_(bitmap) {
98 }
99
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800100 void operator ()(mirror::Object* obj) const {
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700101 bitmap_->Clear(obj);
102 }
103 private:
104 SpaceBitmap* const bitmap_;
105 };
106
107 template <typename Visitor>
108 void VisitRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const {
109 for (; visit_begin < visit_end; visit_begin += kAlignment ) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800110 visitor(reinterpret_cast<mirror::Object*>(visit_begin));
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700111 }
112 }
113
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700114 template <typename Visitor, typename FingerVisitor>
115 void VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end,
116 const Visitor& visitor, const FingerVisitor& finger_visitor) const
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800117 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
118 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700119
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700120 void Walk(Callback* callback, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700121 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700122
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700123 void InOrderWalk(Callback* callback, void* arg)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800124 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700125
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700126 static void SweepWalk(const SpaceBitmap& live,
127 const SpaceBitmap& mark,
128 uintptr_t base, uintptr_t max,
129 SweepCallback* thunk, void* arg);
130
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700131 void CopyFrom(SpaceBitmap* source_bitmap);
132
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700133 // Starting address of our internal storage.
134 word* Begin() {
135 return bitmap_begin_;
136 }
137
138 // Size of our internal storage
139 size_t Size() const {
140 return bitmap_size_;
141 }
142
143 // Size in bytes of the memory that the bitmaps spans.
144 size_t HeapSize() const {
145 return IndexToOffset(Size() / kWordSize);
146 }
147
Mathieu Chartierdcf8d722012-08-02 14:55:54 -0700148 uintptr_t HeapBegin() const {
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700149 return heap_begin_;
150 }
151
Mathieu Chartierdcf8d722012-08-02 14:55:54 -0700152 // The maximum address which the bitmap can span. (HeapBegin() <= object < HeapLimit()).
153 uintptr_t HeapLimit() const {
154 return HeapBegin() + static_cast<uintptr_t>(HeapSize());
155 }
156
157 // Set the max address which can covered by the bitmap.
158 void SetHeapLimit(uintptr_t new_end);
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700159
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700160 std::string GetName() const;
161 void SetName(const std::string& name);
162
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800163 const void* GetObjectWordAddress(const mirror::Object* obj) const {
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700164 uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
165 const uintptr_t offset = addr - heap_begin_;
166 const size_t index = OffsetToIndex(offset);
167 return &bitmap_begin_[index];
168 }
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700169 private:
170 // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
171 // however, we document that this is expected on heap_end_
172 SpaceBitmap(const std::string& name, MemMap* mem_map, word* bitmap_begin, size_t bitmap_size, const void* heap_begin)
173 : mem_map_(mem_map), bitmap_begin_(bitmap_begin), bitmap_size_(bitmap_size),
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700174 heap_begin_(reinterpret_cast<uintptr_t>(heap_begin)),
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700175 name_(name) {}
176
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800177 bool Modify(const mirror::Object* obj, bool do_set);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700178
179 // Backing storage for bitmap.
180 UniquePtr<MemMap> mem_map_;
181
182 // This bitmap itself, word sized for efficiency in scanning.
183 word* const bitmap_begin_;
184
185 // Size of this bitmap.
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700186 size_t bitmap_size_;
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700187
188 // The base address of the heap, which corresponds to the word containing the first bit in the
189 // bitmap.
190 const uintptr_t heap_begin_;
191
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700192 // Name of this bitmap.
193 std::string name_;
194};
195
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -0700196// Like a bitmap except it keeps track of objects using sets.
197class SpaceSetMap {
198 public:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800199 typedef std::set<const mirror::Object*> Objects;
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -0700200
201 bool IsEmpty() const {
202 return contained_.empty();
203 }
204
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800205 inline void Set(const mirror::Object* obj) {
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -0700206 contained_.insert(obj);
207 }
208
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800209 inline void Clear(const mirror::Object* obj) {
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -0700210 Objects::iterator found = contained_.find(obj);
211 if (found != contained_.end()) {
212 contained_.erase(found);
213 }
214 }
215
216 void Clear() {
217 contained_.clear();
218 }
219
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800220 inline bool Test(const mirror::Object* obj) const {
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -0700221 return contained_.find(obj) != contained_.end();
222 }
223
224 std::string GetName() const;
225 void SetName(const std::string& name);
226
227 void Walk(SpaceBitmap::Callback* callback, void* arg)
228 SHARED_LOCKS_REQUIRED(GlobalSynchronization::heap_bitmap_lock_);
229
230 void CopyFrom(const SpaceSetMap& space_set);
231
232 template <typename Visitor>
233 void Visit(const Visitor& visitor) NO_THREAD_SAFETY_ANALYSIS {
234 for (Objects::iterator it = contained_.begin(); it != contained_.end(); ++it) {
235 visitor(*it);
236 }
237 }
238
239 SpaceSetMap(const std::string& name);
240
241 Objects& GetObjects() {
242 return contained_;
243 }
244
245 private:
246 std::string name_;
247 Objects contained_;
248};
249
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700250std::ostream& operator << (std::ostream& stream, const SpaceBitmap& bitmap);
251
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700252} // namespace art
253
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800254#endif // ART_SRC_GC_SPACE_BITMAP_H_