| Index: content/renderer/devtools/v8_sampling_profiler.cc
|
| diff --git a/content/renderer/devtools/v8_sampling_profiler.cc b/content/renderer/devtools/v8_sampling_profiler.cc
|
| index 8f3821b063b4511553f99ad8eaca0e643a57aca5..df8fdd2166ed0c5c8ae2bce9230a771321d45ead 100644
|
| --- a/content/renderer/devtools/v8_sampling_profiler.cc
|
| +++ b/content/renderer/devtools/v8_sampling_profiler.cc
|
| @@ -9,15 +9,16 @@
|
| #define USE_SIGNALS
|
| #endif
|
|
|
| +#if defined(OS_WIN)
|
| +#include <windows.h>
|
| +#endif
|
| +
|
| #include "base/format_macros.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/synchronization/cancellation_flag.h"
|
| #include "base/threading/platform_thread.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "base/trace_event/trace_event_argument.h"
|
| -#if defined(OS_WIN)
|
| -#include "base/win/scoped_handle.h"
|
| -#endif
|
| #include "content/renderer/devtools/lock_free_circular_queue.h"
|
| #include "content/renderer/render_thread_impl.h"
|
| #include "v8/include/v8.h"
|
| @@ -31,10 +32,55 @@ namespace content {
|
|
|
| namespace {
|
|
|
| -#if defined(OS_WIN)
|
| -typedef base::win::ScopedHandle UniversalThreadHandle;
|
| -#else
|
| -typedef base::PlatformThreadHandle UniversalThreadHandle;
|
| +class PlatformDataCommon {
|
| + public:
|
| + base::PlatformThreadId thread_id() { return thread_id_; }
|
| +
|
| + protected:
|
| + PlatformDataCommon() : thread_id_(base::PlatformThread::CurrentId()) {}
|
| +
|
| + private:
|
| + base::PlatformThreadId thread_id_;
|
| +};
|
| +
|
| +#if defined(USE_SIGNALS)
|
| +
|
| +class PlatformData : public PlatformDataCommon {
|
| + public:
|
| + PlatformData() : vm_tid_(pthread_self()) {}
|
| + pthread_t vm_tid() const { return vm_tid_; }
|
| +
|
| + private:
|
| + pthread_t vm_tid_;
|
| +};
|
| +
|
| +#elif defined(OS_WIN)
|
| +
|
| +class PlatformData : public PlatformDataCommon {
|
| + public:
|
| + // Get a handle to the calling thread. This is the thread that we are
|
| + // going to profile. We need to make a copy of the handle because we are
|
| + // going to use it in the sampler thread. Using GetThreadHandle() will
|
| + // not work in this case. We're using OpenThread because DuplicateHandle
|
| + // doesn't work in Chrome's sandbox.
|
| + PlatformData()
|
| + : thread_handle_(::OpenThread(THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME |
|
| + THREAD_QUERY_INFORMATION,
|
| + false,
|
| + ::GetCurrentThreadId())) {}
|
| +
|
| + ~PlatformData() {
|
| + if (thread_handle_ == NULL)
|
| + return;
|
| + ::CloseHandle(thread_handle_);
|
| + thread_handle_ = NULL;
|
| + }
|
| +
|
| + HANDLE thread_handle() { return thread_handle_; }
|
| +
|
| + private:
|
| + HANDLE thread_handle_;
|
| +};
|
| #endif
|
|
|
| std::string PtrToString(const void* value) {
|
| @@ -145,15 +191,13 @@ class Sampler {
|
| static void HandleJitCodeEvent(const v8::JitCodeEvent* event);
|
| static scoped_refptr<ConvertableToTraceFormat> JitCodeEventToTraceFormat(
|
| const v8::JitCodeEvent* event);
|
| - static UniversalThreadHandle GetCurrentThreadHandle();
|
|
|
| void InjectPendingEvents();
|
|
|
| static const unsigned kNumberOfSamples = 10;
|
| typedef LockFreeCircularQueue<SampleRecord, kNumberOfSamples> SamplingQueue;
|
|
|
| - base::PlatformThreadId thread_id_;
|
| - UniversalThreadHandle thread_handle_;
|
| + PlatformData platform_data_;
|
| Isolate* isolate_;
|
| scoped_ptr<SamplingQueue> samples_data_;
|
| base::subtle::Atomic32 code_added_events_count_;
|
| @@ -169,9 +213,7 @@ base::LazyInstance<base::ThreadLocalPointer<Sampler>>::Leaky
|
| Sampler::tls_instance_ = LAZY_INSTANCE_INITIALIZER;
|
|
|
| Sampler::Sampler()
|
| - : thread_id_(base::PlatformThread::CurrentId()),
|
| - thread_handle_(Sampler::GetCurrentThreadHandle()),
|
| - isolate_(Isolate::GetCurrent()),
|
| + : isolate_(Isolate::GetCurrent()),
|
| code_added_events_count_(0),
|
| samples_count_(0),
|
| code_added_events_to_collect_for_test_(0),
|
| @@ -191,17 +233,6 @@ scoped_ptr<Sampler> Sampler::CreateForCurrentThread() {
|
| return scoped_ptr<Sampler>(new Sampler());
|
| }
|
|
|
| -// static
|
| -UniversalThreadHandle Sampler::GetCurrentThreadHandle() {
|
| -#ifdef OS_WIN
|
| - return base::win::ScopedHandle(::OpenThread(
|
| - THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION,
|
| - false, base::PlatformThread::CurrentId()));
|
| -#else
|
| - return base::PlatformThread::CurrentHandle();
|
| -#endif
|
| -}
|
| -
|
| void Sampler::Start() {
|
| samples_data_.reset(new SamplingQueue());
|
| v8::JitCodeEventHandler handler = &HandleJitCodeEvent;
|
| @@ -223,12 +254,12 @@ void Sampler::Stop() {
|
| void Sampler::Sample() {
|
| #if defined(OS_WIN)
|
| const DWORD kSuspendFailed = static_cast<DWORD>(-1);
|
| - if (::SuspendThread(thread_handle_.Get()) == kSuspendFailed)
|
| + if (::SuspendThread(platform_data_.thread_handle()) == kSuspendFailed)
|
| return;
|
| CONTEXT context;
|
| memset(&context, 0, sizeof(context));
|
| context.ContextFlags = CONTEXT_FULL;
|
| - if (::GetThreadContext(thread_handle_.Get(), &context) != 0) {
|
| + if (::GetThreadContext(platform_data_.thread_handle(), &context) != 0) {
|
| v8::RegisterState state;
|
| state.pc = reinterpret_cast<void*>(context.REG_64_32(Rip, Eip));
|
| state.sp = reinterpret_cast<void*>(context.REG_64_32(Rsp, Esp));
|
| @@ -237,9 +268,9 @@ void Sampler::Sample() {
|
| // We can just collect and fire trace event right away.
|
| DoSample(state);
|
| }
|
| - ::ResumeThread(thread_handle_.Get());
|
| + ::ResumeThread(platform_data_.thread_handle());
|
| #elif defined(USE_SIGNALS)
|
| - int error = pthread_kill(thread_handle_.platform_handle(), SIGPROF);
|
| + int error = pthread_kill(platform_data_.vm_tid(), SIGPROF);
|
| if (error) {
|
| LOG(ERROR) << "pthread_kill failed with error " << error << " "
|
| << strerror(error);
|
| @@ -263,7 +294,8 @@ void Sampler::InjectPendingEvents() {
|
| SampleRecord* record = samples_data_->Peek();
|
| while (record) {
|
| TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP1(
|
| - TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"), "V8Sample", thread_id_,
|
| + TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"), "V8Sample",
|
| + platform_data_.thread_id(),
|
| (record->timestamp() - base::TimeTicks()).InMicroseconds(), "data",
|
| record->ToTraceFormat());
|
| samples_data_->Remove();
|
|
|