class AllocRecord { public: // All instances of AllocRecord should be managed by an instance of AllocRecordObjectMap.
AllocRecord(size_t count, mirror::Class* klass, AllocRecordStackTrace&& trace)
: byte_count_(count), klass_(klass), trace_(std::move(trace)) {}
private: const size_t byte_count_; // The klass_ could be a strong or weak root for GC
GcRoot<mirror::Class> klass_; // TODO: Share between alloc records with identical stack traces.
AllocRecordStackTrace trace_;
};
// GcRoot<mirror::Object> pointers in the list are weak roots, and the last recent_record_max_ // number of AllocRecord::klass_ pointers are strong roots (and the rest of klass_ pointers are // weak roots). The last recent_record_max_ number of pairs in the list are always kept for DDMS's // recent allocation tracking, but GcRoot<mirror::Object> pointers in these pairs can become null. // Both types of pointers need read barriers, do not directly access them. using EntryPair = std::pair<GcRoot<mirror::Object>, AllocRecord>; using EntryList = std::list<EntryPair>;
// Caller needs to check that it is enabled before calling since we read the stack trace before // checking the enabled boolean.
EXPORT void RecordAllocation(Thread* self, ObjPtr<mirror::Object>* obj, size_t byte_count)
REQUIRES(!Locks::alloc_tracker_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
// Allocation tracking could be enabled by user in between DisallowNewAllocationRecords() and // AllowNewAllocationRecords(), in which case new allocation records can be added although they // should be disallowed. However, this is GC-safe because new objects are not processed in this GC // cycle. The only downside of not handling this case is that such new allocation records can be // swept from the list. But missing the first few records is acceptable for using the button to // enable allocation tracking. void DisallowNewAllocationRecords()
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(Locks::alloc_tracker_lock_); void AllowNewAllocationRecords()
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(Locks::alloc_tracker_lock_); void BroadcastForNewAllocationRecords()
REQUIRES(Locks::alloc_tracker_lock_);
// TODO: Is there a better way to hide the entries_'s type?
EntryList::iterator Begin()
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(Locks::alloc_tracker_lock_) { return entries_.begin();
}
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.