diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-01-14 14:55:47 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2015-01-15 12:23:28 -0800 |
commit | e34fa1df67fbe0173b4ea9abddcc3ae3d0537037 (patch) | |
tree | a5148f079b5671a95f60910c41981ebf91db3a02 /runtime/gc_root.h | |
parent | 9f06b1946ae3ef1d2fd75bbf7f0a288bc611fe58 (diff) | |
download | art-e34fa1df67fbe0173b4ea9abddcc3ae3d0537037.tar.gz art-e34fa1df67fbe0173b4ea9abddcc3ae3d0537037.tar.bz2 art-e34fa1df67fbe0173b4ea9abddcc3ae3d0537037.zip |
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
(cherry picked from commit 12f7423a2bb4bfab76700d84eb6d4338d211983a)
Bug: 18588862
Change-Id: Ic5a2781f704e931265ffb3621c2eab4b2e25f60f
Diffstat (limited to 'runtime/gc_root.h')
-rw-r--r-- | runtime/gc_root.h | 59 |
1 files changed, 56 insertions, 3 deletions
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_; |