diff options
Diffstat (limited to 'runtime/mirror/class-refvisitor-inl.h')
-rw-r--r-- | runtime/mirror/class-refvisitor-inl.h | 39 |
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 |