From 7bf9f190cd33a7e2f8584299eb889e9df66e0323 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Fri, 4 Apr 2014 11:09:41 -0700 Subject: [PATCH] Improve invalid root dumping. The invalid root dumping now attempts to print the root type. Change-Id: Ie821296d569f34909ba6e2705f5c347cd2143a3a --- runtime/gc/collector/mark_sweep.cc | 15 ++++++++------- runtime/gc/collector/mark_sweep.h | 6 +++--- runtime/gc/heap.h | 2 ++ runtime/object_callbacks.h | 2 +- runtime/thread_list.cc | 4 ++-- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index ca2d0bd6d..944ef8d88 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -76,7 +76,7 @@ static constexpr bool kCountMarkedObjects = false; // Turn off kCheckLocks when profiling the GC since it slows the GC down by up to 40%. static constexpr bool kCheckLocks = kDebugLocking; -static constexpr bool kVerifyRoots = kIsDebugBuild; +static constexpr bool kVerifyRootsMarked = kIsDebugBuild; // If true, revoke the rosalloc thread-local buffers at the // checkpoint, as opposed to during the pause. @@ -466,16 +466,17 @@ void MarkSweep::MarkRootCallback(Object** root, void* arg, uint32_t /*thread_id* } void MarkSweep::VerifyRootCallback(const Object* root, void* arg, size_t vreg, - const StackVisitor* visitor) { - reinterpret_cast(arg)->VerifyRoot(root, vreg, visitor); + const StackVisitor* visitor, RootType root_type) { + reinterpret_cast(arg)->VerifyRoot(root, vreg, visitor, root_type); } -void MarkSweep::VerifyRoot(const Object* root, size_t vreg, const StackVisitor* visitor) { +void MarkSweep::VerifyRoot(const Object* root, size_t vreg, const StackVisitor* visitor, + RootType root_type) { // See if the root is on any space bitmap. - if (GetHeap()->GetLiveBitmap()->GetContinuousSpaceBitmap(root) == NULL) { + if (GetHeap()->GetLiveBitmap()->GetContinuousSpaceBitmap(root) == nullptr) { space::LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace(); if (!large_object_space->Contains(root)) { - LOG(ERROR) << "Found invalid root: " << root; + LOG(ERROR) << "Found invalid root: " << root << " with type " << root_type; if (visitor != NULL) { LOG(ERROR) << visitor->DescribeLocation() << " in VReg: " << vreg; } @@ -918,7 +919,7 @@ void MarkSweep::ReMarkRoots() { kVisitRootFlagStopLoggingNewRoots | kVisitRootFlagClearRootLog)); timings_.EndSplit(); - if (kVerifyRoots) { + if (kVerifyRootsMarked) { timings_.StartSplit("(Paused)VerifyRoots"); Runtime::Current()->VisitRoots(VerifyRootMarked, this); timings_.EndSplit(); diff --git a/runtime/gc/collector/mark_sweep.h b/runtime/gc/collector/mark_sweep.h index f1fd546f3..d49e42724 100644 --- a/runtime/gc/collector/mark_sweep.h +++ b/runtime/gc/collector/mark_sweep.h @@ -249,10 +249,10 @@ class MarkSweep : public GarbageCollector { size_t GetThreadCount(bool paused) const; static void VerifyRootCallback(const mirror::Object* root, void* arg, size_t vreg, - const StackVisitor *visitor); + const StackVisitor *visitor, RootType root_type); - void VerifyRoot(const mirror::Object* root, size_t vreg, const StackVisitor* visitor) - NO_THREAD_SAFETY_ANALYSIS; + void VerifyRoot(const mirror::Object* root, size_t vreg, const StackVisitor* visitor, + RootType root_type) NO_THREAD_SAFETY_ANALYSIS; // Push a single reference on a mark stack. void PushOnMarkStack(mirror::Object* obj); diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index ffb4e5918..a8989ecde 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -115,6 +115,8 @@ enum ProcessState { }; std::ostream& operator<<(std::ostream& os, const ProcessState& process_state); +std::ostream& operator<<(std::ostream& os, const RootType& root_type); + class Heap { public: // If true, measure the total allocation time. diff --git a/runtime/object_callbacks.h b/runtime/object_callbacks.h index 89ee34e81..9198c90d5 100644 --- a/runtime/object_callbacks.h +++ b/runtime/object_callbacks.h @@ -56,7 +56,7 @@ 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); + const StackVisitor* visitor, RootType root_type); typedef void (MarkHeapReferenceCallback)(mirror::HeapReference* ref, void* arg); diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc index 7de9433b2..8dad41990 100644 --- a/runtime/thread_list.cc +++ b/runtime/thread_list.cc @@ -823,9 +823,9 @@ class VerifyRootWrapperArg { }; static void VerifyRootWrapperCallback(mirror::Object** root, void* arg, uint32_t /*thread_id*/, - RootType /*root_type*/) { + RootType root_type) { VerifyRootWrapperArg* wrapperArg = reinterpret_cast(arg); - wrapperArg->callback_(*root, wrapperArg->arg_, 0, NULL); + wrapperArg->callback_(*root, wrapperArg->arg_, 0, NULL, root_type); } void ThreadList::VerifyRoots(VerifyRootCallback* callback, void* arg) const { -- 2.11.0