summaryrefslogtreecommitdiff
path: root/runtime/mirror/class-refvisitor-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mirror/class-refvisitor-inl.h')
-rw-r--r--runtime/mirror/class-refvisitor-inl.h39
1 files changed, 27 insertions, 12 deletions
diff --git a/runtime/mirror/class-refvisitor-inl.h b/runtime/mirror/class-refvisitor-inl.h
index 263b7746db..8c85387d6a 100644
--- a/runtime/mirror/class-refvisitor-inl.h
+++ b/runtime/mirror/class-refvisitor-inl.h
@@ -53,20 +53,14 @@ inline void Class::VisitReferences(ObjPtr<Class> klass, const Visitor& visitor)
template<ReadBarrierOption kReadBarrierOption, class Visitor>
void Class::VisitNativeRoots(Visitor& visitor, PointerSize pointer_size) {
- for (ArtField& field : GetSFieldsUnchecked()) {
- // Visit roots first in case the declaring class gets moved.
- field.VisitRoots(visitor);
+ VisitFields<kReadBarrierOption>([&](ArtField* field) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ field->VisitRoots(visitor);
if (kIsDebugBuild && IsResolved()) {
- CHECK_EQ(field.GetDeclaringClass<kReadBarrierOption>(), this) << GetStatus();
+ CHECK_EQ(field->GetDeclaringClass<kReadBarrierOption>(), this)
+ << GetStatus() << field->GetDeclaringClass()->PrettyClass() << " != " << PrettyClass();
}
- }
- for (ArtField& field : GetIFieldsUnchecked()) {
- // Visit roots first in case the declaring class gets moved.
- field.VisitRoots(visitor);
- if (kIsDebugBuild && IsResolved()) {
- CHECK_EQ(field.GetDeclaringClass<kReadBarrierOption>(), this) << GetStatus();
- }
- }
+ });
+ // Don't use VisitMethods because we don't want to hit the class-ext methods twice.
for (ArtMethod& method : GetMethods(pointer_size)) {
method.VisitRoots<kReadBarrierOption>(visitor, pointer_size);
}
@@ -76,6 +70,27 @@ void Class::VisitNativeRoots(Visitor& visitor, PointerSize pointer_size) {
}
}
+template<ReadBarrierOption kReadBarrierOption, class Visitor>
+void Class::VisitMethods(Visitor visitor, PointerSize pointer_size) {
+ for (ArtMethod& method : GetMethods(pointer_size)) {
+ visitor(&method);
+ }
+ ObjPtr<ClassExt> ext(GetExtData<kDefaultVerifyFlags, kReadBarrierOption>());
+ if (!ext.IsNull()) {
+ ext->VisitMethods<kReadBarrierOption, Visitor>(visitor, pointer_size);
+ }
+}
+
+template<ReadBarrierOption kReadBarrierOption, class Visitor>
+void Class::VisitFields(Visitor visitor) {
+ for (ArtField& sfield : GetSFieldsUnchecked()) {
+ visitor(&sfield);
+ }
+ for (ArtField& ifield : GetIFieldsUnchecked()) {
+ visitor(&ifield);
+ }
+}
+
} // namespace mirror
} // namespace art