#include"base/locks.h"// For Locks::mutator_lock_. #include"base/macros.h" #include"mirror/object_reference.h" #include"read_barrier_option.h"
namespace art HIDDEN { class ArtField; class ArtMethod; template<class MirrorType> class ObjPtr;
namespace mirror { class Object;
} // namespace mirror
template <size_t kBufferSize> class BufferedRootVisitor;
// Dependent on pointer size so that we don't have frames that are too big on 64 bit. staticconst size_t kDefaultBufferedRootCount = 1024 / sizeof(void*);
enum RootType {
kRootUnknown = 0,
kRootJNIGlobal,
kRootJNILocal,
kRootJavaFrame,
kRootNativeStack,
kRootStickyClass,
kRootThreadBlock,
kRootMonitorUsed,
kRootThreadObject,
kRootInternedString,
kRootFinalizing, // used for HPROF's conversion to HprofHeapTag
kRootDebugger,
kRootReferenceCleanup, // used for HPROF's conversion to HprofHeapTag
kRootVMInternal,
kRootJNIMonitor,
};
EXPORT std::ostream& operator<<(std::ostream& os, RootType root_type);
// Only used by hprof. thread_id_ and type_ are only used by hprof. 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) {
}
RootInfo(const RootInfo&) = default; virtual ~RootInfo() {
}
RootType GetType() const { return type_;
}
uint32_t GetThreadId() const { return thread_id_;
} virtualvoid Describe(std::ostream& os) const {
os << "Type=" << type_ << " thread_id=" << thread_id_;
}
std::string ToString() const;
// Not all combinations of flags are valid. You may not visit all roots as well as the new roots // (no logical reason to do this). You also may not start logging new roots and stop logging new // roots (also no logical reason to do this). // // The precise flag ensures that more metadata is supplied. An example is vreg data for compiled // method frames. enum VisitRootFlags : uint8_t {
kVisitRootFlagAllRoots = (1 << 0),
kVisitRootFlagNewRoots = (1 << 1),
kVisitRootFlagStartLoggingNewRoots = (1 << 2),
kVisitRootFlagStopLoggingNewRoots = (1 << 3),
kVisitRootFlagClearRootLog = (1 << 4),
kVisitRootFlagClassLoader = (1 << 5), // There is no (1 << 6).
kVisitRootFlagPrecise = (1 << 7),
};
class RootVisitor { public: virtual ~RootVisitor() { }
// Single root version, not overridable.
ALWAYS_INLINE void VisitRoot(mirror::Object** root, const RootInfo& info)
REQUIRES_SHARED(Locks::mutator_lock_) {
VisitRoots(&root, 1, info);
}
// Single root version, not overridable.
ALWAYS_INLINE void VisitRootIfNonNull(mirror::Object** root, const RootInfo& info)
REQUIRES_SHARED(Locks::mutator_lock_) { if (*root != nullptr) {
VisitRoot(root, info);
}
}
// Only visits roots one at a time, doesn't handle updating roots. Used when performance isn't // critical. class SingleRootVisitor : public RootVisitor { private: void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info) override
REQUIRES_SHARED(Locks::mutator_lock_) { for (size_t i = 0; i < count; ++i) {
VisitRoot(*roots[i], info);
}
}
void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count, const RootInfo& info) override
REQUIRES_SHARED(Locks::mutator_lock_) { for (size_t i = 0; i < count; ++i) {
VisitRoot(roots[i]->AsMirrorPtr(), info);
}
}
// A small CompressedReference wrapper class that makes it harder to forget about read barriers. // Used for references that are roots for an object graph, whether or not they are actually traced // from. Requires an explicit VisitRoots call for tracing. See also Handle (implicitly traced by a // GC) and StackReference (traced explicitly, but not as the result of a read barrier). template<class MirrorType> class GcRoot { public: template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
ALWAYS_INLINE MirrorType* Read(GcRootSource* gc_root_source = nullptr) const
REQUIRES_SHARED(Locks::mutator_lock_);
// TODO: This is often called repeatedly from functions to process an explicit array of roots. // And it calls a function that takes an array of roots. By processing a single root at a time // here and turning it into a 1-element array, do we lose performance? Or does the compiler // eliminate the extra work? void VisitRoot(RootVisitor* visitor, const RootInfo& info) const
REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(!IsNull());
mirror::CompressedReference<mirror::Object>* roots[1] = { &root_ };
visitor->VisitRoots(roots, 1u, info);
DCHECK(!IsNull());
}
private: // Root visitors take pointers to root_ and place them in CompressedReference** arrays. We use a // CompressedReference<mirror::Object> here since it violates strict aliasing requirements to // cast CompressedReference<MirrorType>* to CompressedReference<mirror::Object>*. mutable mirror::CompressedReference<mirror::Object> root_;
// Simple data structure for buffered root visiting to avoid virtual dispatch overhead. Currently // only for CompressedReferences since these are more common than the Object** roots which are only // for thread local roots. template <size_t kBufferSize> class BufferedRootVisitor { public:
BufferedRootVisitor(RootVisitor* visitor, const RootInfo& root_info)
: visitor_(visitor), root_info_(root_info), buffer_pos_(0) {
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.