blob: 7ef681793e684743cc17dc8f1b499463bf22b9b9 [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;
Mathieu Chartier357e9be2012-08-01 11:00:14 -070036class TimingLogger;
Carl Shapiro69759ea2011-07-21 18:13:35 -070037
38class MarkSweep {
39 public:
Elliott Hughes74847412012-06-20 18:10:21 -070040 explicit MarkSweep(MarkStack* mark_stack);
Carl Shapiro58551df2011-07-24 03:09:51 -070041
Carl Shapiro69759ea2011-07-21 18:13:35 -070042 ~MarkSweep();
43
Carl Shapiro58551df2011-07-24 03:09:51 -070044 // Initializes internal structures.
Jesse Wilson078f9b02011-11-18 17:51:47 -050045 void Init();
Carl Shapiro58551df2011-07-24 03:09:51 -070046
Carl Shapiro69759ea2011-07-21 18:13:35 -070047 // Marks the root set at the start of a garbage collection.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070048 void MarkRoots()
Ian Rogersb726dcb2012-09-05 08:57:23 -070049 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
50 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -070051
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070052 // Verify that image roots point to only marked objects within the alloc space.
Ian Rogersb726dcb2012-09-05 08:57:23 -070053 void VerifyImageRoots() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070054
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 Chartier357e9be2012-08-01 11:00:14 -070060 void RecursiveMark(bool partial, TimingLogger& timings)
Ian Rogersb726dcb2012-09-05 08:57:23 -070061 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
62 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mathieu Chartiercc236d72012-07-20 10:29:05 -070063
Mathieu Chartier357e9be2012-08-01 11:00:14 -070064 // Copies mark bits from live bitmap of ZygoteSpace to mark bitmap for partial GCs.
Mathieu Chartier2fde5332012-09-14 14:51:54 -070065 void CopyMarkBits(ContinuousSpace* space);
Carl Shapiro58551df2011-07-24 03:09:51 -070066
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070067 // Builds a mark stack with objects on dirty cards and recursively mark
68 // until it empties.
Mathieu Chartier357e9be2012-08-01 11:00:14 -070069 void RecursiveMarkDirtyObjects(bool update_finger)
Ian Rogersb726dcb2012-09-05 08:57:23 -070070 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
71 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070072
Mathieu Chartier357e9be2012-08-01 11:00:14 -070073 // Recursive mark objects on specified cards. Updates finger.
74 void RecursiveMarkCards(CardTable* card_table, const std::vector<byte*>& cards,
75 TimingLogger& timings)
Ian Rogersb726dcb2012-09-05 08:57:23 -070076 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
77 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);;
Mathieu Chartier357e9be2012-08-01 11:00:14 -070078
Carl Shapiro69759ea2011-07-21 18:13:35 -070079 // Remarks the root set after completing the concurrent mark.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070080 void ReMarkRoots()
Ian Rogersb726dcb2012-09-05 08:57:23 -070081 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
82 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -070083
Mathieu Chartiercc236d72012-07-20 10:29:05 -070084 Heap* GetHeap() {
85 return heap_;
86 }
87
Ian Rogers00f7d0e2012-07-19 15:28:27 -070088 void ProcessReferences(bool clear_soft_references)
Ian Rogersb726dcb2012-09-05 08:57:23 -070089 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
90 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Carl Shapiro58551df2011-07-24 03:09:51 -070091 ProcessReferences(&soft_reference_list_, clear_soft_references,
92 &weak_reference_list_,
93 &finalizer_reference_list_,
94 &phantom_reference_list_);
95 }
96
Carl Shapiro69759ea2011-07-21 18:13:35 -070097 // Sweeps unmarked objects to complete the garbage collection.
Mathieu Chartier357e9be2012-08-01 11:00:14 -070098 void Sweep(bool partial, bool swap_bitmaps)
Ian Rogersb726dcb2012-09-05 08:57:23 -070099 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700100
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -0700101 // Sweeps unmarked objects to complete the garbage collection.
102 void SweepLargeObjects(bool swap_bitmaps)
103 EXCLUSIVE_LOCKS_REQUIRED(GlobalSynchronization::heap_bitmap_lock_);
104
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700105 // Sweep only pointers within an array. WARNING: Trashes objects.
106 void SweepArray(TimingLogger& logger, MarkStack* allocation_stack_, bool swap_bitmaps)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700107 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700108
Elliott Hughesadb460d2011-10-05 17:02:34 -0700109 Object* GetClearedReferences() {
110 return cleared_reference_list_;
111 }
112
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700113 // Proxy for external access to ScanObject.
114 void ScanRoot(const Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700115 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
116 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700117
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700118 // Blackens an object.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700119 void ScanObject(const Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700120 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
121 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700122
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700123 void SetFinger(Object* new_finger) {
124 finger_ = new_finger;
125 }
126
127 void DisableFinger() {
128 SetFinger(reinterpret_cast<Object*>(~static_cast<uintptr_t>(0)));
129 }
130
131 size_t GetFreedBytes() const {
132 return freed_bytes_;
133 }
134
135 size_t GetFreedObjects() const {
136 return freed_objects_;
137 }
138
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -0700139 // Everything inside the immune range is marked.
140 void SetImmuneRange(Object* begin, Object* end) {
141 immune_begin_ = begin;
142 immune_end_ = end;
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700143 }
144
145 void SweepSystemWeaks(bool swap_bitmaps)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700146 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700147
Mathieu Chartierc7b83a02012-09-11 18:07:39 -0700148 static bool VerifyIsLiveCallback(const Object* obj, void* arg)
149 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
150
151 void VerifySystemWeaks()
152 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
153
154 // Verify that an object is live, either in a live bitmap or in the allocation stack.
155 void VerifyIsLive(const Object* obj)
156 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
157
Mathieu Chartierfd678be2012-08-30 14:50:54 -0700158 template <typename Visitor>
159 static void VisitObjectReferences(const Object* obj, const Visitor& visitor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700160 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_,
161 Locks::mutator_lock_) {
Mathieu Chartierfd678be2012-08-30 14:50:54 -0700162 DCHECK(obj != NULL);
163 DCHECK(obj->GetClass() != NULL);
164 if (obj->IsClass()) {
165 VisitClassReferences(obj, visitor);
166 } else if (obj->IsArrayInstance()) {
167 VisitArrayReferences(obj, visitor);
168 } else {
169 VisitOtherReferences(obj, visitor);
170 }
171 }
172
Carl Shapiro69759ea2011-07-21 18:13:35 -0700173 private:
174 // Returns true if the object has its bit set in the mark bitmap.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700175 bool IsMarked(const Object* object) const
Ian Rogersb726dcb2012-09-05 08:57:23 -0700176 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700177 DCHECK(current_mark_bitmap_ != NULL);
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700178 if (current_mark_bitmap_->HasAddress(object)) {
179 return current_mark_bitmap_->Test(object);
180 }
181 return heap_->GetMarkBitmap()->Test(object);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700182 }
183
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700184 static bool IsMarkedCallback(const Object* object, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700185 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Elliott Hughesc33a32b2011-10-11 18:18:07 -0700186
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700187 static bool IsLiveCallback(const Object* object, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700188 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Mathieu Chartier46a23632012-08-07 18:44:40 -0700189
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700190 static void MarkObjectVisitor(const Object* root, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700191 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700192
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700193 static void ReMarkObjectVisitor(const Object* root, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700194 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700195
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700196 static void VerifyImageRootVisitor(Object* root, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700197 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_,
198 Locks::mutator_lock_);
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700199
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700200 static void ScanDirtyCardCallback(Object* obj, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700201 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
202 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700203
Carl Shapiro69759ea2011-07-21 18:13:35 -0700204 // Marks an object.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700205 void MarkObject(const Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700206 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700207
208 // Yuck.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700209 void MarkObject0(const Object* obj, bool check_finger)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700210 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700211
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700212 static void ScanBitmapCallback(Object* obj, void* finger, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700213 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
214 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro58551df2011-07-24 03:09:51 -0700215
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700216 static void SweepCallback(size_t num_ptrs, Object** ptrs, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700217 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Carl Shapiro58551df2011-07-24 03:09:51 -0700218
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700219 // Special sweep for zygote that just marks objects / dirties cards.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700220 static void ZygoteSweepCallback(size_t num_ptrs, Object** ptrs, void* arg)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700221 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Ian Rogers5d76c432011-10-31 21:42:49 -0700222
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700223 void CheckReference(const Object* obj, const Object* ref, MemberOffset offset, bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700224 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700225
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700226 void CheckObject(const Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700227 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
Ian Rogers5d76c432011-10-31 21:42:49 -0700228
Carl Shapiro69759ea2011-07-21 18:13:35 -0700229 // Grays references in instance fields.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700230 void ScanInstanceFields(const Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700231 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
232 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700233
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700234 template <typename Visitor>
Mathieu Chartierfd678be2012-08-30 14:50:54 -0700235 static void VisitInstanceFieldsReferences(const Object* obj, const Visitor& visitor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700236 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700237 DCHECK(obj != NULL);
238 Class* klass = obj->GetClass();
239 DCHECK(klass != NULL);
240 VisitFieldsReferences(obj, klass->GetReferenceInstanceOffsets(), false, visitor);
241 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700242
Carl Shapiro69759ea2011-07-21 18:13:35 -0700243 // Blackens a class object.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700244 void ScanClass(const Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700245 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
246 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700247
Carl Shapiro69759ea2011-07-21 18:13:35 -0700248
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700249 template <typename Visitor>
Mathieu Chartierfd678be2012-08-30 14:50:54 -0700250 static void VisitClassReferences(const Object* obj, const Visitor& visitor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700251 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700252 VisitInstanceFieldsReferences(obj, visitor);
253 VisitStaticFieldsReferences(obj->AsClass(), visitor);
254 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700255
Carl Shapiro69759ea2011-07-21 18:13:35 -0700256 // Grays references in static fields.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700257 void ScanStaticFields(const Class* klass)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700258 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
259 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700260
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700261 template <typename Visitor>
Mathieu Chartierfd678be2012-08-30 14:50:54 -0700262 static void VisitStaticFieldsReferences(const Class* klass, const Visitor& visitor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700263 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700264 DCHECK(klass != NULL);
265 VisitFieldsReferences(klass, klass->GetReferenceStaticOffsets(), true, visitor);
266 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700267
Brian Carlstrom4873d462011-08-21 15:23:39 -0700268 // Used by ScanInstanceFields and ScanStaticFields
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700269 void ScanFields(const Object* obj, uint32_t ref_offsets, bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700270 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
271 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Brian Carlstrom4873d462011-08-21 15:23:39 -0700272
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700273 template <typename Visitor>
Mathieu Chartierfd678be2012-08-30 14:50:54 -0700274 static void VisitFieldsReferences(const Object* obj, uint32_t ref_offsets, bool is_static,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700275 const Visitor& visitor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700276 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_,
277 Locks::mutator_lock_) {
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700278 if (ref_offsets != CLASS_WALK_SUPER) {
279 // Found a reference offset bitmap. Mark the specified offsets.
280 while (ref_offsets != 0) {
281 size_t right_shift = CLZ(ref_offsets);
282 MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
283 const Object* ref = obj->GetFieldObject<const Object*>(field_offset, false);
284 visitor(obj, ref, field_offset, is_static);
285 ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
286 }
287 } else {
288 // There is no reference offset bitmap. In the non-static case,
289 // walk up the class inheritance hierarchy and find reference
290 // offsets the hard way. In the static case, just consider this
291 // class.
292 for (const Class* klass = is_static ? obj->AsClass() : obj->GetClass();
293 klass != NULL;
294 klass = is_static ? NULL : klass->GetSuperClass()) {
295 size_t num_reference_fields = (is_static
296 ? klass->NumReferenceStaticFields()
297 : klass->NumReferenceInstanceFields());
298 for (size_t i = 0; i < num_reference_fields; ++i) {
299 Field* field = (is_static
300 ? klass->GetStaticField(i)
301 : klass->GetInstanceField(i));
302 MemberOffset field_offset = field->GetOffset();
303 const Object* ref = obj->GetFieldObject<const Object*>(field_offset, false);
304 visitor(obj, ref, field_offset, is_static);
305 }
306 }
307 }
308 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700309
Carl Shapiro69759ea2011-07-21 18:13:35 -0700310 // Grays references in an array.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700311 void ScanArray(const Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700312 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
313 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700314
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700315 template <typename Visitor>
Mathieu Chartierfd678be2012-08-30 14:50:54 -0700316 static void VisitArrayReferences(const Object* obj, const Visitor& visitor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700317 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700318 visitor(obj, obj->GetClass(), Object::ClassOffset(), false);
319 if (obj->IsObjectArray()) {
320 const ObjectArray<Object>* array = obj->AsObjectArray<Object>();
321 for (int32_t i = 0; i < array->GetLength(); ++i) {
322 const Object* element = array->GetWithoutChecks(i);
323 size_t width = sizeof(Object*);
324 visitor(obj, element, MemberOffset(i * width + Array::DataOffset(width).Int32Value()), false);
325 }
326 }
327 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700328
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700329 void ScanOther(const Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700330 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
331 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700332
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700333 template <typename Visitor>
Mathieu Chartierfd678be2012-08-30 14:50:54 -0700334 static void VisitOtherReferences(const Object* obj, const Visitor& visitor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700335 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700336 return VisitInstanceFieldsReferences(obj, visitor);
337 }
Ian Rogers5d76c432011-10-31 21:42:49 -0700338
Carl Shapiro69759ea2011-07-21 18:13:35 -0700339 // Blackens objects grayed during a garbage collection.
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700340 void ScanGrayObjects(bool update_finger)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700341 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700342
343 // Schedules an unmarked object for reference processing.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700344 void DelayReferenceReferent(Object* reference)
Ian Rogers23435d02012-09-24 11:23:12 -0700345 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700346
347 // Recursively blackens objects on the mark stack.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700348 void ProcessMarkStack()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700349 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
350 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700351
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700352 void EnqueueFinalizerReferences(Object** ref)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700353 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
354 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700355
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700356 void PreserveSomeSoftReferences(Object** ref)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700357 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
358 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700359
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700360 void ClearWhiteReferences(Object** list)
Ian Rogers23435d02012-09-24 11:23:12 -0700361 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700362
Carl Shapiro58551df2011-07-24 03:09:51 -0700363 void ProcessReferences(Object** soft_references, bool clear_soft_references,
Carl Shapiro69759ea2011-07-21 18:13:35 -0700364 Object** weak_references,
365 Object** finalizer_references,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700366 Object** phantom_references)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700367 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
368 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700369
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700370 void SweepJniWeakGlobals(bool swap_bitmaps)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700371 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
Carl Shapiro58551df2011-07-24 03:09:51 -0700372
Mathieu Chartierb062fdd2012-07-03 09:51:48 -0700373 // Current space, we check this space first to avoid searching for the appropriate space for an object.
374 SpaceBitmap* current_mark_bitmap_;
375
Carl Shapiro69759ea2011-07-21 18:13:35 -0700376 MarkStack* mark_stack_;
377
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800378 Heap* heap_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700379
380 Object* finger_;
381
Mathieu Chartiere0f0cb32012-08-28 11:26:00 -0700382 // Immune range, every object inside the immune range is assumed to be marked.
383 Object* immune_begin_;
384 Object* immune_end_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700385
386 Object* soft_reference_list_;
387
388 Object* weak_reference_list_;
389
390 Object* finalizer_reference_list_;
391
392 Object* phantom_reference_list_;
393
394 Object* cleared_reference_list_;
395
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700396 size_t freed_bytes_;
397 size_t freed_objects_;
398
Elliott Hughes352a4242011-10-31 15:15:21 -0700399 size_t class_count_;
400 size_t array_count_;
401 size_t other_count_;
402
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700403 friend class AddIfReachesAllocSpaceVisitor; // Used by mod-union table.
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700404 friend class CheckBitmapVisitor;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700405 friend class CheckObjectVisitor;
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700406 friend class CheckReferenceVisitor;
Elliott Hughes410c0c82011-09-01 17:58:25 -0700407 friend class InternTableEntryIsUnmarked;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700408 friend class MarkIfReachesAllocspaceVisitor;
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700409 friend class ModUnionCheckReferences;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700410 friend class ModUnionClearCardVisitor;
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700411 friend class ModUnionReferenceVisitor;
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700412 friend class ModUnionVisitor;
413 friend class ModUnionTableBitmap;
Mathieu Chartiere6e06512012-06-26 15:00:26 -0700414 friend class ModUnionTableReferenceCache;
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700415 friend class ModUnionScanImageRootVisitor;
416 friend class ScanBitmapVisitor;
417 friend class ScanImageRootVisitor;
Elliott Hughes410c0c82011-09-01 17:58:25 -0700418
Carl Shapiro69759ea2011-07-21 18:13:35 -0700419 DISALLOW_COPY_AND_ASSIGN(MarkSweep);
420};
421
422} // namespace art
423
424#endif // ART_SRC_MARK_SWEEP_H_