blob: 270c9efde97cd013045c025cf44be7f721e948f7 [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -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 */
16
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_GC_COLLECTOR_MARK_SWEEP_INL_H_
18#define ART_RUNTIME_GC_COLLECTOR_MARK_SWEEP_INL_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
Ian Rogers1d54e732013-05-02 21:10:01 -070020#include "gc/collector/mark_sweep.h"
21
22#include "gc/heap.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070023#include "mirror/art_field.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080024#include "mirror/class.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080025#include "mirror/object_array.h"
26
27namespace art {
Ian Rogers1d54e732013-05-02 21:10:01 -070028namespace gc {
29namespace collector {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080030
31template <typename MarkVisitor>
Mathieu Chartier11409ae2013-09-23 11:49:36 -070032inline void MarkSweep::ScanObjectVisit(mirror::Object* obj, const MarkVisitor& visitor) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080033 DCHECK(obj != NULL);
34 if (kIsDebugBuild && !IsMarked(obj)) {
35 heap_->DumpSpaces();
36 LOG(FATAL) << "Scanning unmarked object " << obj;
37 }
38 mirror::Class* klass = obj->GetClass();
39 DCHECK(klass != NULL);
Mathieu Chartier94c32c52013-08-09 11:14:04 -070040 if (UNLIKELY(klass->IsArrayClass())) {
41 if (kCountScannedTypes) {
42 ++array_count_;
43 }
44 if (klass->IsObjectArrayClass()) {
45 VisitObjectArrayReferences(obj->AsObjectArray<mirror::Object>(), visitor);
46 }
47 } else if (UNLIKELY(klass == java_lang_Class_)) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080048 DCHECK_EQ(klass->GetClass(), java_lang_Class_);
49 if (kCountScannedTypes) {
50 ++class_count_;
51 }
52 VisitClassReferences(klass, obj, visitor);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080053 } else {
54 if (kCountScannedTypes) {
55 ++other_count_;
56 }
57 VisitOtherReferences(klass, obj, visitor);
58 if (UNLIKELY(klass->IsReferenceClass())) {
Mathieu Chartier94c32c52013-08-09 11:14:04 -070059 DelayReferenceReferent(klass, const_cast<mirror::Object*>(obj));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080060 }
61 }
62}
63
64template <typename Visitor>
Mathieu Chartier11409ae2013-09-23 11:49:36 -070065inline void MarkSweep::VisitObjectReferences(mirror::Object* obj, const Visitor& visitor,
66 bool visit_class)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080067 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_,
68 Locks::mutator_lock_) {
69 DCHECK(obj != NULL);
70 DCHECK(obj->GetClass() != NULL);
71
72 mirror::Class* klass = obj->GetClass();
73 DCHECK(klass != NULL);
Mathieu Chartier11409ae2013-09-23 11:49:36 -070074 if (visit_class) {
75 visitor(obj, klass, MemberOffset(0), false);
76 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080077 if (klass == mirror::Class::GetJavaLangClass()) {
78 DCHECK_EQ(klass->GetClass(), mirror::Class::GetJavaLangClass());
79 VisitClassReferences(klass, obj, visitor);
80 } else {
81 if (klass->IsArrayClass()) {
82 visitor(obj, klass, mirror::Object::ClassOffset(), false);
83 if (klass->IsObjectArrayClass()) {
84 VisitObjectArrayReferences(obj->AsObjectArray<mirror::Object>(), visitor);
85 }
86 } else {
87 VisitOtherReferences(klass, obj, visitor);
88 }
89 }
90}
91
92template <typename Visitor>
Mathieu Chartier11409ae2013-09-23 11:49:36 -070093inline void MarkSweep::VisitInstanceFieldsReferences(mirror::Class* klass,
94 mirror::Object* obj,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080095 const Visitor& visitor)
96 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
97 DCHECK(obj != NULL);
98 DCHECK(klass != NULL);
99 VisitFieldsReferences(obj, klass->GetReferenceInstanceOffsets(), false, visitor);
100}
101
102template <typename Visitor>
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700103inline void MarkSweep::VisitClassReferences(mirror::Class* klass, mirror::Object* obj,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800104 const Visitor& visitor)
105 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
106 VisitInstanceFieldsReferences(klass, obj, visitor);
107 VisitStaticFieldsReferences(obj->AsClass(), visitor);
108}
109
110template <typename Visitor>
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700111inline void MarkSweep::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800112 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
113 DCHECK(klass != NULL);
114 VisitFieldsReferences(klass, klass->GetReferenceStaticOffsets(), true, visitor);
115}
116
117template <typename Visitor>
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700118inline void MarkSweep::VisitFieldsReferences(mirror::Object* obj, uint32_t ref_offsets,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800119 bool is_static, const Visitor& visitor) {
120 if (LIKELY(ref_offsets != CLASS_WALK_SUPER)) {
121 // Found a reference offset bitmap. Mark the specified offsets.
Mathieu Chartier94c32c52013-08-09 11:14:04 -0700122#ifndef MOVING_COLLECTOR
123 // Clear the class bit since we mark the class as part of marking the classlinker roots.
124 DCHECK_EQ(mirror::Object::ClassOffset().Uint32Value(), 0U);
125 ref_offsets &= (1U << (sizeof(ref_offsets) * 8 - 1)) - 1;
126#endif
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800127 while (ref_offsets != 0) {
128 size_t right_shift = CLZ(ref_offsets);
129 MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700130 mirror::Object* ref = obj->GetFieldObject<mirror::Object*>(field_offset, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800131 visitor(obj, ref, field_offset, is_static);
132 ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
133 }
134 } else {
135 // There is no reference offset bitmap. In the non-static case,
136 // walk up the class inheritance hierarchy and find reference
137 // offsets the hard way. In the static case, just consider this
138 // class.
139 for (const mirror::Class* klass = is_static ? obj->AsClass() : obj->GetClass();
140 klass != NULL;
141 klass = is_static ? NULL : klass->GetSuperClass()) {
142 size_t num_reference_fields = (is_static
143 ? klass->NumReferenceStaticFields()
144 : klass->NumReferenceInstanceFields());
145 for (size_t i = 0; i < num_reference_fields; ++i) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700146 mirror::ArtField* field = (is_static ? klass->GetStaticField(i)
147 : klass->GetInstanceField(i));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800148 MemberOffset field_offset = field->GetOffset();
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700149 mirror::Object* ref = obj->GetFieldObject<mirror::Object*>(field_offset, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800150 visitor(obj, ref, field_offset, is_static);
151 }
152 }
153 }
154}
155
156template <typename Visitor>
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700157inline void MarkSweep::VisitObjectArrayReferences(mirror::ObjectArray<mirror::Object>* array,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800158 const Visitor& visitor) {
Mathieu Chartier94c32c52013-08-09 11:14:04 -0700159 const size_t length = static_cast<size_t>(array->GetLength());
160 for (size_t i = 0; i < length; ++i) {
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700161 mirror::Object* element = array->GetWithoutChecks(static_cast<int32_t>(i));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800162 const size_t width = sizeof(mirror::Object*);
Mathieu Chartier94c32c52013-08-09 11:14:04 -0700163 MemberOffset offset(i * width + mirror::Array::DataOffset(width).Int32Value());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800164 visitor(array, element, offset, false);
165 }
166}
167
Ian Rogers1d54e732013-05-02 21:10:01 -0700168} // namespace collector
169} // namespace gc
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800170} // namespace art
171
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700172#endif // ART_RUNTIME_GC_COLLECTOR_MARK_SWEEP_INL_H_