summaryrefslogtreecommitdiffstats
path: root/chromium/base/profiler/stack_sampler_impl.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-06 12:48:11 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:33:43 +0000
commit7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (patch)
treefa14ba0ca8d2683ba2efdabd246dc9b18a1229c6 /chromium/base/profiler/stack_sampler_impl.cc
parent79b4f909db1049fca459c07cca55af56a9b54fe3 (diff)
BASELINE: Update Chromium to 84.0.4147.141
Change-Id: Ib85eb4cfa1cbe2b2b81e5022c8cad5c493969535 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/base/profiler/stack_sampler_impl.cc')
-rw-r--r--chromium/base/profiler/stack_sampler_impl.cc118
1 files changed, 54 insertions, 64 deletions
diff --git a/chromium/base/profiler/stack_sampler_impl.cc b/chromium/base/profiler/stack_sampler_impl.cc
index 336decd9f8b..9903b33feea 100644
--- a/chromium/base/profiler/stack_sampler_impl.cc
+++ b/chromium/base/profiler/stack_sampler_impl.cc
@@ -6,8 +6,10 @@
#include <utility>
+#include "base/check.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/profiler/metadata_recorder.h"
#include "base/profiler/profile_builder.h"
#include "base/profiler/sample_metadata.h"
#include "base/profiler/stack_buffer.h"
@@ -31,16 +33,13 @@ namespace {
// the thread is suspended.
class StackCopierDelegate : public StackCopier::Delegate {
public:
- StackCopierDelegate(ModuleCache* module_cache,
- Unwinder* native_unwinder,
- Unwinder* aux_unwinder,
- ProfileBuilder* profile_builder)
- : module_cache_(module_cache),
- native_unwinder_(native_unwinder),
- aux_unwinder_(aux_unwinder),
+ StackCopierDelegate(
+ const base::circular_deque<std::unique_ptr<Unwinder>>* unwinders,
+ ProfileBuilder* profile_builder,
+ MetadataRecorder::MetadataProvider* metadata_provider)
+ : unwinders_(unwinders),
profile_builder_(profile_builder),
- metadata_provider_(
- GetSampleMetadataRecorder()->CreateMetadataProvider()) {}
+ metadata_provider_(metadata_provider) {}
StackCopierDelegate(const StackCopierDelegate&) = delete;
StackCopierDelegate& operator=(const StackCopierDelegate&) = delete;
@@ -51,35 +50,16 @@ class StackCopierDelegate : public StackCopier::Delegate {
// particular, it may not perform any heap allocation or deallocation,
// including indirectly via use of DCHECK/CHECK or other logging statements.
void OnStackCopy() override {
- native_unwinder_->OnStackCapture();
- if (aux_unwinder_)
- aux_unwinder_->OnStackCapture();
-
-#if !defined(OS_POSIX) || defined(OS_MACOSX)
- profile_builder_->RecordMetadata(metadata_provider_.get());
-#else
- // TODO(https://crbug.com/1056283): Support metadata recording on POSIX
- // platforms.
- ALLOW_UNUSED_LOCAL(profile_builder_);
-#endif
- }
-
- void OnThreadResume() override {
- // Reset this as soon as possible because it may hold a lock on the
- // metadata.
- metadata_provider_.reset();
+ for (const auto& unwinder : *unwinders_)
+ unwinder->OnStackCapture();
- native_unwinder_->UpdateModules(module_cache_);
- if (aux_unwinder_)
- aux_unwinder_->UpdateModules(module_cache_);
+ profile_builder_->RecordMetadata(*metadata_provider_);
}
private:
- ModuleCache* const module_cache_;
- Unwinder* const native_unwinder_;
- Unwinder* const aux_unwinder_;
+ const base::circular_deque<std::unique_ptr<Unwinder>>* unwinders_;
ProfileBuilder* const profile_builder_;
- std::unique_ptr<ProfileBuilder::MetadataProvider> metadata_provider_;
+ const MetadataRecorder::MetadataProvider* const metadata_provider_;
};
} // namespace
@@ -89,15 +69,17 @@ StackSamplerImpl::StackSamplerImpl(std::unique_ptr<StackCopier> stack_copier,
ModuleCache* module_cache,
StackSamplerTestDelegate* test_delegate)
: stack_copier_(std::move(stack_copier)),
- native_unwinder_(std::move(native_unwinder)),
module_cache_(module_cache),
- test_delegate_(test_delegate) {}
+ test_delegate_(test_delegate) {
+ DCHECK(native_unwinder);
+ unwinders_.push_front(std::move(native_unwinder));
+}
StackSamplerImpl::~StackSamplerImpl() = default;
void StackSamplerImpl::AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder) {
- aux_unwinder_ = std::move(unwinder);
- aux_unwinder_->AddInitialModules(module_cache_);
+ unwinder->AddInitialModules(module_cache_);
+ unwinders_.push_front(std::move(unwinder));
}
void StackSamplerImpl::RecordStackFrames(StackBuffer* stack_buffer,
@@ -107,19 +89,26 @@ void StackSamplerImpl::RecordStackFrames(StackBuffer* stack_buffer,
RegisterContext thread_context;
uintptr_t stack_top;
TimeTicks timestamp;
- StackCopierDelegate delegate(module_cache_, native_unwinder_.get(),
- aux_unwinder_.get(), profile_builder);
- bool success = stack_copier_->CopyStack(stack_buffer, &stack_top, &timestamp,
- &thread_context, &delegate);
- if (!success)
- return;
+ {
+ // Make this scope as small as possible because |metadata_provider| is
+ // holding a lock.
+ MetadataRecorder::MetadataProvider metadata_provider(
+ GetSampleMetadataRecorder());
+ StackCopierDelegate delegate(&unwinders_, profile_builder,
+ &metadata_provider);
+ bool success = stack_copier_->CopyStack(
+ stack_buffer, &stack_top, &timestamp, &thread_context, &delegate);
+ if (!success)
+ return;
+ }
+ for (const auto& unwinder : unwinders_)
+ unwinder->UpdateModules(module_cache_);
if (test_delegate_)
test_delegate_->OnPreStackWalk();
profile_builder->OnSampleCompleted(
- WalkStack(module_cache_, &thread_context, stack_top,
- native_unwinder_.get(), aux_unwinder_.get()),
+ WalkStack(module_cache_, &thread_context, stack_top, unwinders_),
timestamp);
}
@@ -128,18 +117,16 @@ std::vector<Frame> StackSamplerImpl::WalkStackForTesting(
ModuleCache* module_cache,
RegisterContext* thread_context,
uintptr_t stack_top,
- Unwinder* native_unwinder,
- Unwinder* aux_unwinder) {
- return WalkStack(module_cache, thread_context, stack_top, native_unwinder,
- aux_unwinder);
+ const base::circular_deque<std::unique_ptr<Unwinder>>& unwinders) {
+ return WalkStack(module_cache, thread_context, stack_top, unwinders);
}
// static
-std::vector<Frame> StackSamplerImpl::WalkStack(ModuleCache* module_cache,
- RegisterContext* thread_context,
- uintptr_t stack_top,
- Unwinder* native_unwinder,
- Unwinder* aux_unwinder) {
+std::vector<Frame> StackSamplerImpl::WalkStack(
+ ModuleCache* module_cache,
+ RegisterContext* thread_context,
+ uintptr_t stack_top,
+ const base::circular_deque<std::unique_ptr<Unwinder>>& unwinders) {
std::vector<Frame> stack;
// Reserve enough memory for most stacks, to avoid repeated
// allocations. Approximately 99.9% of recorded stacks are 128 frames or
@@ -154,21 +141,24 @@ std::vector<Frame> StackSamplerImpl::WalkStack(ModuleCache* module_cache,
size_t prior_stack_size;
UnwindResult result;
do {
- // Choose an authoritative unwinder for the current module. Use the aux
- // unwinder if it thinks it can unwind from the current frame, otherwise use
- // the native unwinder.
- Unwinder* unwinder =
- aux_unwinder && aux_unwinder->CanUnwindFrom(stack.back())
- ? aux_unwinder
- : native_unwinder;
+ // Choose an authoritative unwinder for the current module. Use the first
+ // unwinder that thinks it can unwind from the current frame.
+ auto unwinder =
+ std::find_if(unwinders.begin(), unwinders.end(),
+ [&stack](const std::unique_ptr<Unwinder>& unwinder) {
+ return unwinder->CanUnwindFrom(stack.back());
+ });
+ if (unwinder == unwinders.end())
+ return stack;
prior_stack_size = stack.size();
- result =
- unwinder->TryUnwind(thread_context, stack_top, module_cache, &stack);
+ result = unwinder->get()->TryUnwind(thread_context, stack_top, module_cache,
+ &stack);
// The native unwinder should be the only one that returns COMPLETED
// since the stack starts in native code.
- DCHECK(result != UnwindResult::COMPLETED || unwinder == native_unwinder);
+ DCHECK(result != UnwindResult::COMPLETED ||
+ unwinder->get() == unwinders.back().get());
} while (result != UnwindResult::ABORTED &&
result != UnwindResult::COMPLETED &&
// Give up if the authoritative unwinder for the module was unable to