diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-08-18 13:54:21 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2015-08-18 16:11:21 -0700 |
commit | 059ef3ddb2088f926ac452889e0953fdcd646a5e (patch) | |
tree | 36067457d7e4aba11be908ddd235734d29b7c4f2 | |
parent | f71ad9ede9ae322a897e8fe407208dc35c5dee65 (diff) | |
download | art-059ef3ddb2088f926ac452889e0953fdcd646a5e.tar.gz art-059ef3ddb2088f926ac452889e0953fdcd646a5e.tar.bz2 art-059ef3ddb2088f926ac452889e0953fdcd646a5e.zip |
Always visit object class from VisitReferences
We don't want to unload classes which have instances.
Slight increase in CMS GC time from ~6.5s to ~7.3s on
EvaluateAndApplyChanges.
Bug: 22720414
Change-Id: I467ff9c9d55163d2a90b999aef3bdd7b3f648bac
-rw-r--r-- | compiler/driver/compiler_driver.cc | 2 | ||||
-rw-r--r-- | compiler/image_writer.cc | 4 | ||||
-rw-r--r-- | patchoat/patchoat.cc | 2 | ||||
-rw-r--r-- | runtime/gc/accounting/mod_union_table.cc | 6 | ||||
-rw-r--r-- | runtime/gc/accounting/remembered_set.cc | 2 | ||||
-rw-r--r-- | runtime/gc/collector/concurrent_copying.cc | 6 | ||||
-rw-r--r-- | runtime/gc/collector/mark_compact.cc | 4 | ||||
-rw-r--r-- | runtime/gc/collector/mark_sweep-inl.h | 2 | ||||
-rw-r--r-- | runtime/gc/collector/semi_space.cc | 4 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 6 | ||||
-rw-r--r-- | runtime/hprof/hprof.cc | 2 | ||||
-rw-r--r-- | runtime/mirror/class-inl.h | 6 | ||||
-rw-r--r-- | runtime/mirror/class.cc | 4 | ||||
-rw-r--r-- | runtime/mirror/class.h | 9 | ||||
-rw-r--r-- | runtime/mirror/class_loader-inl.h | 4 | ||||
-rw-r--r-- | runtime/mirror/class_loader.h | 6 | ||||
-rw-r--r-- | runtime/mirror/object-inl.h | 33 | ||||
-rw-r--r-- | runtime/mirror/object.cc | 2 | ||||
-rw-r--r-- | runtime/mirror/object.h | 11 | ||||
-rw-r--r-- | runtime/mirror/object_array-inl.h | 5 | ||||
-rw-r--r-- | runtime/mirror/object_array.h | 9 |
21 files changed, 62 insertions, 67 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index fa4667ec97..fa25a17481 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -1109,7 +1109,7 @@ class ClinitImageUpdate { // If it is not a DexCache, visit all references. mirror::Class* klass = object->GetClass(); if (klass != dex_cache_class_) { - object->VisitReferences<false /* visit class */>(*this, *this); + object->VisitReferences(*this, *this); } } diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 3a3410cf3a..93897aa228 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -1350,7 +1350,7 @@ void ImageWriter::FixupClass(mirror::Class* orig, mirror::Class* copy) { } } FixupClassVisitor visitor(this, copy); - static_cast<mirror::Object*>(orig)->VisitReferences<true /*visit class*/>(visitor, visitor); + static_cast<mirror::Object*>(orig)->VisitReferences(visitor, visitor); } void ImageWriter::FixupObject(Object* orig, Object* copy) { @@ -1397,7 +1397,7 @@ void ImageWriter::FixupObject(Object* orig, Object* copy) { down_cast<mirror::ClassLoader*>(copy)->SetClassTable(nullptr); } FixupVisitor visitor(this, copy); - orig->VisitReferences<true /*visit class*/>(visitor, visitor); + orig->VisitReferences(visitor, visitor); } } diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index d60103597a..a71197a6ce 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -623,7 +623,7 @@ void PatchOat::VisitObject(mirror::Object* object) { } } PatchOat::PatchVisitor visitor(this, copy); - object->VisitReferences<true, kVerifyNone>(visitor, visitor); + object->VisitReferences<kVerifyNone>(visitor, visitor); if (object->IsClass<kVerifyNone>()) { auto* klass = object->AsClass(); auto* copy_klass = down_cast<mirror::Class*>(copy); diff --git a/runtime/gc/accounting/mod_union_table.cc b/runtime/gc/accounting/mod_union_table.cc index dd9e2d1272..5151819d96 100644 --- a/runtime/gc/accounting/mod_union_table.cc +++ b/runtime/gc/accounting/mod_union_table.cc @@ -153,7 +153,7 @@ class ModUnionScanImageRootVisitor { DCHECK(root != nullptr); ModUnionUpdateObjectReferencesVisitor ref_visitor(visitor_, from_space_, immune_space_, contains_reference_to_other_space_); - root->VisitReferences<kMovingClasses>(ref_visitor, VoidFunctor()); + root->VisitReferences(ref_visitor, VoidFunctor()); } private: @@ -237,7 +237,7 @@ class ModUnionReferenceVisitor { visitor_, references_, has_target_reference_); - obj->VisitReferences<kMovingClasses>(visitor, VoidFunctor()); + obj->VisitReferences(visitor, VoidFunctor()); } private: @@ -304,7 +304,7 @@ class ModUnionCheckReferences { void operator()(Object* obj) const NO_THREAD_SAFETY_ANALYSIS { Locks::heap_bitmap_lock_->AssertSharedHeld(Thread::Current()); CheckReferenceVisitor visitor(mod_union_table_, references_); - obj->VisitReferences<kMovingClasses>(visitor, VoidFunctor()); + obj->VisitReferences(visitor, VoidFunctor()); } private: diff --git a/runtime/gc/accounting/remembered_set.cc b/runtime/gc/accounting/remembered_set.cc index b9f24f348f..277d319035 100644 --- a/runtime/gc/accounting/remembered_set.cc +++ b/runtime/gc/accounting/remembered_set.cc @@ -120,7 +120,7 @@ class RememberedSetObjectVisitor { SHARED_REQUIRES(Locks::mutator_lock_) { RememberedSetReferenceVisitor visitor(target_space_, contains_reference_to_target_space_, collector_); - obj->VisitReferences<kMovingClasses>(visitor, visitor); + obj->VisitReferences(visitor, visitor); } private: diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc index 220c06ee5a..263e67879b 100644 --- a/runtime/gc/collector/concurrent_copying.cc +++ b/runtime/gc/collector/concurrent_copying.cc @@ -683,7 +683,7 @@ class ConcurrentCopyingVerifyNoFromSpaceRefsObjectVisitor { space::RegionSpace* region_space = collector->RegionSpace(); CHECK(!region_space->IsInFromSpace(obj)) << "Scanning object " << obj << " in from space"; ConcurrentCopyingVerifyNoFromSpaceRefsFieldVisitor visitor(collector); - obj->VisitReferences<true>(visitor, visitor); + obj->VisitReferences(visitor, visitor); if (kUseBakerReadBarrier) { if (collector->RegionSpace()->IsInToSpace(obj)) { CHECK(obj->GetReadBarrierPointer() == nullptr) @@ -808,7 +808,7 @@ class ConcurrentCopyingAssertToSpaceInvariantObjectVisitor { CHECK(!region_space->IsInFromSpace(obj)) << "Scanning object " << obj << " in from space"; collector->AssertToSpaceInvariant(nullptr, MemberOffset(0), obj); ConcurrentCopyingAssertToSpaceInvariantFieldVisitor visitor(collector); - obj->VisitReferences<true>(visitor, visitor); + obj->VisitReferences(visitor, visitor); } private: @@ -1546,7 +1546,7 @@ class ConcurrentCopyingRefFieldsVisitor { void ConcurrentCopying::Scan(mirror::Object* to_ref) { DCHECK(!region_space_->IsInFromSpace(to_ref)); ConcurrentCopyingRefFieldsVisitor visitor(this); - to_ref->VisitReferences<true>(visitor, visitor); + to_ref->VisitReferences(visitor, visitor); } // Process a field. diff --git a/runtime/gc/collector/mark_compact.cc b/runtime/gc/collector/mark_compact.cc index 94ffe6ec79..60f833b349 100644 --- a/runtime/gc/collector/mark_compact.cc +++ b/runtime/gc/collector/mark_compact.cc @@ -457,7 +457,7 @@ class UpdateReferenceVisitor { void MarkCompact::UpdateObjectReferences(mirror::Object* obj) { UpdateReferenceVisitor visitor(this); - obj->VisitReferences<kMovingClasses>(visitor, visitor); + obj->VisitReferences(visitor, visitor); } inline mirror::Object* MarkCompact::GetMarkedForwardAddress(mirror::Object* obj) { @@ -608,7 +608,7 @@ class MarkCompactMarkObjectVisitor { // Visit all of the references of an object and update. void MarkCompact::ScanObject(mirror::Object* obj) { MarkCompactMarkObjectVisitor visitor(this); - obj->VisitReferences<kMovingClasses>(visitor, visitor); + obj->VisitReferences(visitor, visitor); } // Scan anything that's on the mark stack. diff --git a/runtime/gc/collector/mark_sweep-inl.h b/runtime/gc/collector/mark_sweep-inl.h index 4e3845e5d6..a3cc83132f 100644 --- a/runtime/gc/collector/mark_sweep-inl.h +++ b/runtime/gc/collector/mark_sweep-inl.h @@ -32,7 +32,7 @@ template<typename MarkVisitor, typename ReferenceVisitor> inline void MarkSweep::ScanObjectVisit(mirror::Object* obj, const MarkVisitor& visitor, const ReferenceVisitor& ref_visitor) { DCHECK(IsMarked(obj)) << "Scanning unmarked object " << obj << "\n" << heap_->DumpSpaces(); - obj->VisitReferences<false>(visitor, ref_visitor); + obj->VisitReferences(visitor, ref_visitor); if (kCountScannedTypes) { mirror::Class* klass = obj->GetClass<kVerifyNone>(); if (UNLIKELY(klass == mirror::Class::GetJavaLangClass())) { diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc index fc2a801b7f..a355d406d9 100644 --- a/runtime/gc/collector/semi_space.cc +++ b/runtime/gc/collector/semi_space.cc @@ -320,7 +320,7 @@ class SemiSpaceVerifyNoFromSpaceReferencesVisitor { void SemiSpace::VerifyNoFromSpaceReferences(Object* obj) { DCHECK(!from_space_->HasAddress(obj)) << "Scanning object " << obj << " in from space"; SemiSpaceVerifyNoFromSpaceReferencesVisitor visitor(from_space_); - obj->VisitReferences<kMovingClasses>(visitor, VoidFunctor()); + obj->VisitReferences(visitor, VoidFunctor()); } class SemiSpaceVerifyNoFromSpaceReferencesObjectVisitor { @@ -722,7 +722,7 @@ class SemiSpaceMarkObjectVisitor { void SemiSpace::ScanObject(Object* obj) { DCHECK(!from_space_->HasAddress(obj)) << "Scanning object " << obj << " in from space"; SemiSpaceMarkObjectVisitor visitor(this); - obj->VisitReferences<kMovingClasses>(visitor, visitor); + obj->VisitReferences(visitor, visitor); } // Scan anything that's on the mark stack. diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index e56351f553..d7f918b4ff 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -1795,7 +1795,7 @@ class ReferringObjectsFinder { // TODO: Fix lock analysis to not use NO_THREAD_SAFETY_ANALYSIS, requires support for // annotalysis on visitors. void operator()(mirror::Object* o) const NO_THREAD_SAFETY_ANALYSIS { - o->VisitReferences<true>(*this, VoidFunctor()); + o->VisitReferences(*this, VoidFunctor()); } // For Object::VisitReferences. @@ -2788,7 +2788,7 @@ class VerifyObjectVisitor { // be live or else how did we find it in the live bitmap? VerifyReferenceVisitor visitor(heap_, fail_count_, verify_referent_); // The class doesn't count as a reference but we should verify it anyways. - obj->VisitReferences<true>(visitor, visitor); + obj->VisitReferences(visitor, visitor); } static void VisitCallback(mirror::Object* obj, void* arg) @@ -2969,7 +2969,7 @@ class VerifyLiveStackReferences { void operator()(mirror::Object* obj) const SHARED_REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_) { VerifyReferenceCardVisitor visitor(heap_, const_cast<bool*>(&failed_)); - obj->VisitReferences<true>(visitor, VoidFunctor()); + obj->VisitReferences(visitor, VoidFunctor()); } bool Failed() const { diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc index 713797fc3d..a9a236fa69 100644 --- a/runtime/hprof/hprof.cc +++ b/runtime/hprof/hprof.cc @@ -1063,7 +1063,7 @@ void Hprof::DumpHeapObject(mirror::Object* obj) { } GcRootVisitor visitor(this); - obj->VisitReferences<true>(visitor, VoidFunctor()); + obj->VisitReferences(visitor, VoidFunctor()); gc::Heap* const heap = Runtime::Current()->GetHeap(); const gc::space::ContinuousSpace* const space = heap->FindContinuousSpaceFromObject(obj, true); diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index ac9cb09731..cd678f670b 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -669,9 +669,9 @@ inline uint32_t Class::ComputeClassSize(bool has_embedded_tables, return size; } -template <bool kVisitClass, typename Visitor> +template <typename Visitor> inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) { - VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); + VisitInstanceFieldsReferences(klass, visitor); // Right after a class is allocated, but not yet loaded // (kStatusNotReady, see ClassLinker::LoadClass()), GC may find it // and scan it. IsTemp() may call Class::GetAccessFlags() but may @@ -683,7 +683,7 @@ inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) // Temp classes don't ever populate imt/vtable or static fields and they are not even // allocated with the right size for those. Also, unresolved classes don't have fields // linked yet. - VisitStaticFieldsReferences<kVisitClass>(this, visitor); + VisitStaticFieldsReferences(this, visitor); } // Since this class is reachable, we must also visit the associated roots when we scan it. VisitNativeRoots(visitor, Runtime::Current()->GetClassLinker()->GetImagePointerSize()); diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index f20cc6ea5c..055b3e5110 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -872,8 +872,8 @@ class CopyClassVisitor { h_new_class_obj->SetClassSize(new_length_); // Visit all of the references to make sure there is no from space references in the native // roots. - h_new_class_obj->VisitReferences<true>(h_new_class_obj->GetClass(), - ReadBarrierOnNativeRootsVisitor()); + static_cast<mirror::Object*>(h_new_class_obj.Get())->VisitReferences( + ReadBarrierOnNativeRootsVisitor(), VoidFunctor()); } private: diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index dc60a380e3..3f375be9ca 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -1021,10 +1021,6 @@ class MANAGED Class FINAL : public Object { void SetPreverifiedFlagOnAllMethods(size_t pointer_size) SHARED_REQUIRES(Locks::mutator_lock_); - template <bool kVisitClass, typename Visitor> - void VisitReferences(mirror::Class* klass, const Visitor& visitor) - SHARED_REQUIRES(Locks::mutator_lock_); - // Get the descriptor of the class. In a few cases a std::string is required, rather than // always create one the storage argument is populated and its internal c_str() returned. We do // this to avoid memory allocation in the common case. @@ -1153,6 +1149,10 @@ class MANAGED Class FINAL : public Object { static MemberOffset EmbeddedImTableOffset(size_t pointer_size); static MemberOffset EmbeddedVTableOffset(size_t pointer_size); + template <typename Visitor> + void VisitReferences(mirror::Class* klass, const Visitor& visitor) + SHARED_REQUIRES(Locks::mutator_lock_); + // Defining class loader, or null for the "bootstrap" system loader. HeapReference<ClassLoader> class_loader_; @@ -1279,6 +1279,7 @@ class MANAGED Class FINAL : public Object { static GcRoot<Class> java_lang_Class_; friend struct art::ClassOffsets; // for verifying offset information + friend class Object; // For VisitReferences DISALLOW_IMPLICIT_CONSTRUCTORS(Class); }; diff --git a/runtime/mirror/class_loader-inl.h b/runtime/mirror/class_loader-inl.h index 35f3664fbf..e22ddd7e90 100644 --- a/runtime/mirror/class_loader-inl.h +++ b/runtime/mirror/class_loader-inl.h @@ -25,10 +25,10 @@ namespace art { namespace mirror { -template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor> +template <VerifyObjectFlags kVerifyFlags, typename Visitor> inline void ClassLoader::VisitReferences(mirror::Class* klass, const Visitor& visitor) { // Visit instance fields first. - VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); + VisitInstanceFieldsReferences(klass, visitor); // Visit classes loaded after. ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); ClassTable* const class_table = GetClassTable(); diff --git a/runtime/mirror/class_loader.h b/runtime/mirror/class_loader.h index 21c652a941..f27b6155ce 100644 --- a/runtime/mirror/class_loader.h +++ b/runtime/mirror/class_loader.h @@ -46,14 +46,15 @@ class MANAGED ClassLoader : public Object { SetField64<false>(OFFSET_OF_OBJECT_MEMBER(ClassLoader, class_table_), reinterpret_cast<uint64_t>(class_table)); } + + private: // Visit instance fields of the class loader as well as its associated classes. // Null class loader is handled by ClassLinker::VisitClassRoots. - template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor> + template <VerifyObjectFlags kVerifyFlags, typename Visitor> void VisitReferences(mirror::Class* klass, const Visitor& visitor) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Locks::classlinker_classes_lock_); - private: // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". HeapReference<Object> packages_; HeapReference<ClassLoader> parent_; @@ -63,6 +64,7 @@ class MANAGED ClassLoader : public Object { uint64_t class_table_; friend struct art::ClassLoaderOffsets; // for verifying offset information + friend class Object; // For VisitReferences DISALLOW_IMPLICIT_CONSTRUCTORS(ClassLoader); }; diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 7b1660ba7e..586ae30d19 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -942,13 +942,10 @@ inline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrie return success; } -template<bool kVisitClass, bool kIsStatic, typename Visitor> +template<bool kIsStatic, typename Visitor> inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) { if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) { // Instance fields and not the slow-path. - if (kVisitClass) { - visitor(this, ClassOffset(), kIsStatic); - } uint32_t field_offset = mirror::kObjectHeaderSize; while (ref_offsets != 0) { if ((ref_offsets & 1) != 0) { @@ -974,9 +971,9 @@ inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& v ? klass->GetFirstReferenceStaticFieldOffset( Runtime::Current()->GetClassLinker()->GetImagePointerSize()) : klass->GetFirstReferenceInstanceFieldOffset(); - for (size_t i = 0; i < num_reference_fields; ++i) { + for (size_t i = 0u; i < num_reference_fields; ++i) { // TODO: Do a simpler check? - if (kVisitClass || field_offset.Uint32Value() != ClassOffset().Uint32Value()) { + if (field_offset.Uint32Value() != ClassOffset().Uint32Value()) { visitor(this, field_offset, kIsStatic); } field_offset = MemberOffset(field_offset.Uint32Value() + @@ -986,19 +983,17 @@ inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& v } } -template<bool kVisitClass, typename Visitor> +template<typename Visitor> inline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) { - VisitFieldsReferences<kVisitClass, false>( - klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor); + VisitFieldsReferences<false>(klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor); } -template<bool kVisitClass, typename Visitor> +template<typename Visitor> inline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) { DCHECK(!klass->IsTemp()); - klass->VisitFieldsReferences<kVisitClass, true>(0, visitor); + klass->VisitFieldsReferences<true>(0, visitor); } - template<VerifyObjectFlags kVerifyFlags> inline bool Object::IsClassLoader() { return GetClass<kVerifyFlags>()->IsClassLoaderClass(); @@ -1010,25 +1005,23 @@ inline mirror::ClassLoader* Object::AsClassLoader() { return down_cast<mirror::ClassLoader*>(this); } -template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor, - typename JavaLangRefVisitor> +template <VerifyObjectFlags kVerifyFlags, typename Visitor, typename JavaLangRefVisitor> inline void Object::VisitReferences(const Visitor& visitor, const JavaLangRefVisitor& ref_visitor) { mirror::Class* klass = GetClass<kVerifyFlags>(); + visitor(this, ClassOffset(), false); if (klass == Class::GetJavaLangClass()) { - AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor); + AsClass<kVerifyNone>()->VisitReferences(klass, visitor); } else if (klass->IsArrayClass() || klass->IsStringClass()) { if (klass->IsObjectArrayClass<kVerifyNone>()) { - AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor); - } else if (kVisitClass) { - visitor(this, ClassOffset(), false); + AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences(visitor); } } else if (klass->IsClassLoaderClass()) { mirror::ClassLoader* class_loader = AsClassLoader<kVerifyFlags>(); - class_loader->VisitReferences<kVisitClass, kVerifyFlags>(klass, visitor); + class_loader->VisitReferences<kVerifyFlags>(klass, visitor); } else { DCHECK(!klass->IsVariableSize()); - VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); + VisitInstanceFieldsReferences(klass, visitor); if (UNLIKELY(klass->IsTypeOfReferenceClass<kVerifyNone>())) { ref_visitor(klass, AsReference()); } diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc index df680b5ba5..4d941302f9 100644 --- a/runtime/mirror/object.cc +++ b/runtime/mirror/object.cc @@ -85,7 +85,7 @@ Object* Object::CopyObject(Thread* self, mirror::Object* dest, mirror::Object* s // object above, copy references fields one by one again with a // RB. TODO: Optimize this later? CopyReferenceFieldsWithReadBarrierVisitor visitor(dest); - src->VisitReferences<true>(visitor, visitor); + src->VisitReferences(visitor, visitor); } gc::Heap* heap = Runtime::Current()->GetHeap(); // Perform write barriers on copied object references. diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index 4967a14a39..3cec29cd43 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -446,8 +446,9 @@ class MANAGED LOCKABLE Object { } // TODO fix thread safety analysis broken by the use of template. This should be // SHARED_REQUIRES(Locks::mutator_lock_). - template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, - typename Visitor, typename JavaLangRefVisitor = VoidFunctor> + template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, + typename Visitor, + typename JavaLangRefVisitor = VoidFunctor> void VisitReferences(const Visitor& visitor, const JavaLangRefVisitor& ref_visitor) NO_THREAD_SAFETY_ANALYSIS; @@ -481,13 +482,13 @@ class MANAGED LOCKABLE Object { } // TODO: Fixme when anotatalysis works with visitors. - template<bool kVisitClass, bool kIsStatic, typename Visitor> + template<bool kIsStatic, typename Visitor> void VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) HOT_ATTR NO_THREAD_SAFETY_ANALYSIS; - template<bool kVisitClass, typename Visitor> + template<typename Visitor> void VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) HOT_ATTR SHARED_REQUIRES(Locks::mutator_lock_); - template<bool kVisitClass, typename Visitor> + template<typename Visitor> void VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) HOT_ATTR SHARED_REQUIRES(Locks::mutator_lock_); diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h index 4a7e7b35da..5b73557941 100644 --- a/runtime/mirror/object_array-inl.h +++ b/runtime/mirror/object_array-inl.h @@ -269,11 +269,8 @@ inline MemberOffset ObjectArray<T>::OffsetOfElement(int32_t i) { (i * sizeof(HeapReference<Object>))); } -template<class T> template<const bool kVisitClass, typename Visitor> +template<class T> template<typename Visitor> void ObjectArray<T>::VisitReferences(const Visitor& visitor) { - if (kVisitClass) { - visitor(this, ClassOffset(), false); - } const size_t length = static_cast<size_t>(GetLength()); for (size_t i = 0; i < length; ++i) { visitor(this, OffsetOfElement(i), false); diff --git a/runtime/mirror/object_array.h b/runtime/mirror/object_array.h index 607b000488..b45cafd2a3 100644 --- a/runtime/mirror/object_array.h +++ b/runtime/mirror/object_array.h @@ -83,14 +83,15 @@ class MANAGED ObjectArray: public Array { ObjectArray<T>* CopyOf(Thread* self, int32_t new_length) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); + static MemberOffset OffsetOfElement(int32_t i); + + private: // TODO fix thread safety analysis broken by the use of template. This should be // SHARED_REQUIRES(Locks::mutator_lock_). - template<const bool kVisitClass, typename Visitor> + template<typename Visitor> void VisitReferences(const Visitor& visitor) NO_THREAD_SAFETY_ANALYSIS; - static MemberOffset OffsetOfElement(int32_t i); - - private: + friend class Object; // For VisitReferences DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectArray); }; |