diff options
Diffstat (limited to 'runtime')
67 files changed, 371 insertions, 332 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 978c99b..5acef70 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1119,14 +1119,15 @@ void ClassLinker::InitFromImage() { // Keep in sync with InitCallback. Anything we visit, we need to // reinit references to when reinitializing a ClassLinker from a // mapped image. -void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, bool clean_dirty) { - class_roots_ = down_cast<mirror::ObjectArray<mirror::Class>*>(visitor(class_roots_, arg)); +void ClassLinker::VisitRoots(RootCallback* callback, void* arg, bool only_dirty, bool clean_dirty) { + class_roots_ = down_cast<mirror::ObjectArray<mirror::Class>*>( + callback(class_roots_, arg, 0, kRootVMInternal)); Thread* self = Thread::Current(); { ReaderMutexLock mu(self, dex_lock_); if (!only_dirty || dex_caches_dirty_) { for (mirror::DexCache*& dex_cache : dex_caches_) { - dex_cache = down_cast<mirror::DexCache*>(visitor(dex_cache, arg)); + dex_cache = down_cast<mirror::DexCache*>(callback(dex_cache, arg, 0, kRootVMInternal)); DCHECK(dex_cache != nullptr); } if (clean_dirty) { @@ -1139,7 +1140,7 @@ void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, b WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); if (!only_dirty || class_table_dirty_) { for (std::pair<const size_t, mirror::Class*>& it : class_table_) { - it.second = down_cast<mirror::Class*>(visitor(it.second, arg)); + it.second = down_cast<mirror::Class*>(callback(it.second, arg, 0, kRootStickyClass)); DCHECK(it.second != nullptr); } if (clean_dirty) { @@ -1151,7 +1152,8 @@ void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, b // handle image roots by using the MS/CMS rescanning of dirty cards. } - array_iftable_ = reinterpret_cast<mirror::IfTable*>(visitor(array_iftable_, arg)); + array_iftable_ = reinterpret_cast<mirror::IfTable*>(callback(array_iftable_, arg, 0, + kRootVMInternal)); DCHECK(array_iftable_ != nullptr); } diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 7e31356..0745ee2 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -26,8 +26,8 @@ #include "dex_file.h" #include "gtest/gtest.h" #include "jni.h" -#include "root_visitor.h" #include "oat_file.h" +#include "object_callbacks.h" namespace art { namespace gc { @@ -235,7 +235,7 @@ class ClassLinker { LOCKS_EXCLUDED(dex_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, bool clean_dirty) + void VisitRoots(RootCallback* callback, void* arg, bool only_dirty, bool clean_dirty) LOCKS_EXCLUDED(Locks::classlinker_classes_lock_, dex_lock_); mirror::DexCache* FindDexCache(const DexFile& dex_file) const diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index fb979c2..d9ef0c1 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -339,7 +339,7 @@ class ClassLinkerTest : public CommonTest { } } - static mirror::Object* TestRootVisitor(mirror::Object* root, void*) { + static mirror::Object* TestRootVisitor(mirror::Object* root, void*, uint32_t, RootType) { EXPECT_TRUE(root != NULL); return root; } diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 8280c7c..67db2ab 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -85,17 +85,17 @@ struct AllocRecord { return depth; } - void UpdateObjectPointers(RootVisitor* visitor, void* arg) + void UpdateObjectPointers(IsMarkedCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { if (type != nullptr) { - type = down_cast<mirror::Class*>(visitor(type, arg)); + type = down_cast<mirror::Class*>(callback(type, arg)); } for (size_t stack_frame = 0; stack_frame < kMaxAllocRecordStackDepth; ++stack_frame) { mirror::ArtMethod*& m = stack[stack_frame].method; if (m == nullptr) { break; } - m = down_cast<mirror::ArtMethod*>(visitor(m, arg)); + m = down_cast<mirror::ArtMethod*>(callback(m, arg)); } } }; @@ -3793,7 +3793,7 @@ void Dbg::DumpRecentAllocations() { } } -void Dbg::UpdateObjectPointers(RootVisitor* visitor, void* arg) { +void Dbg::UpdateObjectPointers(IsMarkedCallback* visitor, void* arg) { { MutexLock mu(Thread::Current(), gAllocTrackerLock); if (recent_allocation_records_ != nullptr) { diff --git a/runtime/debugger.h b/runtime/debugger.h index f1e3f45..5d269ee 100644 --- a/runtime/debugger.h +++ b/runtime/debugger.h @@ -29,7 +29,7 @@ #include "jdwp/jdwp.h" #include "jni.h" #include "jvalue.h" -#include "root_visitor.h" +#include "object_callbacks.h" #include "thread_state.h" namespace art { @@ -453,7 +453,7 @@ class Dbg { static void DumpRecentAllocations(); // Updates the stored direct object pointers (called from SweepSystemWeaks). - static void UpdateObjectPointers(RootVisitor* visitor, void* arg) + static void UpdateObjectPointers(IsMarkedCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); enum HpifWhen { diff --git a/runtime/gc/accounting/heap_bitmap.cc b/runtime/gc/accounting/heap_bitmap.cc index c520ee6..f94cf24 100644 --- a/runtime/gc/accounting/heap_bitmap.cc +++ b/runtime/gc/accounting/heap_bitmap.cc @@ -72,12 +72,10 @@ void HeapBitmap::RemoveDiscontinuousObjectSet(ObjectSet* set) { discontinuous_space_sets_.erase(it); } -void HeapBitmap::Walk(SpaceBitmap::Callback* callback, void* arg) { +void HeapBitmap::Walk(ObjectCallback* callback, void* arg) { for (const auto& bitmap : continuous_space_bitmaps_) { bitmap->Walk(callback, arg); } - - DCHECK(!discontinuous_space_sets_.empty()); for (const auto& space_set : discontinuous_space_sets_) { space_set->Walk(callback, arg); } diff --git a/runtime/gc/accounting/heap_bitmap.h b/runtime/gc/accounting/heap_bitmap.h index bcf36a2..dde1425 100644 --- a/runtime/gc/accounting/heap_bitmap.h +++ b/runtime/gc/accounting/heap_bitmap.h @@ -20,6 +20,7 @@ #include "base/logging.h" #include "gc_allocator.h" #include "locks.h" +#include "object_callbacks.h" #include "space_bitmap.h" namespace art { @@ -83,7 +84,7 @@ class HeapBitmap { return NULL; } - void Walk(SpaceBitmap::Callback* callback, void* arg) + void Walk(ObjectCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); template <typename Visitor> diff --git a/runtime/gc/accounting/mod_union_table.cc b/runtime/gc/accounting/mod_union_table.cc index 0225f29..aad214a 100644 --- a/runtime/gc/accounting/mod_union_table.cc +++ b/runtime/gc/accounting/mod_union_table.cc @@ -70,8 +70,8 @@ class ModUnionClearCardVisitor { class ModUnionUpdateObjectReferencesVisitor { public: - ModUnionUpdateObjectReferencesVisitor(RootVisitor visitor, void* arg) - : visitor_(visitor), + ModUnionUpdateObjectReferencesVisitor(RootCallback* callback, void* arg) + : callback_(callback), arg_(arg) { } @@ -80,7 +80,7 @@ class ModUnionUpdateObjectReferencesVisitor { bool /* is_static */) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // Only add the reference if it is non null and fits our criteria. if (ref != nullptr) { - Object* new_ref = visitor_(ref, arg_); + Object* new_ref = callback_(ref, arg_, 0, kRootVMInternal); if (new_ref != ref) { // Use SetFieldObjectWithoutWriteBarrier to avoid card mark as an optimization which // reduces dirtied pages and improves performance. @@ -90,26 +90,26 @@ class ModUnionUpdateObjectReferencesVisitor { } private: - RootVisitor* visitor_; + RootCallback* const callback_; void* arg_; }; class ModUnionScanImageRootVisitor { public: - ModUnionScanImageRootVisitor(RootVisitor visitor, void* arg) - : visitor_(visitor), arg_(arg) {} + ModUnionScanImageRootVisitor(RootCallback* callback, void* arg) + : callback_(callback), arg_(arg) {} void operator()(Object* root) const EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { DCHECK(root != NULL); - ModUnionUpdateObjectReferencesVisitor ref_visitor(visitor_, arg_); + ModUnionUpdateObjectReferencesVisitor ref_visitor(callback_, arg_); collector::MarkSweep::VisitObjectReferences(root, ref_visitor, true); } private: - RootVisitor* visitor_; - void* arg_; + RootCallback* const callback_; + void* const arg_; }; void ModUnionTableReferenceCache::ClearCards() { @@ -261,7 +261,7 @@ void ModUnionTableReferenceCache::Dump(std::ostream& os) { } } -void ModUnionTableReferenceCache::UpdateAndMarkReferences(RootVisitor visitor, void* arg) { +void ModUnionTableReferenceCache::UpdateAndMarkReferences(RootCallback* callback, void* arg) { Heap* heap = GetHeap(); CardTable* card_table = heap->GetCardTable(); @@ -296,7 +296,7 @@ void ModUnionTableReferenceCache::UpdateAndMarkReferences(RootVisitor visitor, v for (mirror::HeapReference<Object>* obj_ptr : ref.second) { Object* obj = obj_ptr->AsMirrorPtr(); if (obj != nullptr) { - Object* new_obj = visitor(obj, arg); + Object* new_obj = callback(obj, arg, 0, kRootVMInternal); // Avoid dirtying pages in the image unless necessary. if (new_obj != obj) { obj_ptr->Assign(new_obj); @@ -318,9 +318,9 @@ void ModUnionTableCardCache::ClearCards() { } // Mark all references to the alloc space(s). -void ModUnionTableCardCache::UpdateAndMarkReferences(RootVisitor visitor, void* arg) { +void ModUnionTableCardCache::UpdateAndMarkReferences(RootCallback* callback, void* arg) { CardTable* card_table = heap_->GetCardTable(); - ModUnionScanImageRootVisitor scan_visitor(visitor, arg); + ModUnionScanImageRootVisitor scan_visitor(callback, arg); SpaceBitmap* bitmap = space_->GetLiveBitmap(); for (const byte* card_addr : cleared_cards_) { uintptr_t start = reinterpret_cast<uintptr_t>(card_table->AddrFromCard(card_addr)); diff --git a/runtime/gc/accounting/mod_union_table.h b/runtime/gc/accounting/mod_union_table.h index a89dbd1..7d5d8d2 100644 --- a/runtime/gc/accounting/mod_union_table.h +++ b/runtime/gc/accounting/mod_union_table.h @@ -19,7 +19,7 @@ #include "gc_allocator.h" #include "globals.h" -#include "root_visitor.h" +#include "object_callbacks.h" #include "safe_map.h" #include <set> @@ -69,7 +69,7 @@ class ModUnionTable { // Update the mod-union table using data stored by ClearCards. There may be multiple ClearCards // before a call to update, for example, back-to-back sticky GCs. Also mark references to other // spaces which are stored in the mod-union table. - virtual void UpdateAndMarkReferences(RootVisitor visitor, void* arg) = 0; + virtual void UpdateAndMarkReferences(RootCallback* callback, void* arg) = 0; // Verification, sanity checks that we don't have clean cards which conflict with out cached data // for said cards. Exclusive lock is required since verify sometimes uses @@ -106,7 +106,7 @@ class ModUnionTableReferenceCache : public ModUnionTable { void ClearCards(); // Update table based on cleared cards and mark all references to the other spaces. - void UpdateAndMarkReferences(RootVisitor visitor, void* arg) + void UpdateAndMarkReferences(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); @@ -142,7 +142,7 @@ class ModUnionTableCardCache : public ModUnionTable { void ClearCards(); // Mark all references to the alloc space(s). - void UpdateAndMarkReferences(RootVisitor visitor, void* arg) + void UpdateAndMarkReferences(RootCallback* callback, void* arg) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc index a080bee..ad4ff1b 100644 --- a/runtime/gc/accounting/space_bitmap.cc +++ b/runtime/gc/accounting/space_bitmap.cc @@ -44,7 +44,7 @@ std::string SpaceBitmap::Dump() const { reinterpret_cast<void*>(HeapLimit())); } -void ObjectSet::Walk(SpaceBitmap::Callback* callback, void* arg) { +void ObjectSet::Walk(ObjectCallback* callback, void* arg) { for (const mirror::Object* obj : contained_) { callback(const_cast<mirror::Object*>(obj), arg); } @@ -102,7 +102,7 @@ void SpaceBitmap::CopyFrom(SpaceBitmap* source_bitmap) { // Visits set bits in address order. The callback is not permitted to // change the bitmap bits or max during the traversal. -void SpaceBitmap::Walk(SpaceBitmap::Callback* callback, void* arg) { +void SpaceBitmap::Walk(ObjectCallback* callback, void* arg) { CHECK(bitmap_begin_ != NULL); CHECK(callback != NULL); @@ -174,12 +174,12 @@ void SpaceBitmap::SweepWalk(const SpaceBitmap& live_bitmap, } } -static void WalkFieldsInOrder(SpaceBitmap* visited, SpaceBitmap::Callback* callback, mirror::Object* obj, +static void WalkFieldsInOrder(SpaceBitmap* visited, ObjectCallback* callback, mirror::Object* obj, void* arg); // Walk instance fields of the given Class. Separate function to allow recursion on the super // class. -static void WalkInstanceFields(SpaceBitmap* visited, SpaceBitmap::Callback* callback, mirror::Object* obj, +static void WalkInstanceFields(SpaceBitmap* visited, ObjectCallback* callback, mirror::Object* obj, mirror::Class* klass, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // Visit fields of parent classes first. @@ -204,7 +204,7 @@ static void WalkInstanceFields(SpaceBitmap* visited, SpaceBitmap::Callback* call } // For an unvisited object, visit it then all its children found via fields. -static void WalkFieldsInOrder(SpaceBitmap* visited, SpaceBitmap::Callback* callback, mirror::Object* obj, +static void WalkFieldsInOrder(SpaceBitmap* visited, ObjectCallback* callback, mirror::Object* obj, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { if (visited->Test(obj)) { @@ -246,7 +246,7 @@ static void WalkFieldsInOrder(SpaceBitmap* visited, SpaceBitmap::Callback* callb // Visits set bits with an in order traversal. The callback is not permitted to change the bitmap // bits or max during the traversal. -void SpaceBitmap::InOrderWalk(SpaceBitmap::Callback* callback, void* arg) { +void SpaceBitmap::InOrderWalk(ObjectCallback* callback, void* arg) { UniquePtr<SpaceBitmap> visited(Create("bitmap for in-order walk", reinterpret_cast<byte*>(heap_begin_), IndexToOffset(bitmap_size_ / kWordSize))); diff --git a/runtime/gc/accounting/space_bitmap.h b/runtime/gc/accounting/space_bitmap.h index aa074eb..3c4b674 100644 --- a/runtime/gc/accounting/space_bitmap.h +++ b/runtime/gc/accounting/space_bitmap.h @@ -17,10 +17,11 @@ #ifndef ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_ #define ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_ -#include "locks.h" #include "gc_allocator.h" #include "globals.h" +#include "locks.h" #include "mem_map.h" +#include "object_callbacks.h" #include "UniquePtr.h" #include <limits.h> @@ -42,8 +43,6 @@ class SpaceBitmap { // Alignment of objects within spaces. static const size_t kAlignment = 8; - typedef void Callback(mirror::Object* obj, void* arg); - typedef void ScanCallback(mirror::Object* obj, void* finger, void* arg); typedef void SweepCallback(size_t ptr_count, mirror::Object** ptrs, void* arg); @@ -102,7 +101,7 @@ class SpaceBitmap { return index < bitmap_size_ / kWordSize; } - void VisitRange(uintptr_t base, uintptr_t max, Callback* visitor, void* arg) const; + void VisitRange(uintptr_t base, uintptr_t max, ObjectCallback* callback, void* arg) const; class ClearVisitor { public: @@ -129,10 +128,10 @@ class SpaceBitmap { EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void Walk(Callback* callback, void* arg) + void Walk(ObjectCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); - void InOrderWalk(Callback* callback, void* arg) + void InOrderWalk(ObjectCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); static void SweepWalk(const SpaceBitmap& live, const SpaceBitmap& mark, uintptr_t base, @@ -249,7 +248,7 @@ class ObjectSet { contained_ = space_set.contained_; } - void Walk(SpaceBitmap::Callback* callback, void* arg) + void Walk(ObjectCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(GlobalSynchronization::heap_bitmap_lock_); template <typename Visitor> diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index 862d06f..de9f59e 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -525,14 +525,16 @@ void MarkSweep::MarkRoot(const Object* obj) { } } -Object* MarkSweep::MarkRootParallelCallback(Object* root, void* arg) { +mirror::Object* MarkSweep::MarkRootParallelCallback(mirror::Object* root, void* arg, + uint32_t /*thread_id*/, RootType /*root_type*/) { DCHECK(root != NULL); DCHECK(arg != NULL); reinterpret_cast<MarkSweep*>(arg)->MarkObjectNonNullParallel(root); return root; } -Object* MarkSweep::MarkRootCallback(Object* root, void* arg) { +Object* MarkSweep::MarkRootCallback(Object* root, void* arg, uint32_t /*thread_id*/, + RootType /*root_type*/) { DCHECK(root != nullptr); DCHECK(arg != nullptr); reinterpret_cast<MarkSweep*>(arg)->MarkObjectNonNull(root); @@ -930,7 +932,7 @@ void MarkSweep::RecursiveMark() { ProcessMarkStack(false); } -mirror::Object* MarkSweep::IsMarkedCallback(Object* object, void* arg) { +mirror::Object* MarkSweep::IsMarkedCallback(mirror::Object* object, void* arg) { if (reinterpret_cast<MarkSweep*>(arg)->IsMarked(object)) { return object; } diff --git a/runtime/gc/collector/mark_sweep.h b/runtime/gc/collector/mark_sweep.h index bfedac7..8bc0bb5 100644 --- a/runtime/gc/collector/mark_sweep.h +++ b/runtime/gc/collector/mark_sweep.h @@ -22,8 +22,8 @@ #include "base/macros.h" #include "base/mutex.h" #include "garbage_collector.h" +#include "object_callbacks.h" #include "offsets.h" -#include "root_visitor.h" #include "UniquePtr.h" namespace art { @@ -180,11 +180,13 @@ class MarkSweep : public GarbageCollector { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); - static mirror::Object* MarkRootCallback(mirror::Object* root, void* arg) + static mirror::Object* MarkRootCallback(mirror::Object* root, void* arg, uint32_t thread_id, + RootType root_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); - static mirror::Object* MarkRootParallelCallback(mirror::Object* root, void* arg); + static mirror::Object* MarkRootParallelCallback(mirror::Object* root, void* arg, + uint32_t thread_id, RootType root_type); // Marks an object. void MarkObject(const mirror::Object* obj) diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc index 0c6a938..b37b9d2 100644 --- a/runtime/gc/collector/semi_space.cc +++ b/runtime/gc/collector/semi_space.cc @@ -513,7 +513,7 @@ Object* SemiSpace::MarkObject(Object* obj) { return forward_address; } -Object* SemiSpace::RecursiveMarkObjectCallback(Object* root, void* arg) { +mirror::Object* SemiSpace::RecursiveMarkObjectCallback(mirror::Object* root, void* arg) { DCHECK(root != nullptr); DCHECK(arg != nullptr); SemiSpace* semi_space = reinterpret_cast<SemiSpace*>(arg); @@ -522,7 +522,8 @@ Object* SemiSpace::RecursiveMarkObjectCallback(Object* root, void* arg) { return ret; } -Object* SemiSpace::MarkRootCallback(Object* root, void* arg) { +Object* SemiSpace::MarkRootCallback(Object* root, void* arg, uint32_t /*thread_id*/, + RootType /*root_type*/) { DCHECK(root != nullptr); DCHECK(arg != nullptr); return reinterpret_cast<SemiSpace*>(arg)->MarkObject(root); @@ -536,7 +537,7 @@ void SemiSpace::MarkRoots() { timings_.EndSplit(); } -mirror::Object* SemiSpace::MarkedForwardingAddressCallback(Object* object, void* arg) { +mirror::Object* SemiSpace::MarkedForwardingAddressCallback(mirror::Object* object, void* arg) { return reinterpret_cast<SemiSpace*>(arg)->GetMarkedForwardAddress(object); } diff --git a/runtime/gc/collector/semi_space.h b/runtime/gc/collector/semi_space.h index 685b33c..f58402f 100644 --- a/runtime/gc/collector/semi_space.h +++ b/runtime/gc/collector/semi_space.h @@ -22,8 +22,8 @@ #include "base/macros.h" #include "base/mutex.h" #include "garbage_collector.h" +#include "object_callbacks.h" #include "offsets.h" -#include "root_visitor.h" #include "UniquePtr.h" namespace art { @@ -142,7 +142,8 @@ class SemiSpace : public GarbageCollector { static void VisitObjectReferencesAndClass(mirror::Object* obj, const Visitor& visitor) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); - static mirror::Object* MarkRootCallback(mirror::Object* root, void* arg) + static mirror::Object* MarkRootCallback(mirror::Object* root, void* arg, uint32_t /*tid*/, + RootType /*root_type*/) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); static mirror::Object* RecursiveMarkObjectCallback(mirror::Object* root, void* arg) diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 62567d7..9c828b2 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -369,7 +369,7 @@ void Heap::CreateThreadPool() { } } -void Heap::VisitObjects(ObjectVisitorCallback callback, void* arg) { +void Heap::VisitObjects(ObjectCallback callback, void* arg) { Thread* self = Thread::Current(); // GCs can move objects, so don't allow this. const char* old_cause = self->StartAssertNoThreadSuspension("Visiting objects"); @@ -604,8 +604,8 @@ space::Space* Heap::FindSpaceFromObject(const mirror::Object* obj, bool fail_ok) } struct SoftReferenceArgs { - RootVisitor* is_marked_callback_; - RootVisitor* recursive_mark_callback_; + IsMarkedCallback* is_marked_callback_; + MarkObjectCallback* recursive_mark_callback_; void* arg_; }; @@ -617,8 +617,8 @@ mirror::Object* Heap::PreserveSoftReferenceCallback(mirror::Object* obj, void* a // Process reference class instances and schedule finalizations. void Heap::ProcessReferences(TimingLogger& timings, bool clear_soft, - RootVisitor* is_marked_callback, - RootVisitor* recursive_mark_object_callback, void* arg) { + IsMarkedCallback* is_marked_callback, + MarkObjectCallback* recursive_mark_object_callback, void* arg) { // Unless we are in the zygote or required to clear soft references with white references, // preserve some white referents. if (!clear_soft && !Runtime::Current()->IsZygote()) { @@ -671,13 +671,13 @@ bool Heap::IsEnqueuable(mirror::Object* ref) const { // Process the "referent" field in a java.lang.ref.Reference. If the referent has not yet been // marked, put it on the appropriate list in the heap for later processing. void Heap::DelayReferenceReferent(mirror::Class* klass, mirror::Object* obj, - RootVisitor mark_visitor, void* arg) { + IsMarkedCallback is_marked_callback, void* arg) { DCHECK(klass != nullptr); DCHECK(klass->IsReferenceClass()); DCHECK(obj != nullptr); mirror::Object* referent = GetReferenceReferent(obj); if (referent != nullptr) { - mirror::Object* forward_address = mark_visitor(referent, arg); + mirror::Object* forward_address = is_marked_callback(referent, arg); // Null means that the object is not currently marked. if (forward_address == nullptr) { Thread* self = Thread::Current(); @@ -1169,7 +1169,7 @@ class ReferringObjectsFinder { void Heap::GetReferringObjects(mirror::Object* o, int32_t max_count, std::vector<mirror::Object*>& referring_objects) { - // Can't do any GC in this function since this may move classes. + // Can't do any GC in this function since this may move the object o. Thread* self = Thread::Current(); auto* old_cause = self->StartAssertNoThreadSuspension("GetReferringObjects"); ReferringObjectsFinder finder(o, max_count, referring_objects); @@ -1696,7 +1696,8 @@ void Heap::FinishGC(Thread* self, collector::GcType gc_type) { gc_complete_cond_->Broadcast(self); } -static mirror::Object* RootMatchesObjectVisitor(mirror::Object* root, void* arg) { +static mirror::Object* RootMatchesObjectVisitor(mirror::Object* root, void* arg, + uint32_t /*thread_id*/, RootType /*root_type*/) { mirror::Object* obj = reinterpret_cast<mirror::Object*>(arg); if (root == obj) { LOG(INFO) << "Object " << obj << " is a root"; @@ -1823,7 +1824,8 @@ class VerifyReferenceVisitor { return heap_->IsLiveObjectLocked(obj, true, false, true); } - static mirror::Object* VerifyRoots(mirror::Object* root, void* arg) { + static mirror::Object* VerifyRoots(mirror::Object* root, void* arg, uint32_t /*thread_id*/, + RootType /*root_type*/) { VerifyReferenceVisitor* visitor = reinterpret_cast<VerifyReferenceVisitor*>(arg); (*visitor)(nullptr, root, MemberOffset(0), true); return root; @@ -2041,7 +2043,7 @@ void Heap::ProcessCards(TimingLogger& timings) { } } -static mirror::Object* IdentityCallback(mirror::Object* obj, void*) { +static mirror::Object* IdentityRootCallback(mirror::Object* obj, void*, uint32_t, RootType) { return obj; } @@ -2080,7 +2082,7 @@ void Heap::PreGcVerification(collector::GarbageCollector* gc) { ReaderMutexLock reader_lock(self, *Locks::heap_bitmap_lock_); for (const auto& table_pair : mod_union_tables_) { accounting::ModUnionTable* mod_union_table = table_pair.second; - mod_union_table->UpdateAndMarkReferences(IdentityCallback, nullptr); + mod_union_table->UpdateAndMarkReferences(IdentityRootCallback, nullptr); mod_union_table->Verify(); } thread_list->ResumeAll(); diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 476ceee..368a687 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -32,9 +32,9 @@ #include "gtest/gtest.h" #include "jni.h" #include "locks.h" +#include "object_callbacks.h" #include "offsets.h" #include "reference_queue.h" -#include "root_visitor.h" #include "safe_map.h" #include "thread_pool.h" @@ -183,7 +183,7 @@ class Heap { } // Visit all of the live objects in the heap. - void VisitObjects(ObjectVisitorCallback callback, void* arg) + void VisitObjects(ObjectCallback callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); void SwapSemiSpaces() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -328,8 +328,9 @@ class Heap { return finalizer_reference_zombie_offset_; } static mirror::Object* PreserveSoftReferenceCallback(mirror::Object* obj, void* arg); - void ProcessReferences(TimingLogger& timings, bool clear_soft, RootVisitor* is_marked_callback, - RootVisitor* recursive_mark_object_callback, void* arg) + void ProcessReferences(TimingLogger& timings, bool clear_soft, + IsMarkedCallback* is_marked_callback, + MarkObjectCallback* recursive_mark_object_callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); @@ -605,8 +606,9 @@ class Heap { // Returns true if the reference object has not yet been enqueued. bool IsEnqueuable(mirror::Object* ref) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsEnqueued(mirror::Object* ref) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void DelayReferenceReferent(mirror::Class* klass, mirror::Object* obj, RootVisitor mark_visitor, - void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void DelayReferenceReferent(mirror::Class* klass, mirror::Object* obj, + IsMarkedCallback is_marked_callback, void* arg) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Run the finalizers. void RunFinalization(JNIEnv* env); diff --git a/runtime/gc/reference_queue.cc b/runtime/gc/reference_queue.cc index 2d73a71..fae4cac 100644 --- a/runtime/gc/reference_queue.cc +++ b/runtime/gc/reference_queue.cc @@ -94,13 +94,14 @@ void ReferenceQueue::Dump(std::ostream& os) const { } } -void ReferenceQueue::ClearWhiteReferences(ReferenceQueue& cleared_references, RootVisitor visitor, +void ReferenceQueue::ClearWhiteReferences(ReferenceQueue& cleared_references, + IsMarkedCallback* preserve_callback, void* arg) { while (!IsEmpty()) { mirror::Object* ref = DequeuePendingReference(); mirror::Object* referent = heap_->GetReferenceReferent(ref); if (referent != nullptr) { - mirror::Object* forward_address = visitor(referent, arg); + mirror::Object* forward_address = preserve_callback(referent, arg); if (forward_address == nullptr) { // Referent is white, clear it. heap_->ClearReferenceReferent(ref); @@ -108,7 +109,7 @@ void ReferenceQueue::ClearWhiteReferences(ReferenceQueue& cleared_references, Ro cleared_references.EnqueuePendingReference(ref); } } else if (referent != forward_address) { - // Object moved, need to updated the referrent. + // Object moved, need to updated the referent. heap_->SetReferenceReferent(ref, forward_address); } } @@ -116,8 +117,9 @@ void ReferenceQueue::ClearWhiteReferences(ReferenceQueue& cleared_references, Ro } void ReferenceQueue::EnqueueFinalizerReferences(ReferenceQueue& cleared_references, - RootVisitor is_marked_callback, - RootVisitor recursive_mark_callback, void* arg) { + IsMarkedCallback is_marked_callback, + MarkObjectCallback recursive_mark_callback, + void* arg) { while (!IsEmpty()) { mirror::Object* ref = DequeuePendingReference(); mirror::Object* referent = heap_->GetReferenceReferent(ref); @@ -139,7 +141,7 @@ void ReferenceQueue::EnqueueFinalizerReferences(ReferenceQueue& cleared_referenc } } -void ReferenceQueue::PreserveSomeSoftReferences(RootVisitor preserve_callback, void* arg) { +void ReferenceQueue::PreserveSomeSoftReferences(IsMarkedCallback preserve_callback, void* arg) { ReferenceQueue cleared(heap_); while (!IsEmpty()) { mirror::Object* ref = DequeuePendingReference(); @@ -149,7 +151,7 @@ void ReferenceQueue::PreserveSomeSoftReferences(RootVisitor preserve_callback, v if (forward_address == nullptr) { // Either the reference isn't marked or we don't wish to preserve it. cleared.EnqueuePendingReference(ref); - } else { + } else if (forward_address != referent) { heap_->SetReferenceReferent(ref, forward_address); } } diff --git a/runtime/gc/reference_queue.h b/runtime/gc/reference_queue.h index 3f3069e..e12a95f 100644 --- a/runtime/gc/reference_queue.h +++ b/runtime/gc/reference_queue.h @@ -27,8 +27,8 @@ #include "gtest/gtest.h" #include "jni.h" #include "locks.h" +#include "object_callbacks.h" #include "offsets.h" -#include "root_visitor.h" #include "thread_pool.h" namespace art { @@ -56,17 +56,18 @@ class ReferenceQueue { // Enqueues finalizer references with white referents. White referents are blackened, moved to the // zombie field, and the referent field is cleared. void EnqueueFinalizerReferences(ReferenceQueue& cleared_references, - RootVisitor is_marked_callback, - RootVisitor recursive_mark_callback, void* arg) + IsMarkedCallback is_marked_callback, + MarkObjectCallback recursive_mark_callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Walks the reference list marking any references subject to the reference clearing policy. // References with a black referent are removed from the list. References with white referents // biased toward saving are blackened and also removed from the list. - void PreserveSomeSoftReferences(RootVisitor preserve_callback, void* arg) + void PreserveSomeSoftReferences(IsMarkedCallback* preserve_callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Unlink the reference list clearing references objects with white referents. Cleared references // registered to a reference queue are scheduled for appending by the heap worker thread. - void ClearWhiteReferences(ReferenceQueue& cleared_references, RootVisitor visitor, void* arg) + void ClearWhiteReferences(ReferenceQueue& cleared_references, IsMarkedCallback is_marked_callback, + void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void Dump(std::ostream& os) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/runtime/gc/space/bump_pointer_space.cc b/runtime/gc/space/bump_pointer_space.cc index a314d74..2e07bd3 100644 --- a/runtime/gc/space/bump_pointer_space.cc +++ b/runtime/gc/space/bump_pointer_space.cc @@ -137,7 +137,7 @@ byte* BumpPointerSpace::AllocBlock(size_t bytes) { return storage; } -void BumpPointerSpace::Walk(ObjectVisitorCallback callback, void* arg) { +void BumpPointerSpace::Walk(ObjectCallback* callback, void* arg) { byte* pos = Begin(); { diff --git a/runtime/gc/space/bump_pointer_space.h b/runtime/gc/space/bump_pointer_space.h index d73fe3b..ddd17be 100644 --- a/runtime/gc/space/bump_pointer_space.h +++ b/runtime/gc/space/bump_pointer_space.h @@ -17,7 +17,7 @@ #ifndef ART_RUNTIME_GC_SPACE_BUMP_POINTER_SPACE_H_ #define ART_RUNTIME_GC_SPACE_BUMP_POINTER_SPACE_H_ -#include "root_visitor.h" +#include "object_callbacks.h" #include "space.h" namespace art { @@ -121,7 +121,7 @@ class BumpPointerSpace : public ContinuousMemMapAllocSpace { } // Go through all of the blocks and visit the continuous objects. - void Walk(ObjectVisitorCallback callback, void* arg) + void Walk(ObjectCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Object alignment within the space. diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc index 24d403d..ae03dd9 100644 --- a/runtime/hprof/hprof.cc +++ b/runtime/hprof/hprof.cc @@ -431,12 +431,8 @@ class Hprof { Runtime::Current()->VisitRoots(RootVisitor, this, false, false); Thread* self = Thread::Current(); { - WriterMutexLock mu(self, *Locks::heap_bitmap_lock_); - Runtime::Current()->GetHeap()->FlushAllocStack(); - } - { ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_); - Runtime::Current()->GetHeap()->GetLiveBitmap()->Walk(HeapBitmapCallback, this); + Runtime::Current()->GetHeap()->VisitObjects(VisitObjectCallback, this); } current_record_.StartNewRecord(body_fp_, HPROF_TAG_HEAP_DUMP_END, HPROF_TIME); current_record_.Flush(); @@ -500,22 +496,23 @@ class Hprof { } private: - static mirror::Object* RootVisitor(mirror::Object* obj, void* arg) + static mirror::Object* RootVisitor(mirror::Object* obj, void* arg, uint32_t thread_id, + RootType root_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { DCHECK(arg != NULL); - reinterpret_cast<Hprof*>(arg)->VisitRoot(obj); + reinterpret_cast<Hprof*>(arg)->VisitRoot(obj, thread_id, root_type); return obj; } - static void HeapBitmapCallback(mirror::Object* obj, void* arg) + static void VisitObjectCallback(mirror::Object* obj, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - CHECK(obj != NULL); - CHECK(arg != NULL); - Hprof* hprof = reinterpret_cast<Hprof*>(arg); - hprof->DumpHeapObject(obj); + DCHECK(obj != NULL); + DCHECK(arg != NULL); + reinterpret_cast<Hprof*>(arg)->DumpHeapObject(obj); } - void VisitRoot(const mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void VisitRoot(const mirror::Object* obj, uint32_t thread_id, RootType type) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); int DumpHeapObject(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -1050,10 +1047,7 @@ int Hprof::DumpHeapObject(mirror::Object* obj) { return 0; } -void Hprof::VisitRoot(const mirror::Object* obj) { - uint32_t threadId = 0; // TODO - /*RootType*/ size_t type = 0; // TODO - +void Hprof::VisitRoot(const mirror::Object* obj, uint32_t thread_id, RootType type) { static const HprofHeapTag xlate[] = { HPROF_ROOT_UNKNOWN, HPROF_ROOT_JNI_GLOBAL, @@ -1071,13 +1065,12 @@ void Hprof::VisitRoot(const mirror::Object* obj) { HPROF_ROOT_VM_INTERNAL, HPROF_ROOT_JNI_MONITOR, }; - CHECK_LT(type, sizeof(xlate) / sizeof(HprofHeapTag)); if (obj == NULL) { return; } gc_scan_state_ = xlate[type]; - gc_thread_serial_number_ = threadId; + gc_thread_serial_number_ = thread_id; MarkRootObject(obj, 0); gc_scan_state_ = 0; gc_thread_serial_number_ = 0; diff --git a/runtime/indirect_reference_table.cc b/runtime/indirect_reference_table.cc index 8194a0d..4a02d74 100644 --- a/runtime/indirect_reference_table.cc +++ b/runtime/indirect_reference_table.cc @@ -309,9 +309,10 @@ bool IndirectReferenceTable::Remove(uint32_t cookie, IndirectRef iref) { return true; } -void IndirectReferenceTable::VisitRoots(RootVisitor* visitor, void* arg) { +void IndirectReferenceTable::VisitRoots(RootCallback* callback, void* arg, uint32_t tid, + RootType root_type) { for (auto ref : *this) { - *ref = visitor(const_cast<mirror::Object*>(*ref), arg); + *ref = callback(const_cast<mirror::Object*>(*ref), arg, tid, root_type); DCHECK(*ref != nullptr); } } diff --git a/runtime/indirect_reference_table.h b/runtime/indirect_reference_table.h index 21e942e..9d2fa35 100644 --- a/runtime/indirect_reference_table.h +++ b/runtime/indirect_reference_table.h @@ -23,8 +23,8 @@ #include <string> #include "base/logging.h" +#include "object_callbacks.h" #include "offsets.h" -#include "root_visitor.h" namespace art { namespace mirror { @@ -307,7 +307,7 @@ class IndirectReferenceTable { return IrtIterator(table_, Capacity(), Capacity()); } - void VisitRoots(RootVisitor* visitor, void* arg); + void VisitRoots(RootCallback* callback, void* arg, uint32_t tid, RootType root_type); uint32_t GetSegmentState() const { return segment_state_.all; diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc index a829e97..5693747 100644 --- a/runtime/intern_table.cc +++ b/runtime/intern_table.cc @@ -43,15 +43,16 @@ void InternTable::DumpForSigQuit(std::ostream& os) const { << weak_interns_.size() << " weak\n"; } -void InternTable::VisitRoots(RootVisitor* visitor, void* arg, +void InternTable::VisitRoots(RootCallback* callback, void* arg, bool only_dirty, bool clean_dirty) { MutexLock mu(Thread::Current(), intern_table_lock_); if (!only_dirty || is_dirty_) { for (auto& strong_intern : strong_interns_) { - strong_intern.second = down_cast<mirror::String*>(visitor(strong_intern.second, arg)); + strong_intern.second = + down_cast<mirror::String*>(callback(strong_intern.second, arg, 0, + kRootInternedString)); DCHECK(strong_intern.second != nullptr); } - if (clean_dirty) { is_dirty_ = false; } @@ -196,15 +197,15 @@ mirror::String* InternTable::InternStrong(const char* utf8_data) { } mirror::String* InternTable::InternStrong(mirror::String* s) { - if (s == NULL) { - return NULL; + if (s == nullptr) { + return nullptr; } return Insert(s, true); } mirror::String* InternTable::InternWeak(mirror::String* s) { - if (s == NULL) { - return NULL; + if (s == nullptr) { + return nullptr; } return Insert(s, false); } @@ -215,11 +216,11 @@ bool InternTable::ContainsWeak(mirror::String* s) { return found == s; } -void InternTable::SweepInternTableWeaks(RootVisitor visitor, void* arg) { +void InternTable::SweepInternTableWeaks(IsMarkedCallback* callback, void* arg) { MutexLock mu(Thread::Current(), intern_table_lock_); for (auto it = weak_interns_.begin(), end = weak_interns_.end(); it != end;) { mirror::Object* object = it->second; - mirror::Object* new_object = visitor(object, arg); + mirror::Object* new_object = callback(object, arg); if (new_object == nullptr) { // TODO: use it = weak_interns_.erase(it) when we get a c++11 stl. weak_interns_.erase(it++); diff --git a/runtime/intern_table.h b/runtime/intern_table.h index eec63c8..9f09fb9 100644 --- a/runtime/intern_table.h +++ b/runtime/intern_table.h @@ -18,7 +18,7 @@ #define ART_RUNTIME_INTERN_TABLE_H_ #include "base/mutex.h" -#include "root_visitor.h" +#include "object_callbacks.h" #include <map> @@ -55,13 +55,13 @@ class InternTable { // Interns a potentially new string in the 'weak' table. (See above.) mirror::String* InternWeak(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void SweepInternTableWeaks(RootVisitor visitor, void* arg); + void SweepInternTableWeaks(IsMarkedCallback* callback, void* arg); bool ContainsWeak(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); size_t Size() const; - void VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, bool clean_dirty); + void VisitRoots(RootCallback* callback, void* arg, bool only_dirty, bool clean_dirty); void DumpForSigQuit(std::ostream& os) const; diff --git a/runtime/intern_table_test.cc b/runtime/intern_table_test.cc index aa2502d..c328245 100644 --- a/runtime/intern_table_test.cc +++ b/runtime/intern_table_test.cc @@ -81,7 +81,7 @@ class TestPredicate { mutable std::vector<const mirror::String*> expected_; }; -mirror::Object* IsMarkedSweepingVisitor(mirror::Object* object, void* arg) { +mirror::Object* IsMarkedSweepingCallback(mirror::Object* object, void* arg) { if (reinterpret_cast<TestPredicate*>(arg)->IsMarked(object)) { return object; } @@ -108,7 +108,7 @@ TEST_F(InternTableTest, SweepInternTableWeaks) { p.Expect(s1.get()); { ReaderMutexLock mu(soa.Self(), *Locks::heap_bitmap_lock_); - t.SweepInternTableWeaks(IsMarkedSweepingVisitor, &p); + t.SweepInternTableWeaks(IsMarkedSweepingCallback, &p); } EXPECT_EQ(2U, t.Size()); diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc index 40ba3e3..49dceb2 100644 --- a/runtime/jdwp/object_registry.cc +++ b/runtime/jdwp/object_registry.cc @@ -206,7 +206,7 @@ void ObjectRegistry::DisposeObject(JDWP::ObjectId id, uint32_t reference_count) } } -void ObjectRegistry::UpdateObjectPointers(RootVisitor visitor, void* arg) { +void ObjectRegistry::UpdateObjectPointers(IsMarkedCallback* callback, void* arg) { MutexLock mu(Thread::Current(), lock_); if (object_to_entry_.empty()) { return; @@ -215,7 +215,7 @@ void ObjectRegistry::UpdateObjectPointers(RootVisitor visitor, void* arg) { for (auto& pair : object_to_entry_) { mirror::Object* new_obj; if (pair.first != nullptr) { - new_obj = visitor(pair.first, arg); + new_obj = callback(pair.first, arg); if (new_obj != nullptr) { new_object_to_entry.insert(std::make_pair(new_obj, pair.second)); } diff --git a/runtime/jdwp/object_registry.h b/runtime/jdwp/object_registry.h index 0190575..3c6cb15 100644 --- a/runtime/jdwp/object_registry.h +++ b/runtime/jdwp/object_registry.h @@ -26,7 +26,7 @@ #include "mirror/class.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" -#include "root_visitor.h" +#include "object_callbacks.h" #include "safe_map.h" namespace art { @@ -85,7 +85,7 @@ class ObjectRegistry { jobject GetJObject(JDWP::ObjectId id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Visit, objects are treated as system weaks. - void UpdateObjectPointers(RootVisitor visitor, void* arg) + void UpdateObjectPointers(IsMarkedCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // We have allow / disallow functionality since we use system weak sweeping logic to update moved diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index deea5f6..030b213 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -523,9 +523,9 @@ class SharedLibrary { return dlsym(handle_, symbol_name.c_str()); } - void VisitRoots(RootVisitor* visitor, void* arg) { + void VisitRoots(RootCallback* visitor, void* arg) { if (class_loader_ != nullptr) { - class_loader_ = visitor(class_loader_, arg); + class_loader_ = visitor(class_loader_, arg, 0, kRootVMInternal); } } @@ -619,9 +619,9 @@ class Libraries { return NULL; } - void VisitRoots(RootVisitor* visitor, void* arg) { + void VisitRoots(RootCallback* callback, void* arg) { for (auto& lib_pair : libraries_) { - lib_pair.second->VisitRoots(visitor, arg); + lib_pair.second->VisitRoots(callback, arg); } } @@ -3373,11 +3373,11 @@ void* JavaVMExt::FindCodeForNativeMethod(ArtMethod* m) { return native_method; } -void JavaVMExt::SweepJniWeakGlobals(RootVisitor visitor, void* arg) { +void JavaVMExt::SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg) { MutexLock mu(Thread::Current(), weak_globals_lock_); for (mirror::Object** entry : weak_globals_) { mirror::Object* obj = *entry; - mirror::Object* new_obj = visitor(obj, arg); + mirror::Object* new_obj = callback(obj, arg); if (new_obj == nullptr) { new_obj = kClearedJniWeakGlobal; } @@ -3385,20 +3385,20 @@ void JavaVMExt::SweepJniWeakGlobals(RootVisitor visitor, void* arg) { } } -void JavaVMExt::VisitRoots(RootVisitor* visitor, void* arg) { +void JavaVMExt::VisitRoots(RootCallback* callback, void* arg) { Thread* self = Thread::Current(); { ReaderMutexLock mu(self, globals_lock); - globals.VisitRoots(visitor, arg); + globals.VisitRoots(callback, arg, 0, kRootJNIGlobal); } { MutexLock mu(self, pins_lock); - pin_table.VisitRoots(visitor, arg); + pin_table.VisitRoots(callback, arg, 0, kRootVMInternal); } { MutexLock mu(self, libraries_lock); // Libraries contains shared libraries which hold a pointer to a class loader. - libraries->VisitRoots(visitor, arg); + libraries->VisitRoots(callback, arg); } // The weak_globals table is visited by the GC itself (because it mutates the table). } diff --git a/runtime/jni_internal.h b/runtime/jni_internal.h index cd3c5cb..26905c7 100644 --- a/runtime/jni_internal.h +++ b/runtime/jni_internal.h @@ -22,8 +22,8 @@ #include "base/macros.h" #include "base/mutex.h" #include "indirect_reference_table.h" +#include "object_callbacks.h" #include "reference_table.h" -#include "root_visitor.h" #include "runtime.h" #include "sirt_ref.h" @@ -91,7 +91,7 @@ class JavaVMExt : public JavaVM { void SetCheckJniEnabled(bool enabled); - void VisitRoots(RootVisitor*, void*); + void VisitRoots(RootCallback* callback, void* arg); void DisallowNewWeakGlobals() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); void AllowNewWeakGlobals() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -99,7 +99,7 @@ class JavaVMExt : public JavaVM { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void DeleteWeakGlobalRef(Thread* self, jweak obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void SweepJniWeakGlobals(RootVisitor visitor, void* arg); + void SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg); mirror::Object* DecodeWeakGlobal(Thread* self, IndirectRef ref); Runtime* runtime; diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index b2725e5..35ea2b3 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -111,9 +111,9 @@ inline Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_c } template<class T> -inline void PrimitiveArray<T>::VisitRoots(RootVisitor* visitor, void* arg) { +inline void PrimitiveArray<T>::VisitRoots(RootCallback* callback, void* arg) { if (array_class_ != nullptr) { - array_class_ = down_cast<Class*>(visitor(array_class_, arg)); + array_class_ = down_cast<Class*>(callback(array_class_, arg, 0, kRootStickyClass)); } } diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h index 04f03c3..2e123ef 100644 --- a/runtime/mirror/array.h +++ b/runtime/mirror/array.h @@ -18,6 +18,7 @@ #define ART_RUNTIME_MIRROR_ARRAY_H_ #include "object.h" +#include "object_callbacks.h" #include "gc/heap.h" #include "thread.h" @@ -182,7 +183,7 @@ class MANAGED PrimitiveArray : public Array { array_class_ = NULL; } - static void VisitRoots(RootVisitor* visitor, void* arg) + static void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc index c3a4efb..29aade9 100644 --- a/runtime/mirror/art_field.cc +++ b/runtime/mirror/art_field.cc @@ -52,10 +52,10 @@ void ArtField::SetOffset(MemberOffset num_bytes) { SetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_), num_bytes.Uint32Value(), false); } -void ArtField::VisitRoots(RootVisitor* visitor, void* arg) { +void ArtField::VisitRoots(RootCallback* callback, void* arg) { if (java_lang_reflect_ArtField_ != nullptr) { java_lang_reflect_ArtField_ = down_cast<mirror::Class*>( - visitor(java_lang_reflect_ArtField_, arg)); + callback(java_lang_reflect_ArtField_, arg, 0, kRootStickyClass)); } } diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h index b33fe4b..716b736 100644 --- a/runtime/mirror/art_field.h +++ b/runtime/mirror/art_field.h @@ -20,6 +20,7 @@ #include "class.h" #include "modifiers.h" #include "object.h" +#include "object_callbacks.h" namespace art { @@ -106,7 +107,7 @@ class MANAGED ArtField : public Object { static void SetClass(Class* java_lang_reflect_ArtField); static void ResetClass(); - static void VisitRoots(RootVisitor* visitor, void* arg) + static void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsVolatile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc index 575ea03..3359d59 100644 --- a/runtime/mirror/art_method.cc +++ b/runtime/mirror/art_method.cc @@ -40,10 +40,10 @@ extern "C" void art_quick_invoke_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, // TODO: get global references for these Class* ArtMethod::java_lang_reflect_ArtMethod_ = NULL; -void ArtMethod::VisitRoots(RootVisitor* visitor, void* arg) { +void ArtMethod::VisitRoots(RootCallback* callback, void* arg) { if (java_lang_reflect_ArtMethod_ != nullptr) { java_lang_reflect_ArtMethod_ = down_cast<mirror::Class*>( - visitor(java_lang_reflect_ArtMethod_, arg)); + callback(java_lang_reflect_ArtMethod_, arg, 0, kRootStickyClass)); } } diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h index bfa7cbe..dfaf063 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -23,7 +23,7 @@ #include "locks.h" #include "modifiers.h" #include "object.h" -#include "root_visitor.h" +#include "object_callbacks.h" namespace art { @@ -404,7 +404,7 @@ class MANAGED ArtMethod : public Object { static void ResetClass(); - static void VisitRoots(RootVisitor* visitor, void* arg) + static void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); protected: diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index 8051c9b..99a35e3 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -50,9 +50,10 @@ void Class::ResetClass() { java_lang_Class_ = NULL; } -void Class::VisitRoots(RootVisitor* visitor, void* arg) { +void Class::VisitRoots(RootCallback* callback, void* arg) { if (java_lang_Class_ != nullptr) { - java_lang_Class_ = down_cast<Class*>(visitor(java_lang_Class_, arg)); + java_lang_Class_ = down_cast<Class*>( + callback(java_lang_Class_, arg, 0, kRootStickyClass)); } } diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index cbec476..82c8264 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -795,7 +795,7 @@ class MANAGED Class : public Object { // Can't call this SetClass or else gets called instead of Object::SetClass in places. static void SetClassClass(Class* java_lang_Class); static void ResetClass(); - static void VisitRoots(RootVisitor* visitor, void* arg) + static void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // When class is verified, set the kAccPreverified flag on each method. diff --git a/runtime/mirror/stack_trace_element.cc b/runtime/mirror/stack_trace_element.cc index a7ebe07..2e33198 100644 --- a/runtime/mirror/stack_trace_element.cc +++ b/runtime/mirror/stack_trace_element.cc @@ -58,9 +58,10 @@ StackTraceElement* StackTraceElement::Alloc(Thread* self, return trace; } -void StackTraceElement::VisitRoots(RootVisitor* visitor, void* arg) { +void StackTraceElement::VisitRoots(RootCallback* callback, void* arg) { if (java_lang_StackTraceElement_ != nullptr) { - java_lang_StackTraceElement_ = down_cast<Class*>(visitor(java_lang_StackTraceElement_, arg)); + java_lang_StackTraceElement_ = down_cast<Class*>( + callback(java_lang_StackTraceElement_, arg, 0, kRootStickyClass)); } } diff --git a/runtime/mirror/stack_trace_element.h b/runtime/mirror/stack_trace_element.h index 73d2673..51817f6 100644 --- a/runtime/mirror/stack_trace_element.h +++ b/runtime/mirror/stack_trace_element.h @@ -57,7 +57,7 @@ class MANAGED StackTraceElement : public Object { static void SetClass(Class* java_lang_StackTraceElement); static void ResetClass(); - static void VisitRoots(RootVisitor* visitor, void* arg) + static void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc index 10ae066..6f4ead9 100644 --- a/runtime/mirror/string.cc +++ b/runtime/mirror/string.cc @@ -280,9 +280,9 @@ int32_t String::CompareTo(String* rhs) { return countDiff; } -void String::VisitRoots(RootVisitor* visitor, void* arg) { +void String::VisitRoots(RootCallback* callback, void* arg) { if (java_lang_String_ != nullptr) { - java_lang_String_ = down_cast<Class*>(visitor(java_lang_String_, arg)); + java_lang_String_ = down_cast<Class*>(callback(java_lang_String_, arg, 0, kRootStickyClass)); } } diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h index 406c5a3..57ec314 100644 --- a/runtime/mirror/string.h +++ b/runtime/mirror/string.h @@ -19,7 +19,7 @@ #include "class.h" #include "gtest/gtest.h" -#include "root_visitor.h" +#include "object_callbacks.h" namespace art { @@ -107,7 +107,7 @@ class MANAGED String : public Object { static void SetClass(Class* java_lang_String); static void ResetClass(); - static void VisitRoots(RootVisitor* visitor, void* arg) + static void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc index 2318b74..a57bd43 100644 --- a/runtime/mirror/throwable.cc +++ b/runtime/mirror/throwable.cc @@ -93,9 +93,10 @@ void Throwable::ResetClass() { java_lang_Throwable_ = NULL; } -void Throwable::VisitRoots(RootVisitor* visitor, void* arg) { +void Throwable::VisitRoots(RootCallback* callback, void* arg) { if (java_lang_Throwable_ != nullptr) { - java_lang_Throwable_ = down_cast<Class*>(visitor(java_lang_Throwable_, arg)); + java_lang_Throwable_ = down_cast<Class*>(callback(java_lang_Throwable_, arg, 0, + kRootStickyClass)); } } diff --git a/runtime/mirror/throwable.h b/runtime/mirror/throwable.h index bc9848a..de71957 100644 --- a/runtime/mirror/throwable.h +++ b/runtime/mirror/throwable.h @@ -18,7 +18,7 @@ #define ART_RUNTIME_MIRROR_THROWABLE_H_ #include "object.h" -#include "root_visitor.h" +#include "object_callbacks.h" #include "string.h" namespace art { @@ -51,7 +51,7 @@ class MANAGED Throwable : public Object { static void SetClass(Class* java_lang_Throwable); static void ResetClass(); - static void VisitRoots(RootVisitor* visitor, void* arg) + static void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 72220e0..85f3a09 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -1067,13 +1067,13 @@ void MonitorList::Add(Monitor* m) { list_.push_front(m); } -void MonitorList::SweepMonitorList(RootVisitor visitor, void* arg) { +void MonitorList::SweepMonitorList(IsMarkedCallback* callback, void* arg) { MutexLock mu(Thread::Current(), monitor_list_lock_); for (auto it = list_.begin(); it != list_.end(); ) { Monitor* m = *it; mirror::Object* obj = m->GetObject(); // The object of a monitor can be null if we have deflated it. - mirror::Object* new_obj = obj != nullptr ? visitor(obj, arg) : nullptr; + mirror::Object* new_obj = obj != nullptr ? callback(obj, arg) : nullptr; if (new_obj == nullptr) { VLOG(monitor) << "freeing monitor " << m << " belonging to unmarked object " << m->GetObject(); diff --git a/runtime/monitor.h b/runtime/monitor.h index 85a8c48..ca95e0b 100644 --- a/runtime/monitor.h +++ b/runtime/monitor.h @@ -26,7 +26,7 @@ #include "atomic.h" #include "base/mutex.h" -#include "root_visitor.h" +#include "object_callbacks.h" #include "sirt_ref.h" #include "thread_state.h" @@ -220,7 +220,8 @@ class MonitorList { void Add(Monitor* m); - void SweepMonitorList(RootVisitor visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void SweepMonitorList(IsMarkedCallback* callback, void* arg) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void DisallowNewMonitors(); void AllowNewMonitors(); diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc index d9baaaf..6482917 100644 --- a/runtime/native/dalvik_system_VMDebug.cc +++ b/runtime/native/dalvik_system_VMDebug.cc @@ -234,9 +234,8 @@ static jlong VMDebug_countInstancesOfClass(JNIEnv* env, jclass, jclass javaClass jboolean countAssignable) { ScopedObjectAccess soa(env); gc::Heap* heap = Runtime::Current()->GetHeap(); - // We only want reachable instances, so do a GC. This also ensures that the alloc stack - // is empty, so the live bitmap is the only place we need to look. Need to do GC before decoding - // any jobjects. + // We only want reachable instances, so do a GC. Heap::VisitObjects visits all of the heap + // objects in the all spaces and the allocation stack. heap->CollectGarbage(false); mirror::Class* c = soa.Decode<mirror::Class*>(javaClass); if (c == nullptr) { diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index e1b5f97..5267069 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -181,11 +181,12 @@ static void VMRuntime_concurrentGC(JNIEnv* env, jobject) { typedef std::map<std::string, mirror::String*> StringTable; -static mirror::Object* PreloadDexCachesStringsVisitor(mirror::Object* root, void* arg) +static mirror::Object* PreloadDexCachesStringsCallback(mirror::Object* root, void* arg, + uint32_t /*thread_id*/, + RootType /*root_type*/) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { StringTable& table = *reinterpret_cast<StringTable*>(arg); mirror::String* string = const_cast<mirror::Object*>(root)->AsString(); - // LOG(INFO) << "VMRuntime.preloadDexCaches interned=" << string->ToModifiedUtf8(); table[string->ToModifiedUtf8()] = string; return root; } @@ -404,7 +405,7 @@ static void VMRuntime_preloadDexCaches(JNIEnv* env, jobject) { // We use a std::map to avoid heap allocating StringObjects to lookup in gDvm.literalStrings StringTable strings; if (kPreloadDexCachesStrings) { - runtime->GetInternTable()->VisitRoots(PreloadDexCachesStringsVisitor, &strings, false, false); + runtime->GetInternTable()->VisitRoots(PreloadDexCachesStringsCallback, &strings, false, false); } const std::vector<const DexFile*>& boot_class_path = linker->GetBootClassPath(); diff --git a/runtime/object_callbacks.h b/runtime/object_callbacks.h new file mode 100644 index 0000000..8e3c529 --- /dev/null +++ b/runtime/object_callbacks.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_OBJECT_CALLBACKS_H_ +#define ART_RUNTIME_OBJECT_CALLBACKS_H_ + +// For uint32_t. +#include <stdint.h> +// For size_t. +#include <stdlib.h> + +namespace art { +namespace mirror { +class Object; +} // namespace mirror +class StackVisitor; + +enum RootType { + kRootUnknown = 0, + kRootJNIGlobal, + kRootJNILocal, + kRootJavaFrame, + kRootNativeStack, + kRootStickyClass, + kRootThreadBlock, + kRootMonitorUsed, + kRootThreadObject, + kRootInternedString, + kRootDebugger, + kRootVMInternal, + kRootJNIMonitor, +}; + +// Returns the new address of the object, returns root if it has not moved. tid and root_type are +// only used by hprof. +typedef mirror::Object* (RootCallback)(mirror::Object* root, void* arg, uint32_t thread_id, + RootType root_type) __attribute__((warn_unused_result)); +// A callback for visiting an object in the heap. +typedef void (ObjectCallback)(mirror::Object* obj, void* arg); +// A callback used for marking an object, returns the new address of the object if the object moved. +typedef mirror::Object* (MarkObjectCallback)(mirror::Object* obj, void* arg) + __attribute__((warn_unused_result)); +// A callback for verifying roots. +typedef void (VerifyRootCallback)(const mirror::Object* root, void* arg, size_t vreg, + const StackVisitor* visitor); +// A callback for testing if an object is marked, returns nullptr if not marked, otherwise the new +// address the object (if the object didn't move, returns the object input parameter). +typedef mirror::Object* (IsMarkedCallback)(mirror::Object* object, void* arg) + __attribute__((warn_unused_result)); + +} // namespace art + +#endif // ART_RUNTIME_OBJECT_CALLBACKS_H_ diff --git a/runtime/reference_table.cc b/runtime/reference_table.cc index b5ef735..a9b17e0 100644 --- a/runtime/reference_table.cc +++ b/runtime/reference_table.cc @@ -231,9 +231,10 @@ void ReferenceTable::Dump(std::ostream& os, const Table& entries) { DumpSummaryLine(os, sorted_entries.back(), GetElementCount(sorted_entries.back()), identical, equiv); } -void ReferenceTable::VisitRoots(RootVisitor* visitor, void* arg) { +void ReferenceTable::VisitRoots(RootCallback* visitor, void* arg, uint32_t tid, + RootType root_type) { for (auto& ref : entries_) { - ref = visitor(ref, arg); + ref = visitor(ref, arg, tid, root_type); } } diff --git a/runtime/reference_table.h b/runtime/reference_table.h index 37b3172..c9f5bc5 100644 --- a/runtime/reference_table.h +++ b/runtime/reference_table.h @@ -22,8 +22,8 @@ #include <string> #include <vector> +#include "object_callbacks.h" #include "locks.h" -#include "root_visitor.h" namespace art { namespace mirror { @@ -47,7 +47,7 @@ class ReferenceTable { void Dump(std::ostream& os) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VisitRoots(RootVisitor* visitor, void* arg); + void VisitRoots(RootCallback* visitor, void* arg, uint32_t tid, RootType root_type); private: typedef std::vector<mirror::Object*> Table; diff --git a/runtime/root_visitor.h b/runtime/root_visitor.h deleted file mode 100644 index 78c30ff..0000000 --- a/runtime/root_visitor.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_RUNTIME_ROOT_VISITOR_H_ -#define ART_RUNTIME_ROOT_VISITOR_H_ - -// For size_t. -#include <stdlib.h> - -namespace art { -namespace mirror { -class Object; -} // namespace mirror -class StackVisitor; - -// Returns the new address of the object, returns root if it has not moved. -typedef mirror::Object* (RootVisitor)(mirror::Object* root, void* arg) - __attribute__((warn_unused_result)); -typedef void (VerifyRootVisitor)(const mirror::Object* root, void* arg, size_t vreg, - const StackVisitor* visitor); -typedef bool (IsMarkedTester)(const mirror::Object* object, void* arg); -typedef void (ObjectVisitorCallback)(mirror::Object* obj, void* arg); - -} // namespace art - -#endif // ART_RUNTIME_ROOT_VISITOR_H_ diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 09d05d1..9193be5 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -375,7 +375,7 @@ static double ParseDoubleOrDie(const std::string& option, char after_char, doubl return value; } -void Runtime::SweepSystemWeaks(RootVisitor* visitor, void* arg) { +void Runtime::SweepSystemWeaks(IsMarkedCallback* visitor, void* arg) { GetInternTable()->SweepInternTableWeaks(visitor, arg); GetMonitorList()->SweepMonitorList(visitor, arg); GetJavaVM()->SweepJniWeakGlobals(visitor, arg); @@ -1301,66 +1301,69 @@ void Runtime::DetachCurrentThread() { return pre_allocated_OutOfMemoryError_; } -void Runtime::VisitConcurrentRoots(RootVisitor* visitor, void* arg, bool only_dirty, +void Runtime::VisitConcurrentRoots(RootCallback* callback, void* arg, bool only_dirty, bool clean_dirty) { - intern_table_->VisitRoots(visitor, arg, only_dirty, clean_dirty); - class_linker_->VisitRoots(visitor, arg, only_dirty, clean_dirty); + intern_table_->VisitRoots(callback, arg, only_dirty, clean_dirty); + class_linker_->VisitRoots(callback, arg, only_dirty, clean_dirty); } -void Runtime::VisitNonThreadRoots(RootVisitor* visitor, void* arg) { +void Runtime::VisitNonThreadRoots(RootCallback* callback, void* arg) { // Visit the classes held as static in mirror classes. - mirror::ArtField::VisitRoots(visitor, arg); - mirror::ArtMethod::VisitRoots(visitor, arg); - mirror::Class::VisitRoots(visitor, arg); - mirror::StackTraceElement::VisitRoots(visitor, arg); - mirror::String::VisitRoots(visitor, arg); - mirror::Throwable::VisitRoots(visitor, arg); + mirror::ArtField::VisitRoots(callback, arg); + mirror::ArtMethod::VisitRoots(callback, arg); + mirror::Class::VisitRoots(callback, arg); + mirror::StackTraceElement::VisitRoots(callback, arg); + mirror::String::VisitRoots(callback, arg); + mirror::Throwable::VisitRoots(callback, arg); // Visit all the primitive array types classes. - mirror::PrimitiveArray<uint8_t>::VisitRoots(visitor, arg); // BooleanArray - mirror::PrimitiveArray<int8_t>::VisitRoots(visitor, arg); // ByteArray - mirror::PrimitiveArray<uint16_t>::VisitRoots(visitor, arg); // CharArray - mirror::PrimitiveArray<double>::VisitRoots(visitor, arg); // DoubleArray - mirror::PrimitiveArray<float>::VisitRoots(visitor, arg); // FloatArray - mirror::PrimitiveArray<int32_t>::VisitRoots(visitor, arg); // IntArray - mirror::PrimitiveArray<int64_t>::VisitRoots(visitor, arg); // LongArray - mirror::PrimitiveArray<int16_t>::VisitRoots(visitor, arg); // ShortArray - java_vm_->VisitRoots(visitor, arg); + mirror::PrimitiveArray<uint8_t>::VisitRoots(callback, arg); // BooleanArray + mirror::PrimitiveArray<int8_t>::VisitRoots(callback, arg); // ByteArray + mirror::PrimitiveArray<uint16_t>::VisitRoots(callback, arg); // CharArray + mirror::PrimitiveArray<double>::VisitRoots(callback, arg); // DoubleArray + mirror::PrimitiveArray<float>::VisitRoots(callback, arg); // FloatArray + mirror::PrimitiveArray<int32_t>::VisitRoots(callback, arg); // IntArray + mirror::PrimitiveArray<int64_t>::VisitRoots(callback, arg); // LongArray + mirror::PrimitiveArray<int16_t>::VisitRoots(callback, arg); // ShortArray + java_vm_->VisitRoots(callback, arg); if (pre_allocated_OutOfMemoryError_ != nullptr) { pre_allocated_OutOfMemoryError_ = down_cast<mirror::Throwable*>( - visitor(pre_allocated_OutOfMemoryError_, arg)); + callback(pre_allocated_OutOfMemoryError_, arg, 0, kRootVMInternal)); DCHECK(pre_allocated_OutOfMemoryError_ != nullptr); } - resolution_method_ = down_cast<mirror::ArtMethod*>(visitor(resolution_method_, arg)); + resolution_method_ = down_cast<mirror::ArtMethod*>(callback(resolution_method_, arg, 0, + kRootVMInternal)); DCHECK(resolution_method_ != nullptr); if (HasImtConflictMethod()) { - imt_conflict_method_ = down_cast<mirror::ArtMethod*>(visitor(imt_conflict_method_, arg)); + imt_conflict_method_ = down_cast<mirror::ArtMethod*>(callback(imt_conflict_method_, arg, 0, + kRootVMInternal)); } if (HasDefaultImt()) { - default_imt_ = down_cast<mirror::ObjectArray<mirror::ArtMethod>*>(visitor(default_imt_, arg)); + default_imt_ = down_cast<mirror::ObjectArray<mirror::ArtMethod>*>(callback(default_imt_, arg, + 0, kRootVMInternal)); } for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { if (callee_save_methods_[i] != nullptr) { callee_save_methods_[i] = down_cast<mirror::ArtMethod*>( - visitor(callee_save_methods_[i], arg)); + callback(callee_save_methods_[i], arg, 0, kRootVMInternal)); } } { MutexLock mu(Thread::Current(), method_verifiers_lock_); for (verifier::MethodVerifier* verifier : method_verifiers_) { - verifier->VisitRoots(visitor, arg); + verifier->VisitRoots(callback, arg); } } } -void Runtime::VisitNonConcurrentRoots(RootVisitor* visitor, void* arg) { - thread_list_->VisitRoots(visitor, arg); - VisitNonThreadRoots(visitor, arg); +void Runtime::VisitNonConcurrentRoots(RootCallback* callback, void* arg) { + thread_list_->VisitRoots(callback, arg); + VisitNonThreadRoots(callback, arg); } -void Runtime::VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, bool clean_dirty) { - VisitConcurrentRoots(visitor, arg, only_dirty, clean_dirty); - VisitNonConcurrentRoots(visitor, arg); +void Runtime::VisitRoots(RootCallback* callback, void* arg, bool only_dirty, bool clean_dirty) { + VisitConcurrentRoots(callback, arg, only_dirty, clean_dirty); + VisitNonConcurrentRoots(callback, arg); } mirror::ObjectArray<mirror::ArtMethod>* Runtime::CreateDefaultImt(ClassLinker* cl) { diff --git a/runtime/runtime.h b/runtime/runtime.h index 896a18b..07f3d7d 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -34,7 +34,7 @@ #include "instrumentation.h" #include "jobject_comparator.h" #include "locks.h" -#include "root_visitor.h" +#include "object_callbacks.h" #include "runtime_stats.h" #include "safe_map.h" @@ -341,24 +341,24 @@ class Runtime { // Visit all the roots. If only_dirty is true then non-dirty roots won't be visited. If // clean_dirty is true then dirty roots will be marked as non-dirty after visiting. - void VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, bool clean_dirty) + void VisitRoots(RootCallback* visitor, void* arg, bool only_dirty, bool clean_dirty) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Visit all of the roots we can do safely do concurrently. - void VisitConcurrentRoots(RootVisitor* visitor, void* arg, bool only_dirty, bool clean_dirty) + void VisitConcurrentRoots(RootCallback* visitor, void* arg, bool only_dirty, bool clean_dirty) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Visit all of the non thread roots, we can do this with mutators unpaused. - void VisitNonThreadRoots(RootVisitor* visitor, void* arg) + void VisitNonThreadRoots(RootCallback* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Visit all other roots which must be done with mutators suspended. - void VisitNonConcurrentRoots(RootVisitor* visitor, void* arg) + void VisitNonConcurrentRoots(RootCallback* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Sweep system weaks, the system weak is deleted if the visitor return nullptr. Otherwise, the // system weak is updated to be the visitor's returned value. - void SweepSystemWeaks(RootVisitor* visitor, void* arg) + void SweepSystemWeaks(IsMarkedCallback* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Returns a special method that calls into a trampoline for runtime method resolution diff --git a/runtime/thread.cc b/runtime/thread.cc index c649765..b5320ca 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -992,7 +992,8 @@ void Thread::AssertNoPendingException() const { } } -static mirror::Object* MonitorExitVisitor(mirror::Object* object, void* arg) +static mirror::Object* MonitorExitVisitor(mirror::Object* object, void* arg, uint32_t /*thread_id*/, + RootType /*root_type*/) NO_THREAD_SAFETY_ANALYSIS { Thread* self = reinterpret_cast<Thread*>(arg); mirror::Object* entered_monitor = object; @@ -1034,7 +1035,7 @@ void Thread::Destroy() { // On thread detach, all monitors entered with JNI MonitorEnter are automatically exited. if (jni_env_ != nullptr) { - jni_env_->monitors.VisitRoots(MonitorExitVisitor, self); + jni_env_->monitors.VisitRoots(MonitorExitVisitor, self, 0, kRootVMInternal); } } @@ -1144,16 +1145,17 @@ bool Thread::SirtContains(jobject obj) const { return managed_stack_.ShadowFramesContain(sirt_entry); } -void Thread::SirtVisitRoots(RootVisitor* visitor, void* arg) { +void Thread::SirtVisitRoots(RootCallback* visitor, void* arg) { + uint32_t tid = GetTid(); for (StackIndirectReferenceTable* cur = top_sirt_; cur; cur = cur->GetLink()) { size_t num_refs = cur->NumberOfReferences(); for (size_t j = 0; j < num_refs; ++j) { mirror::Object* object = cur->GetReference(j); if (object != nullptr) { - const mirror::Object* new_obj = visitor(object, arg); + mirror::Object* new_obj = visitor(object, arg, tid, kRootNativeStack); DCHECK(new_obj != nullptr); if (new_obj != object) { - cur->SetReference(j, const_cast<mirror::Object*>(new_obj)); + cur->SetReference(j, new_obj); } } } @@ -1954,31 +1956,17 @@ class ReferenceMapVisitor : public StackVisitor { class RootCallbackVisitor { public: - RootCallbackVisitor(RootVisitor* visitor, void* arg) : visitor_(visitor), arg_(arg) {} + RootCallbackVisitor(RootCallback* callback, void* arg, uint32_t tid) + : callback_(callback), arg_(arg), tid_(tid) {} mirror::Object* operator()(mirror::Object* obj, size_t, const StackVisitor*) const { - return visitor_(obj, arg_); + return callback_(obj, arg_, tid_, kRootJavaFrame); } private: - RootVisitor* visitor_; - void* arg_; -}; - -class VerifyCallbackVisitor { - public: - VerifyCallbackVisitor(VerifyRootVisitor* visitor, void* arg) - : visitor_(visitor), - arg_(arg) { - } - - void operator()(const mirror::Object* obj, size_t vreg, const StackVisitor* visitor) const { - visitor_(obj, arg_, vreg, visitor); - } - - private: - VerifyRootVisitor* const visitor_; + RootCallback* const callback_; void* const arg_; + const uint32_t tid_; }; void Thread::SetClassLoaderOverride(mirror::ClassLoader* class_loader_override) { @@ -1988,39 +1976,42 @@ void Thread::SetClassLoaderOverride(mirror::ClassLoader* class_loader_override) class_loader_override_ = class_loader_override; } -void Thread::VisitRoots(RootVisitor* visitor, void* arg) { +void Thread::VisitRoots(RootCallback* visitor, void* arg) { + uint32_t thread_id = GetThreadId(); if (opeer_ != nullptr) { - opeer_ = visitor(opeer_, arg); + opeer_ = visitor(opeer_, arg, thread_id, kRootThreadObject); } if (exception_ != nullptr) { - exception_ = down_cast<mirror::Throwable*>(visitor(exception_, arg)); + exception_ = down_cast<mirror::Throwable*>(visitor(exception_, arg, thread_id, + kRootNativeStack)); } throw_location_.VisitRoots(visitor, arg); if (class_loader_override_ != nullptr) { - class_loader_override_ = down_cast<mirror::ClassLoader*>(visitor(class_loader_override_, arg)); + class_loader_override_ = + down_cast<mirror::ClassLoader*>(visitor(class_loader_override_, arg, thread_id, + kRootNativeStack)); } - jni_env_->locals.VisitRoots(visitor, arg); - jni_env_->monitors.VisitRoots(visitor, arg); - + jni_env_->locals.VisitRoots(visitor, arg, thread_id, kRootJNILocal); + jni_env_->monitors.VisitRoots(visitor, arg, thread_id, kRootJNIMonitor); SirtVisitRoots(visitor, arg); - // Visit roots on this thread's stack Context* context = GetLongJumpContext(); - RootCallbackVisitor visitorToCallback(visitor, arg); + RootCallbackVisitor visitorToCallback(visitor, arg, thread_id); ReferenceMapVisitor<RootCallbackVisitor> mapper(this, context, visitorToCallback); mapper.WalkStack(); ReleaseLongJumpContext(context); - for (instrumentation::InstrumentationStackFrame& frame : *GetInstrumentationStack()) { if (frame.this_object_ != nullptr) { - frame.this_object_ = visitor(frame.this_object_, arg); + frame.this_object_ = visitor(frame.this_object_, arg, thread_id, kRootJavaFrame); } DCHECK(frame.method_ != nullptr); - frame.method_ = down_cast<mirror::ArtMethod*>(visitor(frame.method_, arg)); + frame.method_ = down_cast<mirror::ArtMethod*>(visitor(frame.method_, arg, thread_id, + kRootJavaFrame)); } } -static mirror::Object* VerifyRoot(mirror::Object* root, void* arg) { +static mirror::Object* VerifyRoot(mirror::Object* root, void* arg, uint32_t /*thread_id*/, + RootType /*root_type*/) { DCHECK(root != nullptr); DCHECK(arg != nullptr); reinterpret_cast<gc::Heap*>(arg)->VerifyObject(root); @@ -2029,7 +2020,7 @@ static mirror::Object* VerifyRoot(mirror::Object* root, void* arg) { void Thread::VerifyStackImpl() { UniquePtr<Context> context(Context::Create()); - RootCallbackVisitor visitorToCallback(VerifyRoot, Runtime::Current()->GetHeap()); + RootCallbackVisitor visitorToCallback(VerifyRoot, Runtime::Current()->GetHeap(), GetTid()); ReferenceMapVisitor<RootCallbackVisitor> mapper(this, context.get(), visitorToCallback); mapper.WalkStack(); } diff --git a/runtime/thread.h b/runtime/thread.h index b7f8bb0..daffc92 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -31,8 +31,8 @@ #include "globals.h" #include "jvalue.h" #include "locks.h" +#include "object_callbacks.h" #include "offsets.h" -#include "root_visitor.h" #include "runtime_stats.h" #include "stack.h" #include "stack_indirect_reference_table.h" @@ -389,7 +389,7 @@ class PACKED(4) Thread { static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal, jobjectArray output_array = NULL, int* stack_depth = NULL); - void VisitRoots(RootVisitor* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void VisitRoots(RootCallback* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void VerifyStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -503,7 +503,8 @@ class PACKED(4) Thread { // Is the given obj in this thread's stack indirect reference table? bool SirtContains(jobject obj) const; - void SirtVisitRoots(RootVisitor* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void SirtVisitRoots(RootCallback* visitor, void* arg) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void PushSirt(StackIndirectReferenceTable* sirt) { sirt->SetLink(top_sirt_); diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc index 8bf099b..25f692d 100644 --- a/runtime/thread_list.cc +++ b/runtime/thread_list.cc @@ -756,28 +756,30 @@ void ThreadList::ForEach(void (*callback)(Thread*, void*), void* context) { } } -void ThreadList::VisitRoots(RootVisitor* visitor, void* arg) const { +void ThreadList::VisitRoots(RootCallback* callback, void* arg) const { MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); for (const auto& thread : list_) { - thread->VisitRoots(visitor, arg); + thread->VisitRoots(callback, arg); } } -struct VerifyRootWrapperArg { - VerifyRootVisitor* visitor; - void* arg; +class VerifyRootWrapperArg { + public: + VerifyRootWrapperArg(VerifyRootCallback* callback, void* arg) : callback_(callback), arg_(arg) { + } + VerifyRootCallback* const callback_; + void* const arg_; }; -static mirror::Object* VerifyRootWrapperCallback(mirror::Object* root, void* arg) { +static mirror::Object* VerifyRootWrapperCallback(mirror::Object* root, void* arg, + uint32_t /*thread_id*/, RootType /*root_type*/) { VerifyRootWrapperArg* wrapperArg = reinterpret_cast<VerifyRootWrapperArg*>(arg); - wrapperArg->visitor(root, wrapperArg->arg, 0, NULL); + wrapperArg->callback_(root, wrapperArg->arg_, 0, NULL); return root; } -void ThreadList::VerifyRoots(VerifyRootVisitor* visitor, void* arg) const { - VerifyRootWrapperArg wrapper; - wrapper.visitor = visitor; - wrapper.arg = arg; +void ThreadList::VerifyRoots(VerifyRootCallback* callback, void* arg) const { + VerifyRootWrapperArg wrapper(callback, arg); MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); for (const auto& thread : list_) { thread->VisitRoots(VerifyRootWrapperCallback, &wrapper); diff --git a/runtime/thread_list.h b/runtime/thread_list.h index 45994ae..e98aed9 100644 --- a/runtime/thread_list.h +++ b/runtime/thread_list.h @@ -19,7 +19,7 @@ #include "base/mutex.h" #include "jni.h" -#include "root_visitor.h" +#include "object_callbacks.h" #include <bitset> #include <list> @@ -113,10 +113,10 @@ class ThreadList { LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); - void VisitRoots(RootVisitor* visitor, void* arg) const + void VisitRoots(RootCallback* callback, void* arg) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VerifyRoots(VerifyRootVisitor* visitor, void* arg) const + void VerifyRoots(VerifyRootCallback* callback, void* arg) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Return a copy of the thread list. diff --git a/runtime/throw_location.cc b/runtime/throw_location.cc index 1cc3e74..2a1faff 100644 --- a/runtime/throw_location.cc +++ b/runtime/throw_location.cc @@ -33,13 +33,13 @@ std::string ThrowLocation::Dump() const { } } -void ThrowLocation::VisitRoots(RootVisitor* visitor, void* arg) { +void ThrowLocation::VisitRoots(RootCallback* visitor, void* arg) { if (this_object_ != nullptr) { - this_object_ = visitor(this_object_, arg); + this_object_ = visitor(this_object_, arg, 0, kRootVMInternal); DCHECK(this_object_ != nullptr); } if (method_ != nullptr) { - method_ = down_cast<mirror::ArtMethod*>(visitor(method_, arg)); + method_ = down_cast<mirror::ArtMethod*>(visitor(method_, arg, 0, kRootVMInternal)); DCHECK(method_ != nullptr); } } diff --git a/runtime/throw_location.h b/runtime/throw_location.h index 5da446e..f30aa4e 100644 --- a/runtime/throw_location.h +++ b/runtime/throw_location.h @@ -17,8 +17,8 @@ #ifndef ART_RUNTIME_THROW_LOCATION_H_ #define ART_RUNTIME_THROW_LOCATION_H_ +#include "object_callbacks.h" #include "base/macros.h" -#include "root_visitor.h" #include <stdint.h> #include <string> @@ -62,7 +62,7 @@ class PACKED(4) ThrowLocation { std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VisitRoots(RootVisitor* visitor, void* arg); + void VisitRoots(RootCallback* visitor, void* arg); private: // The 'this' reference of the throwing method. diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 30be36c..ab943a6 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -3983,8 +3983,8 @@ void MethodVerifier::Shutdown() { verifier::RegTypeCache::ShutDown(); } -void MethodVerifier::VisitRoots(RootVisitor* visitor, void* arg) { - reg_types_.VisitRoots(visitor, arg); +void MethodVerifier::VisitRoots(RootCallback* callback, void* arg) { + reg_types_.VisitRoots(callback, arg); } } // namespace verifier diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index 7c75c9c..031cfec 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -220,7 +220,7 @@ class MethodVerifier { // Describe VRegs at the given dex pc. std::vector<int32_t> DescribeVRegs(uint32_t dex_pc); - void VisitRoots(RootVisitor* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Accessors used by the compiler via CompilerCallback const DexFile::CodeItem* CodeItem() const; diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc index f394bce..e56e670 100644 --- a/runtime/verifier/reg_type.cc +++ b/runtime/verifier/reg_type.cc @@ -969,9 +969,9 @@ void RegType::CheckInvariants() const { } } -void RegType::VisitRoots(RootVisitor* visitor, void* arg) { +void RegType::VisitRoots(RootCallback* callback, void* arg) { if (klass_ != nullptr) { - klass_ = down_cast<mirror::Class*>(visitor(klass_, arg)); + klass_ = down_cast<mirror::Class*>(callback(klass_, arg, 0, kRootUnknown)); } } diff --git a/runtime/verifier/reg_type.h b/runtime/verifier/reg_type.h index 3818375..a23b8c4 100644 --- a/runtime/verifier/reg_type.h +++ b/runtime/verifier/reg_type.h @@ -19,8 +19,8 @@ #include "base/macros.h" #include "globals.h" +#include "object_callbacks.h" #include "primitive.h" -#include "root_visitor.h" #include "jni.h" @@ -270,7 +270,7 @@ class RegType { virtual ~RegType() {} - void VisitRoots(RootVisitor* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); protected: RegType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id) diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc index c8a03d6..5e894ed 100644 --- a/runtime/verifier/reg_type_cache.cc +++ b/runtime/verifier/reg_type_cache.cc @@ -573,9 +573,9 @@ void RegTypeCache::Dump(std::ostream& os) { } } -void RegTypeCache::VisitRoots(RootVisitor* visitor, void* arg) { +void RegTypeCache::VisitRoots(RootCallback* callback, void* arg) { for (RegType* entry : entries_) { - entry->VisitRoots(visitor, arg); + entry->VisitRoots(callback, arg); } } diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h index 41bc8c9..4cc7e61 100644 --- a/runtime/verifier/reg_type_cache.h +++ b/runtime/verifier/reg_type_cache.h @@ -20,8 +20,8 @@ #include "base/casts.h" #include "base/macros.h" #include "base/stl_util.h" +#include "object_callbacks.h" #include "reg_type.h" -#include "root_visitor.h" #include "runtime.h" #include <stdint.h> @@ -146,7 +146,7 @@ class RegTypeCache { void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); const RegType& RegTypeFromPrimitiveType(Primitive::Type) const; - void VisitRoots(RootVisitor* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); private: void FillPrimitiveAndSmallConstantTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); |