blob: 5f275a462439f4662e49b2ac0a51617549cd5db6 [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.
60 void RecursiveMark();
61
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070062 // Builds a mark stack with objects on dirty cards and recursively mark
63 // until it empties.
64 void RecursiveMarkDirtyObjects();
65
Carl Shapiro69759ea2011-07-21 18:13:35 -070066 // Remarks the root set after completing the concurrent mark.
67 void ReMarkRoots();
68
Carl Shapiro58551df2011-07-24 03:09:51 -070069 void ProcessReferences(bool clear_soft_references) {
70 ProcessReferences(&soft_reference_list_, clear_soft_references,
71 &weak_reference_list_,
72 &finalizer_reference_list_,
73 &phantom_reference_list_);
74 }
75
Carl Shapiro69759ea2011-07-21 18:13:35 -070076 // Sweeps unmarked objects to complete the garbage collection.
77 void Sweep();
78
Elliott Hughesadb460d2011-10-05 17:02:34 -070079 Object* GetClearedReferences() {
80 return cleared_reference_list_;
81 }
82
Carl Shapiro69759ea2011-07-21 18:13:35 -070083 private:
84 // Returns true if the object has its bit set in the mark bitmap.
85 bool IsMarked(const Object* object) const {
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070086 if (current_mark_bitmap_->HasAddress(object)) {
87 return current_mark_bitmap_->Test(object);
88 }
89 return heap_->GetMarkBitmap()->Test(object);
Carl Shapiro69759ea2011-07-21 18:13:35 -070090 }
91
Elliott Hughesc33a32b2011-10-11 18:18:07 -070092 static bool IsMarked(const Object* object, void* arg) {
93 return reinterpret_cast<MarkSweep*>(arg)->IsMarked(object);
94 }
95
Elliott Hughescf4c6c42011-09-01 15:16:42 -070096 static void MarkObjectVisitor(const Object* root, void* arg);
Brian Carlstrom1f870082011-08-23 16:02:11 -070097
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070098 static void ReMarkObjectVisitor(const Object* root, void* arg);
99
Ian Rogers5d76c432011-10-31 21:42:49 -0700100 static void ScanImageRootVisitor(Object* root, void* arg);
101
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700102 static void VerifyImageRootVisitor(Object* root, void* arg);
103
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700104 static void ScanDirtyCardCallback(Object* obj, void* arg);
105
Carl Shapiro69759ea2011-07-21 18:13:35 -0700106 // Marks an object.
107 void MarkObject(const Object* obj);
108
109 // Yuck.
110 void MarkObject0(const Object* obj, bool check_finger);
111
Carl Shapiro58551df2011-07-24 03:09:51 -0700112 static void ScanBitmapCallback(Object* obj, void* finger, void* arg);
113
Ian Rogers5d76c432011-10-31 21:42:49 -0700114 static void CheckBitmapCallback(Object* obj, void* finger, void* arg);
115
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700116 static void CheckBitmapNoFingerCallback(Object* obj, void* arg);
117
Ian Rogers30fab402012-01-23 15:43:46 -0800118 static void SweepCallback(size_t num_ptrs, Object** ptrs, void* arg);
Carl Shapiro58551df2011-07-24 03:09:51 -0700119
Ian Rogers5d76c432011-10-31 21:42:49 -0700120 void CheckReference(const Object* obj, const Object* ref, MemberOffset offset, bool is_static);
121
Carl Shapiro69759ea2011-07-21 18:13:35 -0700122 // Blackens an object.
123 void ScanObject(const Object* obj);
124
Ian Rogers5d76c432011-10-31 21:42:49 -0700125 void CheckObject(const Object* obj);
126
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700127 template <typename Visitor>
128 void VisitObjectReferences(const Object* obj, const Visitor& visitor) {
129 DCHECK(obj != NULL);
130 DCHECK(obj->GetClass() != NULL);
131 if (obj->IsClass()) {
132 VisitClassReferences(obj, visitor);
133 } else if (obj->IsArrayInstance()) {
134 VisitArrayReferences(obj, visitor);
135 } else {
136 VisitOtherReferences(obj, visitor);
137 }
138 }
139
Carl Shapiro69759ea2011-07-21 18:13:35 -0700140 // Grays references in instance fields.
141 void ScanInstanceFields(const Object* obj);
142
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700143 template <typename Visitor>
144 void VisitInstanceFieldsReferences(const Object* obj, const Visitor& visitor) {
145 DCHECK(obj != NULL);
146 Class* klass = obj->GetClass();
147 DCHECK(klass != NULL);
148 VisitFieldsReferences(obj, klass->GetReferenceInstanceOffsets(), false, visitor);
149 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700150
Carl Shapiro69759ea2011-07-21 18:13:35 -0700151 // Blackens a class object.
152 void ScanClass(const Object* obj);
153
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700154 template <typename Visitor>
155 void VisitClassReferences(const Object* obj, const Visitor& visitor) {
156 VisitInstanceFieldsReferences(obj, visitor);
157 VisitStaticFieldsReferences(obj->AsClass(), visitor);
158 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700159
Carl Shapiro69759ea2011-07-21 18:13:35 -0700160 // Grays references in static fields.
161 void ScanStaticFields(const Class* klass);
162
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700163 template <typename Visitor>
164 void VisitStaticFieldsReferences(const Class* klass, const Visitor& visitor) {
165 DCHECK(klass != NULL);
166 VisitFieldsReferences(klass, klass->GetReferenceStaticOffsets(), true, visitor);
167 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700168
Brian Carlstrom4873d462011-08-21 15:23:39 -0700169 // Used by ScanInstanceFields and ScanStaticFields
170 void ScanFields(const Object* obj, uint32_t ref_offsets, bool is_static);
171
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700172 template <typename Visitor>
173 void VisitFieldsReferences(const Object* obj, uint32_t ref_offsets, bool is_static, const Visitor& visitor) {
174 if (ref_offsets != CLASS_WALK_SUPER) {
175 // Found a reference offset bitmap. Mark the specified offsets.
176 while (ref_offsets != 0) {
177 size_t right_shift = CLZ(ref_offsets);
178 MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
179 const Object* ref = obj->GetFieldObject<const Object*>(field_offset, false);
180 visitor(obj, ref, field_offset, is_static);
181 ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
182 }
183 } else {
184 // There is no reference offset bitmap. In the non-static case,
185 // walk up the class inheritance hierarchy and find reference
186 // offsets the hard way. In the static case, just consider this
187 // class.
188 for (const Class* klass = is_static ? obj->AsClass() : obj->GetClass();
189 klass != NULL;
190 klass = is_static ? NULL : klass->GetSuperClass()) {
191 size_t num_reference_fields = (is_static
192 ? klass->NumReferenceStaticFields()
193 : klass->NumReferenceInstanceFields());
194 for (size_t i = 0; i < num_reference_fields; ++i) {
195 Field* field = (is_static
196 ? klass->GetStaticField(i)
197 : klass->GetInstanceField(i));
198 MemberOffset field_offset = field->GetOffset();
199 const Object* ref = obj->GetFieldObject<const Object*>(field_offset, false);
200 visitor(obj, ref, field_offset, is_static);
201 }
202 }
203 }
204 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700205
Carl Shapiro69759ea2011-07-21 18:13:35 -0700206 // Grays references in an array.
207 void ScanArray(const Object* obj);
208
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700209 template <typename Visitor>
210 void VisitArrayReferences(const Object* obj, const Visitor& visitor) {
211 visitor(obj, obj->GetClass(), Object::ClassOffset(), false);
212 if (obj->IsObjectArray()) {
213 const ObjectArray<Object>* array = obj->AsObjectArray<Object>();
214 for (int32_t i = 0; i < array->GetLength(); ++i) {
215 const Object* element = array->GetWithoutChecks(i);
216 size_t width = sizeof(Object*);
217 visitor(obj, element, MemberOffset(i * width + Array::DataOffset(width).Int32Value()), false);
218 }
219 }
220 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700221
Carl Shapiro58551df2011-07-24 03:09:51 -0700222 void ScanOther(const Object* obj);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700223
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700224 template <typename Visitor>
225 void VisitOtherReferences(const Object* obj, const Visitor& visitor) {
226 return VisitInstanceFieldsReferences(obj, visitor);
227 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700228
Carl Shapiro69759ea2011-07-21 18:13:35 -0700229 // Blackens objects grayed during a garbage collection.
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700230 void ScanGrayObjects();
Carl Shapiro69759ea2011-07-21 18:13:35 -0700231
232 // Schedules an unmarked object for reference processing.
233 void DelayReferenceReferent(Object* reference);
234
235 // Recursively blackens objects on the mark stack.
236 void ProcessMarkStack();
237
Carl Shapiro69759ea2011-07-21 18:13:35 -0700238 void EnqueueFinalizerReferences(Object** ref);
239
240 void PreserveSomeSoftReferences(Object** ref);
241
Carl Shapiro69759ea2011-07-21 18:13:35 -0700242 void ClearWhiteReferences(Object** list);
243
Carl Shapiro58551df2011-07-24 03:09:51 -0700244 void ProcessReferences(Object** soft_references, bool clear_soft_references,
Carl Shapiro69759ea2011-07-21 18:13:35 -0700245 Object** weak_references,
246 Object** finalizer_references,
247 Object** phantom_references);
248
Carl Shapiro58551df2011-07-24 03:09:51 -0700249 void SweepSystemWeaks();
Elliott Hughes410c0c82011-09-01 17:58:25 -0700250 void SweepJniWeakGlobals();
Carl Shapiro58551df2011-07-24 03:09:51 -0700251
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700252 // Current space, we check this space first to avoid searching for the appropriate space for an object.
253 SpaceBitmap* current_mark_bitmap_;
254
Carl Shapiro69759ea2011-07-21 18:13:35 -0700255 MarkStack* mark_stack_;
256
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800257 Heap* heap_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700258
259 Object* finger_;
260
261 Object* condemned_;
262
263 Object* soft_reference_list_;
264
265 Object* weak_reference_list_;
266
267 Object* finalizer_reference_list_;
268
269 Object* phantom_reference_list_;
270
271 Object* cleared_reference_list_;
272
Elliott Hughes352a4242011-10-31 15:15:21 -0700273 size_t class_count_;
274 size_t array_count_;
275 size_t other_count_;
276
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700277 friend class AddIfReachesAllocSpaceVisitor; // Used by mod-union table.
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700278 friend class CheckObjectVisitor;
Elliott Hughes410c0c82011-09-01 17:58:25 -0700279 friend class InternTableEntryIsUnmarked;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700280 friend class MarkIfReachesAllocspaceVisitor;
281 friend class ModUnionClearCardVisitor;
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700282 friend class ModUnionReferenceVisitor;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700283 friend class ModUnionVisitor;
284 friend class ModUnionTableBitmap;
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700285 friend class ModUnionTableReferenceCache;
Elliott Hughes410c0c82011-09-01 17:58:25 -0700286
Carl Shapiro69759ea2011-07-21 18:13:35 -0700287 DISALLOW_COPY_AND_ASSIGN(MarkSweep);
288};
289
290} // namespace art
291
292#endif // ART_SRC_MARK_SWEEP_H_