Print more info in MarkSweep::VerifyRoot
Refactored old root callback to use a new class called RootInfo.
RootInfo contains all the relevant info related to the root
associated with the callback. The MarkSweep::VerifyRoot function
now uses this info to print the StackVisitor's described location
if the GC root is of the type kRootJavaFrame.
Some other cleanup.
Example output:
E/art (12167): Tried to mark 0x123 not contained by any spaces
E/art (12167): Attempting see if it's a bad root
E/art (12167): Found invalid root: 0x123 with type RootJavaFrame
E/art (12167): Location=Visiting method
'void java.lang.Runtime.gc()' at dex PC 0xffffffff (native PC 0x0)
vreg=0
Bug: 18588862
Change-Id: Ic5a2781f704e931265ffb3621c2eab4b2e25f60f
diff --git a/runtime/Android.mk b/runtime/Android.mk
index 0f5050b..84f2248 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -298,6 +298,7 @@
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 @@
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 702e901..0afd174 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1706,23 +1706,23 @@
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 @@
// 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 @@
}
}
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 928780a..7ca0927 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -364,7 +364,7 @@
}
}
- 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 c2745ff..5db9d41 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -341,19 +341,18 @@
// 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 @@
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 3fdd823..ac9616e 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 @@
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 @@
// 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 4044852..c63fec4 100644
--- a/runtime/gc/collector/mark_compact.cc
+++ b/runtime/gc/collector/mark_compact.cc
@@ -300,22 +300,20 @@
}
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 bb85fa0..cbdd19e 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 @@
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 @@
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 95530be..07f04cb 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -456,42 +456,35 @@
}
}
-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 2780099..d101456 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 @@
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 @@
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 @@
// 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 8fb33ce..144e6a8 100644
--- a/runtime/gc/collector/semi_space.cc
+++ b/runtime/gc/collector/semi_space.cc
@@ -590,8 +590,7 @@
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 71a83f2..17da367 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 @@
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 0c14ded..bad8de3 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2277,8 +2277,8 @@
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 @@
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 aee5586..7e0be64 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 a2cccc5..174b350 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 @@
}
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 @@
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 @@
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 @@
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 c5526bb..fe924fb 100644
--- a/runtime/indirect_reference_table.cc
+++ b/runtime/indirect_reference_table.cc
@@ -239,10 +239,10 @@
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 51b2fcf..0202347 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 @@
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 a698c9e..8282fab 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -1142,7 +1142,7 @@
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 29a2459..144b2c5 100644
--- a/runtime/intern_table.cc
+++ b/runtime/intern_table.cc
@@ -60,7 +60,7 @@
} 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::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 2c8148f..938bf2c 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -437,9 +437,7 @@
}
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 @@
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 2c0ea36..6445245 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -166,9 +166,7 @@
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 7e20076..5a4ebd1 100644
--- a/runtime/mirror/art_field.cc
+++ b/runtime/mirror/art_field.cc
@@ -56,9 +56,7 @@
}
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 9bd5e7d..afc1079 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -60,9 +60,7 @@
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 b91dfc1..f9791fa 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -52,9 +52,7 @@
}
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 c36bd98..35130e8 100644
--- a/runtime/mirror/reference.cc
+++ b/runtime/mirror/reference.cc
@@ -33,9 +33,7 @@
}
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 1eb20f7..c2a67e8 100644
--- a/runtime/mirror/stack_trace_element.cc
+++ b/runtime/mirror/stack_trace_element.cc
@@ -68,9 +68,7 @@
}
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 01599ae..e199d0e 100644
--- a/runtime/mirror/string.cc
+++ b/runtime/mirror/string.cc
@@ -224,9 +224,7 @@
}
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 93ed4d4..61d85e2 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -138,9 +138,7 @@
}
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 4b1236a..9fbb938 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -216,7 +216,7 @@
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 592deed..cf81cc5 100644
--- a/runtime/object_callbacks.h
+++ b/runtime/object_callbacks.h
@@ -35,34 +35,10 @@
} // 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 5035463..179110c 100644
--- a/runtime/reference_table.cc
+++ b/runtime/reference_table.cc
@@ -242,10 +242,9 @@
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 6cffa85..22cf1cd 100644
--- a/runtime/reference_table.h
+++ b/runtime/reference_table.h
@@ -49,7 +49,7 @@
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 d6cafcc..346d0a1 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1157,29 +1157,14 @@
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 3558a81..f0b6c21 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -608,4 +608,11 @@
}
}
+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 e58caee..7188d30 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 @@
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 a3eb9fb..2f474f7 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1153,8 +1153,7 @@
}
}
-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 @@
// 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 @@
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 @@
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::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 @@
}
}
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 @@
}
// 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 3647dc4..5460249 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -942,28 +942,6 @@
}
}
-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 9f515a8..3c72190 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 @@
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 04abe64..4d2aec0 100644
--- a/runtime/throw_location.cc
+++ b/runtime/throw_location.cc
@@ -34,11 +34,11 @@
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 b36eb67..bec0da4 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 50f1eca..23b9656 100644
--- a/runtime/transaction.cc
+++ b/runtime/transaction.cc
@@ -172,7 +172,7 @@
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 @@
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 @@
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::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 6625390..83206b2 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 30be82f..ede9866 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -968,9 +968,7 @@
}
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 {