blob: 189462f5d3cfbc9ab1052b15481dfa1db945e24d [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Carl Shapiro69759ea2011-07-21 18:13:35 -070016
17#ifndef ART_SRC_MARK_SWEEP_H_
18#define ART_SRC_MARK_SWEEP_H_
19
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070020#include "macros.h"
21#include "mark_stack.h"
Elliott Hughes5e71b522011-10-20 13:12:32 -070022#include "heap_bitmap.h"
Mathieu Chartierb43b7d42012-06-19 13:15:09 -070023#include "object.h"
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070024#include "offsets.h"
Carl Shapiro69759ea2011-07-21 18:13:35 -070025
26namespace art {
27
Mathieu Chartierb43b7d42012-06-19 13:15:09 -070028class CheckObjectVisitor;
Carl Shapiro69759ea2011-07-21 18:13:35 -070029class Class;
Elliott Hughesb3bd5f02012-03-08 21:05:27 -080030class Heap;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -070031class MarkIfReachesAllocspaceVisitor;
32class ModUnionClearCardVisitor;
33class ModUnionVisitor;
34class ModUnionTableBitmap;
Carl Shapiro69759ea2011-07-21 18:13:35 -070035class Object;
36
37class MarkSweep {
38 public:
Elliott Hughes74847412012-06-20 18:10:21 -070039 explicit MarkSweep(MarkStack* mark_stack);
Carl Shapiro58551df2011-07-24 03:09:51 -070040
Carl Shapiro69759ea2011-07-21 18:13:35 -070041 ~MarkSweep();
42
Carl Shapiro58551df2011-07-24 03:09:51 -070043 // Initializes internal structures.
Jesse Wilson078f9b02011-11-18 17:51:47 -050044 void Init();
Carl Shapiro58551df2011-07-24 03:09:51 -070045
Carl Shapiro69759ea2011-07-21 18:13:35 -070046 // Marks the root set at the start of a garbage collection.
47 void MarkRoots();
48
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070049 // Marks the roots in the image space on dirty cards.
Ian Rogers5d76c432011-10-31 21:42:49 -070050 void ScanDirtyImageRoots();
51
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070052 // Verify that image roots point to only marked objects within the alloc space.
53 void VerifyImageRoots();
54
Ian Rogers5d76c432011-10-31 21:42:49 -070055 bool IsMarkStackEmpty() const {
56 return mark_stack_->IsEmpty();
57 }
58
Carl Shapiro58551df2011-07-24 03:09:51 -070059 // Builds a mark stack and recursively mark until it empties.
Mathieu Chartiercc236d72012-07-20 10:29:05 -070060 void RecursiveMark(bool partial);
61
62 // Copies mark bits from live bitmap of zygote space to mark bitmap for partial GCs.
63 void CopyMarkBits();
Carl Shapiro58551df2011-07-24 03:09:51 -070064
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070065 // Builds a mark stack with objects on dirty cards and recursively mark
66 // until it empties.
67 void RecursiveMarkDirtyObjects();
68
Carl Shapiro69759ea2011-07-21 18:13:35 -070069 // Remarks the root set after completing the concurrent mark.
70 void ReMarkRoots();
71
Mathieu Chartiercc236d72012-07-20 10:29:05 -070072 Heap* GetHeap() {
73 return heap_;
74 }
75
Carl Shapiro58551df2011-07-24 03:09:51 -070076 void ProcessReferences(bool clear_soft_references) {
77 ProcessReferences(&soft_reference_list_, clear_soft_references,
78 &weak_reference_list_,
79 &finalizer_reference_list_,
80 &phantom_reference_list_);
81 }
82
Carl Shapiro69759ea2011-07-21 18:13:35 -070083 // Sweeps unmarked objects to complete the garbage collection.
Mathieu Chartiercc236d72012-07-20 10:29:05 -070084 void Sweep(bool partial);
Carl Shapiro69759ea2011-07-21 18:13:35 -070085
Elliott Hughesadb460d2011-10-05 17:02:34 -070086 Object* GetClearedReferences() {
87 return cleared_reference_list_;
88 }
89
Mathieu Chartiercc236d72012-07-20 10:29:05 -070090 // Blackens an object.
91 void ScanObject(const Object* obj);
92
Carl Shapiro69759ea2011-07-21 18:13:35 -070093 private:
94 // Returns true if the object has its bit set in the mark bitmap.
95 bool IsMarked(const Object* object) const {
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070096 if (current_mark_bitmap_->HasAddress(object)) {
97 return current_mark_bitmap_->Test(object);
98 }
99 return heap_->GetMarkBitmap()->Test(object);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700100 }
101
Mathieu Chartier46a23632012-08-07 18:44:40 -0700102 static bool IsMarkedCallback(const Object* object, void* arg) {
Elliott Hughesc33a32b2011-10-11 18:18:07 -0700103 return reinterpret_cast<MarkSweep*>(arg)->IsMarked(object);
104 }
105
Mathieu Chartier46a23632012-08-07 18:44:40 -0700106 static bool IsLiveCallback(const Object* object, void* arg) {
107 return reinterpret_cast<MarkSweep*>(arg)->GetHeap()->GetLiveBitmap()->Test(object);
108 }
109
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700110 static void MarkObjectVisitor(const Object* root, void* arg);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700111
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700112 static void ReMarkObjectVisitor(const Object* root, void* arg);
113
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700114 static void VerifyImageRootVisitor(Object* root, void* arg);
115
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700116 static void ScanDirtyCardCallback(Object* obj, void* arg);
117
Carl Shapiro69759ea2011-07-21 18:13:35 -0700118 // Marks an object.
119 void MarkObject(const Object* obj);
120
121 // Yuck.
122 void MarkObject0(const Object* obj, bool check_finger);
123
Carl Shapiro58551df2011-07-24 03:09:51 -0700124 static void ScanBitmapCallback(Object* obj, void* finger, void* arg);
125
Ian Rogers30fab402012-01-23 15:43:46 -0800126 static void SweepCallback(size_t num_ptrs, Object** ptrs, void* arg);
Carl Shapiro58551df2011-07-24 03:09:51 -0700127
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700128 // Special sweep for zygote that just marks objects / dirties cards.
129 static void ZygoteSweepCallback(size_t num_ptrs, Object** ptrs, void* arg);
Ian Rogers5d76c432011-10-31 21:42:49 -0700130
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700131 void CheckReference(const Object* obj, const Object* ref, MemberOffset offset, bool is_static);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700132
Ian Rogers5d76c432011-10-31 21:42:49 -0700133 void CheckObject(const Object* obj);
134
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700135 template <typename Visitor>
136 void VisitObjectReferences(const Object* obj, const Visitor& visitor) {
137 DCHECK(obj != NULL);
138 DCHECK(obj->GetClass() != NULL);
139 if (obj->IsClass()) {
140 VisitClassReferences(obj, visitor);
141 } else if (obj->IsArrayInstance()) {
142 VisitArrayReferences(obj, visitor);
143 } else {
144 VisitOtherReferences(obj, visitor);
145 }
146 }
147
Carl Shapiro69759ea2011-07-21 18:13:35 -0700148 // Grays references in instance fields.
149 void ScanInstanceFields(const Object* obj);
150
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700151 template <typename Visitor>
152 void VisitInstanceFieldsReferences(const Object* obj, const Visitor& visitor) {
153 DCHECK(obj != NULL);
154 Class* klass = obj->GetClass();
155 DCHECK(klass != NULL);
156 VisitFieldsReferences(obj, klass->GetReferenceInstanceOffsets(), false, visitor);
157 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700158
Carl Shapiro69759ea2011-07-21 18:13:35 -0700159 // Blackens a class object.
160 void ScanClass(const Object* obj);
161
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700162 template <typename Visitor>
163 void VisitClassReferences(const Object* obj, const Visitor& visitor) {
164 VisitInstanceFieldsReferences(obj, visitor);
165 VisitStaticFieldsReferences(obj->AsClass(), visitor);
166 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700167
Carl Shapiro69759ea2011-07-21 18:13:35 -0700168 // Grays references in static fields.
169 void ScanStaticFields(const Class* klass);
170
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700171 template <typename Visitor>
172 void VisitStaticFieldsReferences(const Class* klass, const Visitor& visitor) {
173 DCHECK(klass != NULL);
174 VisitFieldsReferences(klass, klass->GetReferenceStaticOffsets(), true, visitor);
175 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700176
Brian Carlstrom4873d462011-08-21 15:23:39 -0700177 // Used by ScanInstanceFields and ScanStaticFields
178 void ScanFields(const Object* obj, uint32_t ref_offsets, bool is_static);
179
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700180 template <typename Visitor>
181 void VisitFieldsReferences(const Object* obj, uint32_t ref_offsets, bool is_static, const Visitor& visitor) {
182 if (ref_offsets != CLASS_WALK_SUPER) {
183 // Found a reference offset bitmap. Mark the specified offsets.
184 while (ref_offsets != 0) {
185 size_t right_shift = CLZ(ref_offsets);
186 MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
187 const Object* ref = obj->GetFieldObject<const Object*>(field_offset, false);
188 visitor(obj, ref, field_offset, is_static);
189 ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
190 }
191 } else {
192 // There is no reference offset bitmap. In the non-static case,
193 // walk up the class inheritance hierarchy and find reference
194 // offsets the hard way. In the static case, just consider this
195 // class.
196 for (const Class* klass = is_static ? obj->AsClass() : obj->GetClass();
197 klass != NULL;
198 klass = is_static ? NULL : klass->GetSuperClass()) {
199 size_t num_reference_fields = (is_static
200 ? klass->NumReferenceStaticFields()
201 : klass->NumReferenceInstanceFields());
202 for (size_t i = 0; i < num_reference_fields; ++i) {
203 Field* field = (is_static
204 ? klass->GetStaticField(i)
205 : klass->GetInstanceField(i));
206 MemberOffset field_offset = field->GetOffset();
207 const Object* ref = obj->GetFieldObject<const Object*>(field_offset, false);
208 visitor(obj, ref, field_offset, is_static);
209 }
210 }
211 }
212 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700213
Carl Shapiro69759ea2011-07-21 18:13:35 -0700214 // Grays references in an array.
215 void ScanArray(const Object* obj);
216
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700217 template <typename Visitor>
218 void VisitArrayReferences(const Object* obj, const Visitor& visitor) {
219 visitor(obj, obj->GetClass(), Object::ClassOffset(), false);
220 if (obj->IsObjectArray()) {
221 const ObjectArray<Object>* array = obj->AsObjectArray<Object>();
222 for (int32_t i = 0; i < array->GetLength(); ++i) {
223 const Object* element = array->GetWithoutChecks(i);
224 size_t width = sizeof(Object*);
225 visitor(obj, element, MemberOffset(i * width + Array::DataOffset(width).Int32Value()), false);
226 }
227 }
228 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700229
Carl Shapiro58551df2011-07-24 03:09:51 -0700230 void ScanOther(const Object* obj);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700231
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700232 template <typename Visitor>
233 void VisitOtherReferences(const Object* obj, const Visitor& visitor) {
234 return VisitInstanceFieldsReferences(obj, visitor);
235 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700236
Carl Shapiro69759ea2011-07-21 18:13:35 -0700237 // Blackens objects grayed during a garbage collection.
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700238 void ScanGrayObjects();
Carl Shapiro69759ea2011-07-21 18:13:35 -0700239
240 // Schedules an unmarked object for reference processing.
241 void DelayReferenceReferent(Object* reference);
242
243 // Recursively blackens objects on the mark stack.
244 void ProcessMarkStack();
245
Carl Shapiro69759ea2011-07-21 18:13:35 -0700246 void EnqueueFinalizerReferences(Object** ref);
247
248 void PreserveSomeSoftReferences(Object** ref);
249
Carl Shapiro69759ea2011-07-21 18:13:35 -0700250 void ClearWhiteReferences(Object** list);
251
Carl Shapiro58551df2011-07-24 03:09:51 -0700252 void ProcessReferences(Object** soft_references, bool clear_soft_references,
Carl Shapiro69759ea2011-07-21 18:13:35 -0700253 Object** weak_references,
254 Object** finalizer_references,
255 Object** phantom_references);
256
Mathieu Chartier46a23632012-08-07 18:44:40 -0700257 void SweepSystemWeaks(bool swap_bitmaps);
258 void SweepJniWeakGlobals(HeapBitmap* bitmap);
Carl Shapiro58551df2011-07-24 03:09:51 -0700259
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700260 // Current space, we check this space first to avoid searching for the appropriate space for an object.
261 SpaceBitmap* current_mark_bitmap_;
262
Carl Shapiro69759ea2011-07-21 18:13:35 -0700263 MarkStack* mark_stack_;
264
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800265 Heap* heap_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700266
267 Object* finger_;
268
269 Object* condemned_;
270
271 Object* soft_reference_list_;
272
273 Object* weak_reference_list_;
274
275 Object* finalizer_reference_list_;
276
277 Object* phantom_reference_list_;
278
279 Object* cleared_reference_list_;
280
Elliott Hughes352a4242011-10-31 15:15:21 -0700281 size_t class_count_;
282 size_t array_count_;
283 size_t other_count_;
284
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700285 friend class AddIfReachesAllocSpaceVisitor; // Used by mod-union table.
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700286 friend class CheckBitmapVisitor;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700287 friend class CheckObjectVisitor;
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700288 friend class CheckReferenceVisitor;
Elliott Hughes410c0c82011-09-01 17:58:25 -0700289 friend class InternTableEntryIsUnmarked;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700290 friend class MarkIfReachesAllocspaceVisitor;
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700291 friend class ModUnionCheckReferences;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700292 friend class ModUnionClearCardVisitor;
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700293 friend class ModUnionReferenceVisitor;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700294 friend class ModUnionVisitor;
295 friend class ModUnionTableBitmap;
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700296 friend class ModUnionTableReferenceCache;
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700297 friend class ModUnionScanImageRootVisitor;
298 friend class ScanBitmapVisitor;
299 friend class ScanImageRootVisitor;
Elliott Hughes410c0c82011-09-01 17:58:25 -0700300
Carl Shapiro69759ea2011-07-21 18:13:35 -0700301 DISALLOW_COPY_AND_ASSIGN(MarkSweep);
302};
303
304} // namespace art
305
306#endif // ART_SRC_MARK_SWEEP_H_