diff options
42 files changed, 203 insertions, 224 deletions
diff --git a/runtime/Android.mk b/runtime/Android.mk index 0f5050b545..84f2248ef1 100644 --- a/runtime/Android.mk +++ b/runtime/Android.mk @@ -298,6 +298,7 @@ LIBART_ENUM_OPERATOR_OUT_HEADER_FILES := \ base/unix_file/fd_file.h \ dex_file.h \ dex_instruction.h \ + gc_root.h \ gc/collector/gc_type.h \ gc/collector_type.h \ gc/space/space.h \ @@ -310,7 +311,6 @@ LIBART_ENUM_OPERATOR_OUT_HEADER_FILES := \ lock_word.h \ mirror/class.h \ oat.h \ - object_callbacks.h \ quick/inline_method_analyser.h \ thread.h \ thread_state.h \ diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 702e9014eb..0afd174076 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1706,23 +1706,23 @@ void ClassLinker::VisitClassRoots(RootCallback* callback, void* arg, VisitRootFl WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); if ((flags & kVisitRootFlagAllRoots) != 0) { for (GcRoot<mirror::Class>& root : class_table_) { - root.VisitRoot(callback, arg, 0, kRootStickyClass); + root.VisitRoot(callback, arg, RootInfo(kRootStickyClass)); } for (GcRoot<mirror::Class>& root : pre_zygote_class_table_) { - root.VisitRoot(callback, arg, 0, kRootStickyClass); + root.VisitRoot(callback, arg, RootInfo(kRootStickyClass)); } } else if ((flags & kVisitRootFlagNewRoots) != 0) { for (auto& root : new_class_roots_) { mirror::Class* old_ref = root.Read<kWithoutReadBarrier>(); - root.VisitRoot(callback, arg, 0, kRootStickyClass); + root.VisitRoot(callback, arg, RootInfo(kRootStickyClass)); mirror::Class* new_ref = root.Read<kWithoutReadBarrier>(); if (UNLIKELY(new_ref != old_ref)) { // Uh ohes, GC moved a root in the log. Need to search the class_table and update the // corresponding object. This is slow, but luckily for us, this may only happen with a // concurrent moving GC. auto it = class_table_.Find(GcRoot<mirror::Class>(old_ref)); - class_table_.Erase(it); - class_table_.Insert(GcRoot<mirror::Class>(new_ref)); + DCHECK(it != class_table_.end()); + *it = GcRoot<mirror::Class>(new_ref); } } } @@ -1742,17 +1742,17 @@ void ClassLinker::VisitClassRoots(RootCallback* callback, void* arg, VisitRootFl // reinit references to when reinitializing a ClassLinker from a // mapped image. void ClassLinker::VisitRoots(RootCallback* callback, void* arg, VisitRootFlags flags) { - class_roots_.VisitRoot(callback, arg, 0, kRootVMInternal); + class_roots_.VisitRoot(callback, arg, RootInfo(kRootVMInternal)); Thread* self = Thread::Current(); { ReaderMutexLock mu(self, dex_lock_); if ((flags & kVisitRootFlagAllRoots) != 0) { for (GcRoot<mirror::DexCache>& dex_cache : dex_caches_) { - dex_cache.VisitRoot(callback, arg, 0, kRootVMInternal); + dex_cache.VisitRoot(callback, arg, RootInfo(kRootVMInternal)); } } else if ((flags & kVisitRootFlagNewRoots) != 0) { for (size_t index : new_dex_cache_roots_) { - dex_caches_[index].VisitRoot(callback, arg, 0, kRootVMInternal); + dex_caches_[index].VisitRoot(callback, arg, RootInfo(kRootVMInternal)); } } if ((flags & kVisitRootFlagClearRootLog) != 0) { @@ -1765,12 +1765,10 @@ void ClassLinker::VisitRoots(RootCallback* callback, void* arg, VisitRootFlags f } } VisitClassRoots(callback, arg, flags); - array_iftable_.VisitRoot(callback, arg, 0, kRootVMInternal); + array_iftable_.VisitRoot(callback, arg, RootInfo(kRootVMInternal)); DCHECK(!array_iftable_.IsNull()); for (size_t i = 0; i < kFindArrayCacheSize; ++i) { - if (!find_array_class_cache_[i].IsNull()) { - find_array_class_cache_[i].VisitRoot(callback, arg, 0, kRootVMInternal); - } + find_array_class_cache_[i].VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal)); } } diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 928780ad7e..7ca0927e83 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -364,7 +364,7 @@ class ClassLinkerTest : public CommonRuntimeTest { } } - static void TestRootVisitor(mirror::Object** root, void*, uint32_t, RootType) { + static void TestRootVisitor(mirror::Object** root, void*, const RootInfo&) { EXPECT_TRUE(*root != NULL); } }; diff --git a/runtime/debugger.cc b/runtime/debugger.cc index c2745ff2c6..5db9d41dbf 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -341,19 +341,18 @@ uint32_t Dbg::instrumentation_events_ = 0; // Breakpoints. static std::vector<Breakpoint> gBreakpoints GUARDED_BY(Locks::breakpoint_lock_); -void DebugInvokeReq::VisitRoots(RootCallback* callback, void* arg, uint32_t tid, - RootType root_type) { +void DebugInvokeReq::VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) { if (receiver != nullptr) { - callback(&receiver, arg, tid, root_type); + callback(&receiver, arg, root_info); } if (thread != nullptr) { - callback(&thread, arg, tid, root_type); + callback(&thread, arg, root_info); } if (klass != nullptr) { - callback(reinterpret_cast<mirror::Object**>(&klass), arg, tid, root_type); + callback(reinterpret_cast<mirror::Object**>(&klass), arg, root_info); } if (method != nullptr) { - callback(reinterpret_cast<mirror::Object**>(&method), arg, tid, root_type); + callback(reinterpret_cast<mirror::Object**>(&method), arg, root_info); } } @@ -365,10 +364,9 @@ void DebugInvokeReq::Clear() { method = nullptr; } -void SingleStepControl::VisitRoots(RootCallback* callback, void* arg, uint32_t tid, - RootType root_type) { +void SingleStepControl::VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) { if (method != nullptr) { - callback(reinterpret_cast<mirror::Object**>(&method), arg, tid, root_type); + callback(reinterpret_cast<mirror::Object**>(&method), arg, root_info); } } diff --git a/runtime/debugger.h b/runtime/debugger.h index 3fdd823f72..ac9616e987 100644 --- a/runtime/debugger.h +++ b/runtime/debugger.h @@ -28,6 +28,7 @@ #include <string> #include <vector> +#include "gc_root.h" #include "jdwp/jdwp.h" #include "jni.h" #include "jvalue.h" @@ -87,7 +88,7 @@ struct DebugInvokeReq { Mutex lock DEFAULT_MUTEX_ACQUIRED_AFTER; ConditionVariable cond GUARDED_BY(lock); - void VisitRoots(RootCallback* callback, void* arg, uint32_t tid, RootType root_type) + void VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void Clear(); @@ -122,7 +123,7 @@ struct SingleStepControl { // single-step depth. int stack_depth; - void VisitRoots(RootCallback* callback, void* arg, uint32_t tid, RootType root_type) + void VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool ContainsDexPc(uint32_t dex_pc) const; diff --git a/runtime/gc/collector/mark_compact.cc b/runtime/gc/collector/mark_compact.cc index 40448524c6..c63fec4afa 100644 --- a/runtime/gc/collector/mark_compact.cc +++ b/runtime/gc/collector/mark_compact.cc @@ -300,22 +300,20 @@ mirror::Object* MarkCompact::MarkObjectCallback(mirror::Object* root, void* arg) } void MarkCompact::MarkHeapReferenceCallback(mirror::HeapReference<mirror::Object>* obj_ptr, - void* arg) { + void* arg) { reinterpret_cast<MarkCompact*>(arg)->MarkObject(obj_ptr->AsMirrorPtr()); } void MarkCompact::DelayReferenceReferentCallback(mirror::Class* klass, mirror::Reference* ref, - void* arg) { + void* arg) { reinterpret_cast<MarkCompact*>(arg)->DelayReferenceReferent(klass, ref); } -void MarkCompact::MarkRootCallback(Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) { +void MarkCompact::MarkRootCallback(Object** root, void* arg, const RootInfo& /*root_info*/) { reinterpret_cast<MarkCompact*>(arg)->MarkObject(*root); } -void MarkCompact::UpdateRootCallback(Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) { +void MarkCompact::UpdateRootCallback(Object** root, void* arg, const RootInfo& /*root_info*/) { mirror::Object* obj = *root; mirror::Object* new_obj = reinterpret_cast<MarkCompact*>(arg)->GetMarkedForwardAddress(obj); if (obj != new_obj) { diff --git a/runtime/gc/collector/mark_compact.h b/runtime/gc/collector/mark_compact.h index bb85fa0a81..cbdd19e9d9 100644 --- a/runtime/gc/collector/mark_compact.h +++ b/runtime/gc/collector/mark_compact.h @@ -24,6 +24,7 @@ #include "base/macros.h" #include "base/mutex.h" #include "garbage_collector.h" +#include "gc_root.h" #include "gc/accounting/heap_bitmap.h" #include "immune_region.h" #include "lock_word.h" @@ -113,8 +114,7 @@ class MarkCompact : public GarbageCollector { void SweepSystemWeaks() SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); - static void MarkRootCallback(mirror::Object** root, void* arg, uint32_t /*tid*/, - RootType /*root_type*/) + static void MarkRootCallback(mirror::Object** root, void* arg, const RootInfo& root_info) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); static mirror::Object* MarkObjectCallback(mirror::Object* root, void* arg) @@ -180,8 +180,7 @@ class MarkCompact : public GarbageCollector { EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_); // Update the references of objects by using the forwarding addresses. void UpdateReferences() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_); - static void UpdateRootCallback(mirror::Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) + static void UpdateRootCallback(mirror::Object** root, void* arg, const RootInfo& /*root_info*/) EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); // Move objects and restore lock words. diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index 95530be202..07f04cbbf9 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -456,42 +456,35 @@ inline void MarkSweep::MarkObject(Object* obj) { } } -void MarkSweep::MarkRootParallelCallback(Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) { +void MarkSweep::MarkRootParallelCallback(Object** root, void* arg, const RootInfo& /*root_info*/) { reinterpret_cast<MarkSweep*>(arg)->MarkObjectNonNullParallel(*root); } -void MarkSweep::VerifyRootMarked(Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) { +void MarkSweep::VerifyRootMarked(Object** root, void* arg, const RootInfo& /*root_info*/) { CHECK(reinterpret_cast<MarkSweep*>(arg)->IsMarked(*root)); } -void MarkSweep::MarkRootCallback(Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) { +void MarkSweep::MarkRootCallback(Object** root, void* arg, const RootInfo& /*root_info*/) { reinterpret_cast<MarkSweep*>(arg)->MarkObjectNonNull(*root); } -void MarkSweep::VerifyRootCallback(const Object* root, void* arg, size_t vreg, - const StackVisitor* visitor, RootType root_type) { - reinterpret_cast<MarkSweep*>(arg)->VerifyRoot(root, vreg, visitor, root_type); +void MarkSweep::VerifyRootCallback(Object** root, void* arg, const RootInfo& root_info) { + reinterpret_cast<MarkSweep*>(arg)->VerifyRoot(*root, root_info); } -void MarkSweep::VerifyRoot(const Object* root, size_t vreg, const StackVisitor* visitor, - RootType root_type) { +void MarkSweep::VerifyRoot(const Object* root, const RootInfo& root_info) { // See if the root is on any space bitmap. if (heap_->GetLiveBitmap()->GetContinuousSpaceBitmap(root) == nullptr) { space::LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace(); if (!large_object_space->Contains(root)) { - LOG(ERROR) << "Found invalid root: " << root << " with type " << root_type; - if (visitor != NULL) { - LOG(ERROR) << visitor->DescribeLocation() << " in VReg: " << vreg; - } + LOG(ERROR) << "Found invalid root: " << root << " "; + root_info.Describe(LOG(ERROR)); } } } void MarkSweep::VerifyRoots() { - Runtime::Current()->GetThreadList()->VerifyRoots(VerifyRootCallback, this); + Runtime::Current()->GetThreadList()->VisitRoots(VerifyRootCallback, this); } void MarkSweep::MarkRoots(Thread* self) { diff --git a/runtime/gc/collector/mark_sweep.h b/runtime/gc/collector/mark_sweep.h index 2780099fe2..d101456561 100644 --- a/runtime/gc/collector/mark_sweep.h +++ b/runtime/gc/collector/mark_sweep.h @@ -24,6 +24,7 @@ #include "base/macros.h" #include "base/mutex.h" #include "garbage_collector.h" +#include "gc_root.h" #include "gc/accounting/heap_bitmap.h" #include "immune_region.h" #include "object_callbacks.h" @@ -182,13 +183,11 @@ class MarkSweep : public GarbageCollector { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); - static void MarkRootCallback(mirror::Object** root, void* arg, uint32_t thread_id, - RootType root_type) + static void MarkRootCallback(mirror::Object** root, void* arg, const RootInfo& root_info) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); - static void VerifyRootMarked(mirror::Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) + static void VerifyRootMarked(mirror::Object** root, void* arg, const RootInfo& root_info) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); @@ -196,8 +195,7 @@ class MarkSweep : public GarbageCollector { EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - static void MarkRootParallelCallback(mirror::Object** root, void* arg, uint32_t thread_id, - RootType root_type) + static void MarkRootParallelCallback(mirror::Object** root, void* arg, const RootInfo& root_info) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Marks an object. @@ -247,11 +245,9 @@ class MarkSweep : public GarbageCollector { // whether or not we care about pauses. size_t GetThreadCount(bool paused) const; - static void VerifyRootCallback(const mirror::Object* root, void* arg, size_t vreg, - const StackVisitor *visitor, RootType root_type); + static void VerifyRootCallback(mirror::Object** root, void* arg, const RootInfo& root_info); - void VerifyRoot(const mirror::Object* root, size_t vreg, const StackVisitor* visitor, - RootType root_type) NO_THREAD_SAFETY_ANALYSIS; + void VerifyRoot(const mirror::Object* root, const RootInfo& root_info) NO_THREAD_SAFETY_ANALYSIS; // Push a single reference on a mark stack. void PushOnMarkStack(mirror::Object* obj); diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc index 8fb33cec2f..144e6a8020 100644 --- a/runtime/gc/collector/semi_space.cc +++ b/runtime/gc/collector/semi_space.cc @@ -590,8 +590,7 @@ void SemiSpace::DelayReferenceReferentCallback(mirror::Class* klass, mirror::Ref reinterpret_cast<SemiSpace*>(arg)->DelayReferenceReferent(klass, ref); } -void SemiSpace::MarkRootCallback(Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) { +void SemiSpace::MarkRootCallback(Object** root, void* arg, const RootInfo& /*root_info*/) { auto ref = StackReference<mirror::Object>::FromMirrorPtr(*root); reinterpret_cast<SemiSpace*>(arg)->MarkObject(&ref); if (*root != ref.AsMirrorPtr()) { diff --git a/runtime/gc/collector/semi_space.h b/runtime/gc/collector/semi_space.h index 71a83f2624..17da3673ab 100644 --- a/runtime/gc/collector/semi_space.h +++ b/runtime/gc/collector/semi_space.h @@ -23,6 +23,7 @@ #include "base/macros.h" #include "base/mutex.h" #include "garbage_collector.h" +#include "gc_root.h" #include "gc/accounting/heap_bitmap.h" #include "immune_region.h" #include "mirror/object_reference.h" @@ -132,8 +133,7 @@ class SemiSpace : public GarbageCollector { void SweepSystemWeaks() SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); - static void MarkRootCallback(mirror::Object** root, void* arg, uint32_t /*tid*/, - RootType /*root_type*/) + static void MarkRootCallback(mirror::Object** root, void* arg, const RootInfo& root_info) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); static mirror::Object* MarkObjectCallback(mirror::Object* root, void* arg) diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 0c14ded3ac..bad8de31ac 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -2277,8 +2277,8 @@ void Heap::FinishGC(Thread* self, collector::GcType gc_type) { gc_complete_cond_->Broadcast(self); } -static void RootMatchesObjectVisitor(mirror::Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) { +static void RootMatchesObjectVisitor(mirror::Object** root, void* arg, + const RootInfo& /*root_info*/) { mirror::Object* obj = reinterpret_cast<mirror::Object*>(arg); if (*root == obj) { LOG(INFO) << "Object " << obj << " is a root"; @@ -2319,12 +2319,12 @@ class VerifyReferenceVisitor { return heap_->IsLiveObjectLocked(obj, true, false, true); } - static void VerifyRootCallback(mirror::Object** root, void* arg, uint32_t thread_id, - RootType root_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + static void VerifyRootCallback(mirror::Object** root, void* arg, const RootInfo& root_info) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { VerifyReferenceVisitor* visitor = reinterpret_cast<VerifyReferenceVisitor*>(arg); if (!visitor->VerifyReference(nullptr, *root, MemberOffset(0))) { LOG(ERROR) << "Root " << *root << " is dead with type " << PrettyTypeOf(*root) - << " thread_id= " << thread_id << " root_type= " << root_type; + << " thread_id= " << root_info.GetThreadId() << " root_type= " << root_info.GetType(); } } diff --git a/runtime/gc_root.h b/runtime/gc_root.h index aee5586f3d..7e0be64441 100644 --- a/runtime/gc_root.h +++ b/runtime/gc_root.h @@ -19,22 +19,75 @@ #include "base/macros.h" #include "base/mutex.h" // For Locks::mutator_lock_. -#include "object_callbacks.h" namespace art { +namespace mirror { +class Object; +} // namespace mirror + +enum RootType { + kRootUnknown = 0, + kRootJNIGlobal, + kRootJNILocal, + kRootJavaFrame, + kRootNativeStack, + kRootStickyClass, + kRootThreadBlock, + kRootMonitorUsed, + kRootThreadObject, + kRootInternedString, + kRootDebugger, + kRootVMInternal, + kRootJNIMonitor, +}; +std::ostream& operator<<(std::ostream& os, const RootType& root_type); + +class RootInfo { + public: + // Thread id 0 is for non thread roots. + explicit RootInfo(RootType type, uint32_t thread_id = 0) + : type_(type), thread_id_(thread_id) { + } + virtual ~RootInfo() { + } + RootType GetType() const { + return type_; + } + uint32_t GetThreadId() const { + return thread_id_; + } + virtual void Describe(std::ostream& os) const { + os << "Type=" << type_ << " thread_id=" << thread_id_; + } + + private: + const RootType type_; + const uint32_t thread_id_; +}; + +// Returns the new address of the object, returns root if it has not moved. tid and root_type are +// only used by hprof. +typedef void (RootCallback)(mirror::Object** root, void* arg, const RootInfo& root_info); + template<class MirrorType> class PACKED(4) GcRoot { public: template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier> ALWAYS_INLINE MirrorType* Read() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VisitRoot(RootCallback* callback, void* arg, uint32_t thread_id, RootType root_type) const { + void VisitRoot(RootCallback* callback, void* arg, const RootInfo& info) const { DCHECK(!IsNull()); - callback(reinterpret_cast<mirror::Object**>(&root_), arg, thread_id, root_type); + callback(reinterpret_cast<mirror::Object**>(&root_), arg, info); DCHECK(!IsNull()); } + void VisitRootIfNonNull(RootCallback* callback, void* arg, const RootInfo& info) const { + if (!IsNull()) { + VisitRoot(callback, arg, info); + } + } + // This is only used by IrtIterator. ALWAYS_INLINE MirrorType** AddressWithoutBarrier() { return &root_; diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc index a2cccc5f9e..174b350282 100644 --- a/runtime/hprof/hprof.cc +++ b/runtime/hprof/hprof.cc @@ -44,6 +44,7 @@ #include "common_throws.h" #include "debugger.h" #include "dex_file-inl.h" +#include "gc_root.h" #include "gc/accounting/heap_bitmap.h" #include "gc/heap.h" #include "gc/space/space.h" @@ -501,12 +502,12 @@ class Hprof { } private: - static void RootVisitor(mirror::Object** obj, void* arg, uint32_t thread_id, RootType root_type) + static void RootVisitor(mirror::Object** obj, void* arg, const RootInfo& root_info) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { DCHECK(arg != nullptr); DCHECK(obj != nullptr); DCHECK(*obj != nullptr); - reinterpret_cast<Hprof*>(arg)->VisitRoot(*obj, thread_id, root_type); + reinterpret_cast<Hprof*>(arg)->VisitRoot(*obj, root_info); } static void VisitObjectCallback(mirror::Object* obj, void* arg) @@ -516,7 +517,7 @@ class Hprof { reinterpret_cast<Hprof*>(arg)->DumpHeapObject(obj); } - void VisitRoot(const mirror::Object* obj, uint32_t thread_id, RootType type) + void VisitRoot(const mirror::Object* obj, const RootInfo& root_info) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); int DumpHeapObject(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -1061,7 +1062,7 @@ int Hprof::DumpHeapObject(mirror::Object* obj) { return 0; } -void Hprof::VisitRoot(const mirror::Object* obj, uint32_t thread_id, RootType type) { +void Hprof::VisitRoot(const mirror::Object* obj, const RootInfo& root_info) { static const HprofHeapTag xlate[] = { HPROF_ROOT_UNKNOWN, HPROF_ROOT_JNI_GLOBAL, @@ -1079,12 +1080,12 @@ void Hprof::VisitRoot(const mirror::Object* obj, uint32_t thread_id, RootType ty HPROF_ROOT_VM_INTERNAL, HPROF_ROOT_JNI_MONITOR, }; - CHECK_LT(type, sizeof(xlate) / sizeof(HprofHeapTag)); + CHECK_LT(root_info.GetType(), sizeof(xlate) / sizeof(HprofHeapTag)); if (obj == NULL) { return; } - gc_scan_state_ = xlate[type]; - gc_thread_serial_number_ = thread_id; + gc_scan_state_ = xlate[root_info.GetType()]; + gc_thread_serial_number_ = root_info.GetThreadId(); 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 c5526bbaeb..fe924fb46b 100644 --- a/runtime/indirect_reference_table.cc +++ b/runtime/indirect_reference_table.cc @@ -239,10 +239,10 @@ void IndirectReferenceTable::Trim() { madvise(release_start, release_end - release_start, MADV_DONTNEED); } -void IndirectReferenceTable::VisitRoots(RootCallback* callback, void* arg, uint32_t tid, - RootType root_type) { +void IndirectReferenceTable::VisitRoots(RootCallback* callback, void* arg, + const RootInfo& root_info) { for (auto ref : *this) { - callback(ref, arg, tid, root_type); + callback(ref, arg, root_info); DCHECK(*ref != nullptr); } } diff --git a/runtime/indirect_reference_table.h b/runtime/indirect_reference_table.h index 51b2fcf2cc..0202347b77 100644 --- a/runtime/indirect_reference_table.h +++ b/runtime/indirect_reference_table.h @@ -31,6 +31,9 @@ #include "read_barrier_option.h" namespace art { + +class RootInfo; + namespace mirror { class Object; } // namespace mirror @@ -329,7 +332,7 @@ class IndirectReferenceTable { return IrtIterator(table_, Capacity(), Capacity()); } - void VisitRoots(RootCallback* callback, void* arg, uint32_t tid, RootType root_type) + void VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); uint32_t GetSegmentState() const { diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index a698c9efdf..8282fab996 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -1142,7 +1142,7 @@ void Instrumentation::VisitRoots(RootCallback* callback, void* arg) { return; } for (auto pair : deoptimized_methods_) { - pair.second.VisitRoot(callback, arg, 0, kRootVMInternal); + pair.second.VisitRoot(callback, arg, RootInfo(kRootVMInternal)); } } diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc index 29a24597e7..144b2c596a 100644 --- a/runtime/intern_table.cc +++ b/runtime/intern_table.cc @@ -60,7 +60,7 @@ void InternTable::VisitRoots(RootCallback* callback, void* arg, VisitRootFlags f } else if ((flags & kVisitRootFlagNewRoots) != 0) { for (auto& root : new_strong_intern_roots_) { mirror::String* old_ref = root.Read<kWithoutReadBarrier>(); - root.VisitRoot(callback, arg, 0, kRootInternedString); + root.VisitRoot(callback, arg, RootInfo(kRootInternedString)); mirror::String* new_ref = root.Read<kWithoutReadBarrier>(); if (new_ref != old_ref) { // The GC moved a root in the log. Need to search the strong interns and update the @@ -329,10 +329,10 @@ void InternTable::Table::Insert(mirror::String* s) { void InternTable::Table::VisitRoots(RootCallback* callback, void* arg) { for (auto& intern : pre_zygote_table_) { - intern.VisitRoot(callback, arg, 0, kRootInternedString); + intern.VisitRoot(callback, arg, RootInfo(kRootInternedString)); } for (auto& intern : post_zygote_table_) { - intern.VisitRoot(callback, arg, 0, kRootInternedString); + intern.VisitRoot(callback, arg, RootInfo(kRootInternedString)); } } diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index 2c8148f0bc..938bf2c20e 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -437,9 +437,7 @@ class SharedLibrary { } void VisitRoots(RootCallback* visitor, void* arg) { - if (!class_loader_.IsNull()) { - class_loader_.VisitRoot(visitor, arg, 0, kRootVMInternal); - } + class_loader_.VisitRootIfNonNull(visitor, arg, RootInfo(kRootVMInternal)); } private: @@ -3416,7 +3414,7 @@ void JavaVMExt::VisitRoots(RootCallback* callback, void* arg) { Thread* self = Thread::Current(); { ReaderMutexLock mu(self, globals_lock); - globals.VisitRoots(callback, arg, 0, kRootJNIGlobal); + globals.VisitRoots(callback, arg, RootInfo(kRootJNIGlobal)); } { MutexLock mu(self, libraries_lock); diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index 2c0ea367cc..64452452d9 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -166,9 +166,7 @@ inline Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_c template<class T> inline void PrimitiveArray<T>::VisitRoots(RootCallback* callback, void* arg) { - if (!array_class_.IsNull()) { - array_class_.VisitRoot(callback, arg, 0, kRootStickyClass); - } + array_class_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass)); } template<typename T> diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc index 7e20076112..5a4ebd1f6e 100644 --- a/runtime/mirror/art_field.cc +++ b/runtime/mirror/art_field.cc @@ -56,9 +56,7 @@ void ArtField::SetOffset(MemberOffset num_bytes) { } void ArtField::VisitRoots(RootCallback* callback, void* arg) { - if (!java_lang_reflect_ArtField_.IsNull()) { - java_lang_reflect_ArtField_.VisitRoot(callback, arg, 0, kRootStickyClass); - } + java_lang_reflect_ArtField_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass)); } // TODO: we could speed up the search if fields are ordered by offsets. diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc index 9bd5e7d9b2..afc1079878 100644 --- a/runtime/mirror/art_method.cc +++ b/runtime/mirror/art_method.cc @@ -60,9 +60,7 @@ ArtMethod* ArtMethod::FromReflectedMethod(const ScopedObjectAccessAlreadyRunnabl void ArtMethod::VisitRoots(RootCallback* callback, void* arg) { - if (!java_lang_reflect_ArtMethod_.IsNull()) { - java_lang_reflect_ArtMethod_.VisitRoot(callback, arg, 0, kRootStickyClass); - } + java_lang_reflect_ArtMethod_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass)); } InvokeType ArtMethod::GetInvokeType() { diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index b91dfc171b..f9791fa944 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -52,9 +52,7 @@ void Class::ResetClass() { } void Class::VisitRoots(RootCallback* callback, void* arg) { - if (!java_lang_Class_.IsNull()) { - java_lang_Class_.VisitRoot(callback, arg, 0, kRootStickyClass); - } + java_lang_Class_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass)); } void Class::SetStatus(Status new_status, Thread* self) { diff --git a/runtime/mirror/reference.cc b/runtime/mirror/reference.cc index c36bd980f9..35130e8b88 100644 --- a/runtime/mirror/reference.cc +++ b/runtime/mirror/reference.cc @@ -33,9 +33,7 @@ void Reference::ResetClass() { } void Reference::VisitRoots(RootCallback* callback, void* arg) { - if (!java_lang_ref_Reference_.IsNull()) { - java_lang_ref_Reference_.VisitRoot(callback, arg, 0, kRootStickyClass); - } + java_lang_ref_Reference_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass)); } } // namespace mirror diff --git a/runtime/mirror/stack_trace_element.cc b/runtime/mirror/stack_trace_element.cc index 1eb20f71a6..c2a67e809a 100644 --- a/runtime/mirror/stack_trace_element.cc +++ b/runtime/mirror/stack_trace_element.cc @@ -68,9 +68,7 @@ void StackTraceElement::Init(Handle<String> declaring_class, Handle<String> meth } void StackTraceElement::VisitRoots(RootCallback* callback, void* arg) { - if (!java_lang_StackTraceElement_.IsNull()) { - java_lang_StackTraceElement_.VisitRoot(callback, arg, 0, kRootStickyClass); - } + java_lang_StackTraceElement_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass)); } diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc index 01599ae907..e199d0e2ef 100644 --- a/runtime/mirror/string.cc +++ b/runtime/mirror/string.cc @@ -224,9 +224,7 @@ int32_t String::CompareTo(String* rhs) { } void String::VisitRoots(RootCallback* callback, void* arg) { - if (!java_lang_String_.IsNull()) { - java_lang_String_.VisitRoot(callback, arg, 0, kRootStickyClass); - } + java_lang_String_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass)); } } // namespace mirror diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc index 93ed4d4daf..61d85e2fe2 100644 --- a/runtime/mirror/throwable.cc +++ b/runtime/mirror/throwable.cc @@ -138,9 +138,7 @@ void Throwable::ResetClass() { } void Throwable::VisitRoots(RootCallback* callback, void* arg) { - if (!java_lang_Throwable_.IsNull()) { - java_lang_Throwable_.VisitRoot(callback, arg, 0, kRootStickyClass); - } + java_lang_Throwable_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass)); } } // namespace mirror diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index 4b1236abe2..9fbb9385d8 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -216,7 +216,7 @@ static void VMRuntime_concurrentGC(JNIEnv* env, jobject) { typedef std::map<std::string, mirror::String*> StringTable; static void PreloadDexCachesStringsCallback(mirror::Object** root, void* arg, - uint32_t /*thread_id*/, RootType /*root_type*/) + const RootInfo& /*root_info*/) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { StringTable& table = *reinterpret_cast<StringTable*>(arg); mirror::String* string = const_cast<mirror::Object*>(*root)->AsString(); diff --git a/runtime/object_callbacks.h b/runtime/object_callbacks.h index 592deed1a7..cf81cc5093 100644 --- a/runtime/object_callbacks.h +++ b/runtime/object_callbacks.h @@ -35,34 +35,10 @@ namespace mirror { } // namespace mirror class StackVisitor; -enum RootType { - kRootUnknown = 0, - kRootJNIGlobal, - kRootJNILocal, - kRootJavaFrame, - kRootNativeStack, - kRootStickyClass, - kRootThreadBlock, - kRootMonitorUsed, - kRootThreadObject, - kRootInternedString, - kRootDebugger, - kRootVMInternal, - kRootJNIMonitor, -}; -std::ostream& operator<<(std::ostream& os, const RootType& root_type); - -// Returns the new address of the object, returns root if it has not moved. tid and root_type are -// only used by hprof. -typedef void (RootCallback)(mirror::Object** root, void* arg, uint32_t thread_id, - RootType root_type); // 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) WARN_UNUSED; -// A callback for verifying roots. -typedef void (VerifyRootCallback)(const mirror::Object* root, void* arg, size_t vreg, - const StackVisitor* visitor, RootType root_type); typedef void (MarkHeapReferenceCallback)(mirror::HeapReference<mirror::Object>* ref, void* arg); typedef void (DelayReferenceReferentCallback)(mirror::Class* klass, mirror::Reference* ref, void* arg); diff --git a/runtime/reference_table.cc b/runtime/reference_table.cc index 503546388b..179110cae8 100644 --- a/runtime/reference_table.cc +++ b/runtime/reference_table.cc @@ -242,10 +242,9 @@ void ReferenceTable::Dump(std::ostream& os, Table& entries) { identical, equiv); } -void ReferenceTable::VisitRoots(RootCallback* visitor, void* arg, uint32_t tid, - RootType root_type) { +void ReferenceTable::VisitRoots(RootCallback* visitor, void* arg, const RootInfo& root_info) { for (GcRoot<mirror::Object>& root : entries_) { - root.VisitRoot(visitor, arg, tid, root_type); + root.VisitRoot(visitor, arg, root_info); } } diff --git a/runtime/reference_table.h b/runtime/reference_table.h index 6cffa85d7f..22cf1cd804 100644 --- a/runtime/reference_table.h +++ b/runtime/reference_table.h @@ -49,7 +49,7 @@ class ReferenceTable { void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VisitRoots(RootCallback* visitor, void* arg, uint32_t tid, RootType root_type); + void VisitRoots(RootCallback* visitor, void* arg, const RootInfo& root_info); private: typedef std::vector<GcRoot<mirror::Object>, diff --git a/runtime/runtime.cc b/runtime/runtime.cc index d6cafcc6dc..346d0a1933 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1157,29 +1157,14 @@ void Runtime::VisitConcurrentRoots(RootCallback* callback, void* arg, VisitRootF void Runtime::VisitNonThreadRoots(RootCallback* callback, void* arg) { java_vm_->VisitRoots(callback, arg); - if (!pre_allocated_OutOfMemoryError_.IsNull()) { - pre_allocated_OutOfMemoryError_.VisitRoot(callback, arg, 0, kRootVMInternal); - DCHECK(!pre_allocated_OutOfMemoryError_.IsNull()); - } - resolution_method_.VisitRoot(callback, arg, 0, kRootVMInternal); - DCHECK(!resolution_method_.IsNull()); - if (!pre_allocated_NoClassDefFoundError_.IsNull()) { - pre_allocated_NoClassDefFoundError_.VisitRoot(callback, arg, 0, kRootVMInternal); - DCHECK(!pre_allocated_NoClassDefFoundError_.IsNull()); - } - if (HasImtConflictMethod()) { - imt_conflict_method_.VisitRoot(callback, arg, 0, kRootVMInternal); - } - if (!imt_unimplemented_method_.IsNull()) { - imt_unimplemented_method_.VisitRoot(callback, arg, 0, kRootVMInternal); - } - if (HasDefaultImt()) { - default_imt_.VisitRoot(callback, arg, 0, kRootVMInternal); - } + pre_allocated_OutOfMemoryError_.VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal)); + resolution_method_.VisitRoot(callback, arg, RootInfo(kRootVMInternal)); + pre_allocated_NoClassDefFoundError_.VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal)); + imt_conflict_method_.VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal)); + imt_unimplemented_method_.VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal)); + default_imt_.VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal)); for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { - if (!callee_save_methods_[i].IsNull()) { - callee_save_methods_[i].VisitRoot(callback, arg, 0, kRootVMInternal); - } + callee_save_methods_[i].VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal)); } verifier::MethodVerifier::VisitStaticRoots(callback, arg); { diff --git a/runtime/stack.cc b/runtime/stack.cc index 3558a81d83..f0b6c21eec 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -608,4 +608,11 @@ void StackVisitor::WalkStack(bool include_transitions) { } } +void JavaFrameRootInfo::Describe(std::ostream& os) const { + const StackVisitor* visitor = stack_visitor_; + CHECK(visitor != nullptr); + os << "Type=" << GetType() << " thread_id=" << GetThreadId() << " location=" << + visitor->DescribeLocation() << " vreg=" << vreg_; +} + } // namespace art diff --git a/runtime/stack.h b/runtime/stack.h index e58caeee79..7188d30268 100644 --- a/runtime/stack.h +++ b/runtime/stack.h @@ -21,6 +21,7 @@ #include <string> #include "dex_file.h" +#include "gc_root.h" #include "instruction_set.h" #include "mirror/object_reference.h" #include "throw_location.h" @@ -397,6 +398,19 @@ class ShadowFrame { DISALLOW_IMPLICIT_CONSTRUCTORS(ShadowFrame); }; +class JavaFrameRootInfo : public RootInfo { + public: + JavaFrameRootInfo(uint32_t thread_id, const StackVisitor* stack_visitor, size_t vreg) + : RootInfo(kRootJavaFrame, thread_id), stack_visitor_(stack_visitor), vreg_(vreg) { + } + virtual void Describe(std::ostream& os) const OVERRIDE + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + private: + const StackVisitor* const stack_visitor_; + const size_t vreg_; +}; + // The managed stack is used to record fragments of managed code stacks. Managed code stacks // may either be shadow frames or lists of frames using fixed frame sizes. Transition records are // necessary for transitions between code using different frame layouts and transitions into native diff --git a/runtime/thread.cc b/runtime/thread.cc index a3eb9fbcc6..2f474f7ae1 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -1153,8 +1153,7 @@ void Thread::AssertNoPendingExceptionForNewException(const char* msg) const { } } -static void MonitorExitVisitor(mirror::Object** object, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) +static void MonitorExitVisitor(mirror::Object** object, void* arg, const RootInfo& /*root_info*/) NO_THREAD_SAFETY_ANALYSIS { Thread* self = reinterpret_cast<Thread*>(arg); mirror::Object* entered_monitor = *object; @@ -1202,7 +1201,7 @@ void Thread::Destroy() { // On thread detach, all monitors entered with JNI MonitorEnter are automatically exited. if (tlsPtr_.jni_env != nullptr) { - tlsPtr_.jni_env->monitors.VisitRoots(MonitorExitVisitor, self, 0, kRootVMInternal); + tlsPtr_.jni_env->monitors.VisitRoots(MonitorExitVisitor, self, RootInfo(kRootVMInternal)); } } @@ -1323,7 +1322,7 @@ void Thread::HandleScopeVisitRoots(RootCallback* visitor, void* arg, uint32_t th mirror::Object* object = cur->GetReference(j); if (object != nullptr) { mirror::Object* old_obj = object; - visitor(&object, arg, thread_id, kRootNativeStack); + visitor(&object, arg, RootInfo(kRootNativeStack, thread_id)); if (old_obj != object) { cur->SetReference(j, object); } @@ -2172,8 +2171,8 @@ class RootCallbackVisitor { RootCallbackVisitor(RootCallback* callback, void* arg, uint32_t tid) : callback_(callback), arg_(arg), tid_(tid) {} - void operator()(mirror::Object** obj, size_t, const StackVisitor*) const { - callback_(obj, arg_, tid_, kRootJavaFrame); + void operator()(mirror::Object** obj, size_t vreg, const StackVisitor* stack_visitor) const { + callback_(obj, arg_, JavaFrameRootInfo(tid_, stack_visitor, vreg)); } private: @@ -2190,27 +2189,28 @@ void Thread::SetClassLoaderOverride(mirror::ClassLoader* class_loader_override) void Thread::VisitRoots(RootCallback* visitor, void* arg) { uint32_t thread_id = GetThreadId(); if (tlsPtr_.opeer != nullptr) { - visitor(&tlsPtr_.opeer, arg, thread_id, kRootThreadObject); + visitor(&tlsPtr_.opeer, arg, RootInfo(kRootThreadObject, thread_id)); } if (tlsPtr_.exception != nullptr && tlsPtr_.exception != GetDeoptimizationException()) { - visitor(reinterpret_cast<mirror::Object**>(&tlsPtr_.exception), arg, thread_id, kRootNativeStack); + visitor(reinterpret_cast<mirror::Object**>(&tlsPtr_.exception), arg, + RootInfo(kRootNativeStack, thread_id)); } tlsPtr_.throw_location.VisitRoots(visitor, arg); if (tlsPtr_.class_loader_override != nullptr) { - visitor(reinterpret_cast<mirror::Object**>(&tlsPtr_.class_loader_override), arg, thread_id, - kRootNativeStack); + visitor(reinterpret_cast<mirror::Object**>(&tlsPtr_.class_loader_override), arg, + RootInfo(kRootNativeStack, thread_id)); } if (tlsPtr_.monitor_enter_object != nullptr) { - visitor(&tlsPtr_.monitor_enter_object, arg, thread_id, kRootNativeStack); + visitor(&tlsPtr_.monitor_enter_object, arg, RootInfo(kRootNativeStack, thread_id)); } - tlsPtr_.jni_env->locals.VisitRoots(visitor, arg, thread_id, kRootJNILocal); - tlsPtr_.jni_env->monitors.VisitRoots(visitor, arg, thread_id, kRootJNIMonitor); + tlsPtr_.jni_env->locals.VisitRoots(visitor, arg, RootInfo(kRootJNILocal, thread_id)); + tlsPtr_.jni_env->monitors.VisitRoots(visitor, arg, RootInfo(kRootJNIMonitor, thread_id)); HandleScopeVisitRoots(visitor, arg, thread_id); if (tlsPtr_.debug_invoke_req != nullptr) { - tlsPtr_.debug_invoke_req->VisitRoots(visitor, arg, thread_id, kRootDebugger); + tlsPtr_.debug_invoke_req->VisitRoots(visitor, arg, RootInfo(kRootDebugger, thread_id)); } if (tlsPtr_.single_step_control != nullptr) { - tlsPtr_.single_step_control->VisitRoots(visitor, arg, thread_id, kRootDebugger); + tlsPtr_.single_step_control->VisitRoots(visitor, arg, RootInfo(kRootDebugger, thread_id)); } if (tlsPtr_.deoptimization_shadow_frame != nullptr) { RootCallbackVisitor visitorToCallback(visitor, arg, thread_id); @@ -2221,8 +2221,8 @@ void Thread::VisitRoots(RootCallback* visitor, void* arg) { } } if (tlsPtr_.shadow_frame_under_construction != nullptr) { - RootCallbackVisitor visitorToCallback(visitor, arg, thread_id); - ReferenceMapVisitor<RootCallbackVisitor> mapper(this, nullptr, visitorToCallback); + RootCallbackVisitor visitor_to_callback(visitor, arg, thread_id); + ReferenceMapVisitor<RootCallbackVisitor> mapper(this, nullptr, visitor_to_callback); for (ShadowFrame* shadow_frame = tlsPtr_.shadow_frame_under_construction; shadow_frame != nullptr; shadow_frame = shadow_frame->GetLink()) { @@ -2231,21 +2231,22 @@ void Thread::VisitRoots(RootCallback* visitor, void* arg) { } // Visit roots on this thread's stack Context* context = GetLongJumpContext(); - RootCallbackVisitor visitorToCallback(visitor, arg, thread_id); - ReferenceMapVisitor<RootCallbackVisitor> mapper(this, context, visitorToCallback); + RootCallbackVisitor visitor_to_callback(visitor, arg, thread_id); + ReferenceMapVisitor<RootCallbackVisitor> mapper(this, context, visitor_to_callback); mapper.WalkStack(); ReleaseLongJumpContext(context); for (instrumentation::InstrumentationStackFrame& frame : *GetInstrumentationStack()) { if (frame.this_object_ != nullptr) { - visitor(&frame.this_object_, arg, thread_id, kRootJavaFrame); + visitor(&frame.this_object_, arg, RootInfo(kRootVMInternal, thread_id)); } DCHECK(frame.method_ != nullptr); - visitor(reinterpret_cast<mirror::Object**>(&frame.method_), arg, thread_id, kRootJavaFrame); + visitor(reinterpret_cast<mirror::Object**>(&frame.method_), arg, + RootInfo(kRootVMInternal, thread_id)); } } -static void VerifyRoot(mirror::Object** root, void* /*arg*/, uint32_t /*thread_id*/, - RootType /*root_type*/) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +static void VerifyRoot(mirror::Object** root, void* /*arg*/, const RootInfo& /*root_info*/) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { VerifyObject(*root); } diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc index 3647dc4ed8..5460249e91 100644 --- a/runtime/thread_list.cc +++ b/runtime/thread_list.cc @@ -942,28 +942,6 @@ void ThreadList::VisitRoots(RootCallback* callback, void* arg) const { } } -class VerifyRootWrapperArg { - public: - VerifyRootWrapperArg(VerifyRootCallback* callback, void* arg) : callback_(callback), arg_(arg) { - } - VerifyRootCallback* const callback_; - void* const arg_; -}; - -static void VerifyRootWrapperCallback(mirror::Object** root, void* arg, uint32_t /*thread_id*/, - RootType root_type) { - VerifyRootWrapperArg* wrapperArg = reinterpret_cast<VerifyRootWrapperArg*>(arg); - wrapperArg->callback_(*root, wrapperArg->arg_, 0, NULL, root_type); -} - -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); - } -} - uint32_t ThreadList::AllocThreadId(Thread* self) { MutexLock mu(self, *Locks::allocated_thread_ids_lock_); for (size_t i = 0; i < allocated_ids_.size(); ++i) { diff --git a/runtime/thread_list.h b/runtime/thread_list.h index 9f515a8686..3c721909ad 100644 --- a/runtime/thread_list.h +++ b/runtime/thread_list.h @@ -18,6 +18,7 @@ #define ART_RUNTIME_THREAD_LIST_H_ #include "base/mutex.h" +#include "gc_root.h" #include "jni.h" #include "object_callbacks.h" @@ -126,9 +127,6 @@ class ThreadList { void VisitRoots(RootCallback* callback, void* arg) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VerifyRoots(VerifyRootCallback* callback, void* arg) const - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - // Return a copy of the thread list. std::list<Thread*> GetList() EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) { return list_; diff --git a/runtime/throw_location.cc b/runtime/throw_location.cc index 04abe64453..4d2aec088e 100644 --- a/runtime/throw_location.cc +++ b/runtime/throw_location.cc @@ -34,11 +34,11 @@ std::string ThrowLocation::Dump() const { void ThrowLocation::VisitRoots(RootCallback* visitor, void* arg) { if (this_object_ != nullptr) { - visitor(&this_object_, arg, 0, kRootVMInternal); + visitor(&this_object_, arg, RootInfo(kRootVMInternal)); DCHECK(this_object_ != nullptr); } if (method_ != nullptr) { - visitor(reinterpret_cast<mirror::Object**>(&method_), arg, 0, kRootVMInternal); + visitor(reinterpret_cast<mirror::Object**>(&method_), arg, RootInfo(kRootVMInternal)); DCHECK(method_ != nullptr); } } diff --git a/runtime/throw_location.h b/runtime/throw_location.h index b36eb67f9c..bec0da490a 100644 --- a/runtime/throw_location.h +++ b/runtime/throw_location.h @@ -20,6 +20,7 @@ #include "object_callbacks.h" #include "base/macros.h" #include "base/mutex.h" +#include "gc_root.h" #include <stdint.h> #include <string> diff --git a/runtime/transaction.cc b/runtime/transaction.cc index 50f1ecaa79..23b9656059 100644 --- a/runtime/transaction.cc +++ b/runtime/transaction.cc @@ -172,7 +172,7 @@ void Transaction::VisitObjectLogs(RootCallback* callback, void* arg) { it.second.VisitRoots(callback, arg); mirror::Object* old_root = it.first; mirror::Object* new_root = old_root; - callback(&new_root, arg, 0, kRootUnknown); + callback(&new_root, arg, RootInfo(kRootUnknown)); if (new_root != old_root) { moving_roots.push_back(std::make_pair(old_root, new_root)); } @@ -199,7 +199,7 @@ void Transaction::VisitArrayLogs(RootCallback* callback, void* arg) { mirror::Array* old_root = it.first; CHECK(!old_root->IsObjectArray()); mirror::Array* new_root = old_root; - callback(reinterpret_cast<mirror::Object**>(&new_root), arg, 0, kRootUnknown); + callback(reinterpret_cast<mirror::Object**>(&new_root), arg, RootInfo(kRootUnknown)); if (new_root != old_root) { moving_roots.push_back(std::make_pair(old_root, new_root)); } @@ -319,7 +319,7 @@ void Transaction::ObjectLog::VisitRoots(RootCallback* callback, void* arg) { mirror::Object* obj = reinterpret_cast<mirror::Object*>(static_cast<uintptr_t>(field_value.value)); if (obj != nullptr) { - callback(&obj, arg, 0, kRootUnknown); + callback(&obj, arg, RootInfo(kRootUnknown)); field_value.value = reinterpret_cast<uintptr_t>(obj); } } @@ -364,7 +364,7 @@ void Transaction::InternStringLog::Undo(InternTable* intern_table) { } void Transaction::InternStringLog::VisitRoots(RootCallback* callback, void* arg) { - callback(reinterpret_cast<mirror::Object**>(&str_), arg, 0, kRootInternedString); + callback(reinterpret_cast<mirror::Object**>(&str_), arg, RootInfo(kRootInternedString)); } void Transaction::ArrayLog::LogValue(size_t index, uint64_t value) { diff --git a/runtime/transaction.h b/runtime/transaction.h index 6625390811..83206b282f 100644 --- a/runtime/transaction.h +++ b/runtime/transaction.h @@ -19,6 +19,7 @@ #include "base/macros.h" #include "base/mutex.h" +#include "gc_root.h" #include "object_callbacks.h" #include "offsets.h" #include "primitive.h" diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc index 30be82f231..ede9866d2a 100644 --- a/runtime/verifier/reg_type.cc +++ b/runtime/verifier/reg_type.cc @@ -968,9 +968,7 @@ void RegType::CheckInvariants() const { } void RegType::VisitRoots(RootCallback* callback, void* arg) { - if (!klass_.IsNull()) { - klass_.VisitRoot(callback, arg, 0, kRootUnknown); - } + klass_.VisitRootIfNonNull(callback, arg, RootInfo(kRootUnknown)); } void UninitializedThisReferenceType::CheckInvariants() const { |