| Index: base/debug/activity_analyzer.cc
|
| diff --git a/base/debug/activity_analyzer.cc b/base/debug/activity_analyzer.cc
|
| index 0c30d8d0c213c2e973dec707cc439d97e58e3fe7..1040207c83f389c5789ad17ab7fbce4c35591520 100644
|
| --- a/base/debug/activity_analyzer.cc
|
| +++ b/base/debug/activity_analyzer.cc
|
| @@ -17,7 +17,7 @@ namespace debug {
|
|
|
| ThreadActivityAnalyzer::ThreadActivityAnalyzer(
|
| const ThreadActivityTracker& tracker)
|
| - : activity_snapshot_valid_(tracker.Snapshot(&activity_snapshot_)) {}
|
| + : activity_snapshot_valid_(tracker.CreateSnapshot(&activity_snapshot_)) {}
|
|
|
| ThreadActivityAnalyzer::ThreadActivityAnalyzer(void* base, size_t size)
|
| : ThreadActivityAnalyzer(ThreadActivityTracker(base, size)) {}
|
| @@ -33,6 +33,29 @@ ThreadActivityAnalyzer::ThreadActivityAnalyzer(
|
|
|
| ThreadActivityAnalyzer::~ThreadActivityAnalyzer() {}
|
|
|
| +void ThreadActivityAnalyzer::AddGlobalInformation(
|
| + GlobalActivityAnalyzer* global) {
|
| + if (!IsValid())
|
| + return;
|
| +
|
| + // User-data is held at the global scope even though it's referenced an the
|
| + // thread scope.
|
| + user_data_snapshots_.clear();
|
| + for (auto& activity : activity_snapshot_.activity_stack) {
|
| + if (activity.user_data_ref) {
|
| + ActivityUserData::Snapshot user_data = global->GetUserDataSnapshot(
|
| + activity.user_data_ref, activity.user_data_id);
|
| + user_data_snapshots_.push_back(std::move(user_data));
|
| + }
|
| + }
|
| +}
|
| +
|
| +const ActivityUserData::Snapshot& ThreadActivityAnalyzer::GetUserDataSnapshot(
|
| + size_t stack_index) {
|
| + DCHECK_GT(user_data_snapshots_.size(), stack_index);
|
| + return user_data_snapshots_[stack_index];
|
| +}
|
| +
|
| GlobalActivityAnalyzer::GlobalActivityAnalyzer(
|
| std::unique_ptr<PersistentMemoryAllocator> allocator)
|
| : allocator_(std::move(allocator)), allocator_iterator_(allocator_.get()) {}
|
| @@ -83,6 +106,46 @@ ThreadActivityAnalyzer* GlobalActivityAnalyzer::GetAnalyzerForThread(
|
| return found->second.get();
|
| }
|
|
|
| +ActivityUserData::Snapshot GlobalActivityAnalyzer::GetUserDataSnapshot(
|
| + uint32_t ref,
|
| + uint32_t id) {
|
| + ActivityUserData::Snapshot snapshot;
|
| +
|
| + void* memory = allocator_->GetAsArray<char>(
|
| + ref, GlobalActivityTracker::kTypeIdUserDataRecord,
|
| + PersistentMemoryAllocator::kSizeAny);
|
| + if (memory) {
|
| + size_t size = allocator_->GetAllocSize(ref);
|
| + const ActivityUserData user_data(memory, size);
|
| + user_data.CreateSnapshot(&snapshot);
|
| + if (user_data.id() != id) {
|
| + // This allocation has been overwritten since it was created. Return an
|
| + // empty snapshot because whatever was captured is incorrect.
|
| + snapshot.clear();
|
| + }
|
| + }
|
| +
|
| + return snapshot;
|
| +}
|
| +
|
| +ActivityUserData::Snapshot GlobalActivityAnalyzer::GetGlobalUserDataSnapshot() {
|
| + ActivityUserData::Snapshot snapshot;
|
| +
|
| + PersistentMemoryAllocator::Reference ref =
|
| + PersistentMemoryAllocator::Iterator(allocator_.get())
|
| + .GetNextOfType(GlobalActivityTracker::kTypeIdGlobalDataRecord);
|
| + void* memory = allocator_->GetAsArray<char>(
|
| + ref, GlobalActivityTracker::kTypeIdGlobalDataRecord,
|
| + PersistentMemoryAllocator::kSizeAny);
|
| + if (memory) {
|
| + size_t size = allocator_->GetAllocSize(ref);
|
| + const ActivityUserData global_data(memory, size);
|
| + global_data.CreateSnapshot(&snapshot);
|
| + }
|
| +
|
| + return snapshot;
|
| +}
|
| +
|
| GlobalActivityAnalyzer::ProgramLocation
|
| GlobalActivityAnalyzer::GetProgramLocationFromAddress(uint64_t address) {
|
| // TODO(bcwhite): Implement this.
|
| @@ -123,6 +186,7 @@ void GlobalActivityAnalyzer::PrepareAllAnalyzers() {
|
| base, allocator_->GetAllocSize(tracker_ref)));
|
| if (!analyzer->IsValid())
|
| continue;
|
| + analyzer->AddGlobalInformation(this);
|
|
|
| // Add this analyzer to the map of known ones, indexed by a unique thread
|
| // identifier.
|
|
|