Commit 1d6b43ae authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

Revert "[Sampling profiler] Use cross-platform sampling implementation for Mac"

This reverts commit f99a085f.

Reason for revert: Broke iOS build

Original change's description:
> [Sampling profiler] Use cross-platform sampling implementation for Mac
> 
> Refactors the Mac sampling to use the StackSamplerImpl implementation,
> with the platform-specific aspects moved into ThreadDelegateMac.
> 
> Bug: 931418
> Change-Id: I8f468fa09b9ddc85921f21563ff41000a5c968f5
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1535178
> Reviewed-by: Lei Zhang <thestig@chromium.org>
> Reviewed-by: Leonard Grey <lgrey@chromium.org>
> Commit-Queue: Mike Wittman <wittman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#644804}

TBR=thestig@chromium.org,wittman@chromium.org,lgrey@chromium.org

Change-Id: I3f50a2117449abca9c58d89b13febab3889b421b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 931418
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1541586Reviewed-by: default avatarMike Wittman <wittman@chromium.org>
Commit-Queue: Mike Wittman <wittman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#644810}
parent 5409d7be
......@@ -626,8 +626,6 @@ jumbo_component("base") {
"profiler/stack_sampling_profiler.cc",
"profiler/stack_sampling_profiler.h",
"profiler/thread_delegate.h",
"profiler/thread_delegate_mac.cc",
"profiler/thread_delegate_mac.h",
"profiler/thread_delegate_win.cc",
"profiler/thread_delegate_win.h",
"profiler/unwind_result.h",
......
......@@ -9,29 +9,13 @@
#ifndef BASE_PROFILER_REGISTER_CONTEXT_H_
#define BASE_PROFILER_REGISTER_CONTEXT_H_
#include <type_traits>
#include "build/build_config.h"
#if defined(OS_WIN)
#include <windows.h>
#elif defined(OS_MACOSX)
#include <mach/machine/thread_status.h>
#endif
// Helper function to account for the fact that platform-specific register state
// types may be unsigned and of the same size as uintptr_t, but not of the same
// type -- e.g. unsigned int vs. unsigned long on 32-bit Windows and unsigned
// long vs. unsigned long long on Mac.
template <typename T>
uintptr_t& AsUintPtr(T* value) {
static_assert(std::is_unsigned<T>::value && sizeof(T) == sizeof(uintptr_t),
"register state type must be equivalent to uintptr_t");
return *reinterpret_cast<uintptr_t*>(value);
}
#if defined(OS_WIN)
using RegisterContext = ::CONTEXT;
inline uintptr_t& RegisterContextStackPointer(::CONTEXT* context) {
......@@ -40,7 +24,10 @@ inline uintptr_t& RegisterContextStackPointer(::CONTEXT* context) {
#elif defined(ARCH_CPU_ARM64)
return context->Sp;
#else
return AsUintPtr(&context->Esp);
// The reinterpret_cast accounts for the fact that Esp is a DWORD, which is an
// unsigned long, while uintptr_t is an unsigned int. The two types have the
// same representation on Windows, but C++ treats them as different.
return *reinterpret_cast<uintptr_t*>(&context->Esp);
#endif
}
......@@ -50,24 +37,13 @@ inline uintptr_t& RegisterContextFramePointer(::CONTEXT* context) {
#elif defined(ARCH_CPU_ARM64)
return context->Fp;
#else
return AsUintPtr(&context->Ebp);
// The reinterpret_cast accounts for the fact that Ebp is a DWORD, which is an
// unsigned long, while uintptr_t is an unsigned int. The two types have the
// same representation on Windows, but C++ treats them as different.
return *reinterpret_cast<uintptr_t*>(&context->Ebp);
#endif
}
#elif defined(OS_MACOSX) // #if defined(OS_WIN)
using RegisterContext = x86_thread_state64_t;
inline uintptr_t& RegisterContextStackPointer(x86_thread_state64_t* context) {
return AsUintPtr(&context->__rsp);
}
inline uintptr_t& RegisterContextFramePointer(x86_thread_state64_t* context) {
return AsUintPtr(&context->__rbp);
}
#else // #if defined(OS_WIN)
#else // #if defined(OS_WIN)
// Placeholders for other platforms.
struct RegisterContext {
uintptr_t stack_pointer;
......@@ -81,7 +57,6 @@ inline uintptr_t& RegisterContextStackPointer(RegisterContext* context) {
inline uintptr_t& RegisterContextFramePointer(RegisterContext* context) {
return context->frame_pointer;
}
#endif // #if defined(OS_WIN)
#endif // BASE_PROFILER_REGISTER_CONTEXT_H_
......@@ -86,24 +86,21 @@ void StackSamplerImpl::RecordStackFrames(StackBuffer* stack_buffer,
DCHECK(stack_buffer);
RegisterContext thread_context;
uintptr_t stack_top;
bool success =
CopyStack(stack_buffer, &stack_top, profile_builder, &thread_context);
bool success = CopyStack(stack_buffer, profile_builder, &thread_context);
if (!success)
return;
if (test_delegate_)
test_delegate_->OnPreStackWalk();
profile_builder->OnSampleCompleted(WalkStack(&thread_context, stack_top));
profile_builder->OnSampleCompleted(WalkStack(&thread_context));
}
// Suspends the thread, copies its stack, top address of the stack copy, and
// register context, records the current metadata, then resumes the thread.
// Returns true on success, and returns the copied state via the params. NO HEAP
// ALLOCATIONS within the ScopedSuspendThread scope.
// Suspends the thread, copies its stack and register context, and records the
// current metadata, then resumes the thread. Returns true on success, and
// returns the copied state via the params. NO HEAP ALLOCATIONS within the
// ScopedSuspendThread scope.
bool StackSamplerImpl::CopyStack(StackBuffer* stack_buffer,
uintptr_t* stack_top,
ProfileBuilder* profile_builder,
RegisterContext* thread_context) {
const uintptr_t top = thread_delegate_->GetStackBaseAddress();
......@@ -139,9 +136,6 @@ bool StackSamplerImpl::CopyStack(StackBuffer* stack_buffer,
stack_buffer->buffer());
}
*stack_top =
reinterpret_cast<uintptr_t>(stack_buffer->buffer()) + (top - bottom);
for (uintptr_t* reg :
thread_delegate_->GetRegistersToRewrite(thread_context)) {
*reg = RewritePointerIfInOriginalStack(reinterpret_cast<uintptr_t*>(bottom),
......@@ -155,16 +149,14 @@ bool StackSamplerImpl::CopyStack(StackBuffer* stack_buffer,
// Walks the stack represented by |thread_context|, recording and returning the
// frames.
std::vector<ProfileBuilder::Frame> StackSamplerImpl::WalkStack(
RegisterContext* thread_context,
uintptr_t stack_top) {
RegisterContext* thread_context) {
std::vector<ProfileBuilder::Frame> stack;
// Reserve enough memory for most stacks, to avoid repeated
// allocations. Approximately 99.9% of recorded stacks are 128 frames or
// fewer.
stack.reserve(128);
thread_delegate_->WalkNativeFrames(thread_context, stack_top, module_cache_,
&stack);
thread_delegate_->WalkNativeFrames(thread_context, module_cache_, &stack);
return stack;
}
......
......@@ -34,12 +34,10 @@ class BASE_EXPORT StackSamplerImpl : public StackSampler {
private:
bool CopyStack(StackBuffer* stack_buffer,
uintptr_t* stack_top,
ProfileBuilder* profile_builder,
RegisterContext* thread_context);
std::vector<ProfileBuilder::Frame> WalkStack(RegisterContext* thread_context,
uintptr_t stack_top);
std::vector<ProfileBuilder::Frame> WalkStack(RegisterContext* thread_context);
const std::unique_ptr<ThreadDelegate> thread_delegate_;
ModuleCache* const module_cache_;
......
......@@ -96,7 +96,6 @@ class TestThreadDelegate : public ThreadDelegate {
UnwindResult WalkNativeFrames(
RegisterContext* thread_context,
uintptr_t stack_top,
ModuleCache* module_cache,
std::vector<ProfileBuilder::Frame>* stack) override {
if (stack_copy_) {
......
This diff is collapsed.
......@@ -72,7 +72,6 @@ class BASE_EXPORT ThreadDelegate {
// TODO(wittman): Move the unwinding support into a separate UnwindDelegate.
virtual UnwindResult WalkNativeFrames(
RegisterContext* thread_context,
uintptr_t stack_top,
ModuleCache* module_cache,
std::vector<ProfileBuilder::Frame>* stack) = 0;
};
......
This diff is collapsed.
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_PROFILER_THREAD_DELEGATE_MAC_H_
#define BASE_PROFILER_THREAD_DELEGATE_MAC_H_
#include <mach/mach.h>
#include "base/base_export.h"
#include "base/profiler/thread_delegate.h"
#include "base/sampling_heap_profiler/module_cache.h"
#include "base/threading/platform_thread.h"
namespace base {
// Platform- and thread-specific implementation in support of stack sampling on
// Mac.
class BASE_EXPORT ThreadDelegateMac : public ThreadDelegate {
public:
class ScopedSuspendThread : public ThreadDelegate::ScopedSuspendThread {
public:
explicit ScopedSuspendThread(mach_port_t thread_port);
~ScopedSuspendThread() override;
ScopedSuspendThread(const ScopedSuspendThread&) = delete;
ScopedSuspendThread& operator=(const ScopedSuspendThread&) = delete;
bool WasSuccessful() const override;
private:
mach_port_t thread_port_;
};
ThreadDelegateMac(mach_port_t thread_port, ModuleCache* module_cache);
~ThreadDelegateMac() override;
ThreadDelegateMac(const ThreadDelegateMac&) = delete;
ThreadDelegateMac& operator=(const ThreadDelegateMac&) = delete;
// ThreadDelegate
std::unique_ptr<ThreadDelegate::ScopedSuspendThread>
CreateScopedSuspendThread() override;
bool GetThreadContext(x86_thread_state64_t* thread_context) override;
uintptr_t GetStackBaseAddress() const override;
bool CanCopyStack(uintptr_t stack_pointer) override;
std::vector<uintptr_t*> GetRegistersToRewrite(
x86_thread_state64_t* thread_context) override;
UnwindResult WalkNativeFrames(
x86_thread_state64_t* thread_context,
uintptr_t stack_top,
ModuleCache* module_cache,
std::vector<ProfileBuilder::Frame>* stack) override;
private:
// Weak reference: Mach port for thread being profiled.
mach_port_t thread_port_;
// The stack base address corresponding to |thread_port_|.
const uintptr_t thread_stack_base_address_;
// Cached pointer to the libsystem_kernel module.
const ModuleCache::Module* const libsystem_kernel_module_;
// The address range of |_sigtramp|, the signal trampoline function.
uintptr_t sigtramp_start_;
uintptr_t sigtramp_end_;
};
} // namespace base
#endif // BASE_PROFILER_THREAD_DELEGATE_MAC_H_
......@@ -202,7 +202,6 @@ std::vector<uintptr_t*> ThreadDelegateWin::GetRegistersToRewrite(
UnwindResult ThreadDelegateWin::WalkNativeFrames(
CONTEXT* thread_context,
uintptr_t stack_top,
ModuleCache* module_cache,
std::vector<ProfileBuilder::Frame>* stack) {
Win32StackFrameUnwinder frame_unwinder;
......
......@@ -49,7 +49,6 @@ class BASE_EXPORT ThreadDelegateWin : public ThreadDelegate {
UnwindResult WalkNativeFrames(
CONTEXT* thread_context,
uintptr_t stack_top,
ModuleCache* module_cache,
std::vector<ProfileBuilder::Frame>* stack) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment