Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Unified Diff: src/sampler.cc

Issue 23115005: Use signals for cpu profiling on Mac OS X (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/cpu-profiler.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/sampler.cc
diff --git a/src/sampler.cc b/src/sampler.cc
index 52b03853d35c2df1ba6462d07aa56ba3d91c1b52..fa8c2e80ecd98b42d59642055f4bcbd63a44a57e 100644
--- a/src/sampler.cc
+++ b/src/sampler.cc
@@ -29,7 +29,7 @@
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
|| defined(__NetBSD__) || defined(__sun) || defined(__ANDROID__) \
- || defined(__native_client__)
+ || defined(__native_client__) || defined(__MACH__)
#define USE_SIGNALS
@@ -38,9 +38,12 @@
#include <signal.h>
#include <sys/time.h>
#include <sys/syscall.h>
+
+#if defined(__MACH__)
+#include <mach/mach.h>
// OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h>
// and is a typedef for struct sigcontext. There is no uc_mcontext.
-#if (!defined(__ANDROID__) || defined(__BIONIC_HAVE_UCONTEXT_T)) \
+#elif(!defined(__ANDROID__) || defined(__BIONIC_HAVE_UCONTEXT_T)) \
&& !defined(__OpenBSD__)
#include <ucontext.h>
#endif
@@ -53,10 +56,6 @@
#include <asm/sigcontext.h>
#endif
-#elif defined(__MACH__)
-
-#include <mach/mach.h>
-
#elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#include "win32-headers.h"
@@ -174,33 +173,12 @@ class PlatformDataCommon : public Malloced {
class Sampler::PlatformData : public PlatformDataCommon {
public:
PlatformData() : vm_tid_(pthread_self()) {}
-
- void SendProfilingSignal() const;
+ pthread_t vm_tid() const { return vm_tid_; }
private:
pthread_t vm_tid_;
};
-#elif defined(__MACH__)
-
-class Sampler::PlatformData : public PlatformDataCommon {
- public:
- PlatformData() : profiled_thread_(mach_thread_self()) {}
-
- ~PlatformData() {
- // Deallocate Mach port for thread.
- mach_port_deallocate(mach_task_self(), profiled_thread_);
- }
-
- thread_act_t profiled_thread() { return profiled_thread_; }
-
- private:
- // Note: for profiled_thread_ Mach primitives are used instead of PThread's
- // because the latter doesn't provide thread manipulation primitives required.
- // For details, consult "Mac OS X Internals" book, Section 7.3.
- thread_act_t profiled_thread_;
-};
-
#elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
// ----------------------------------------------------------------------------
@@ -365,6 +343,28 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
state.sp = reinterpret_cast<Address>(mcontext.gregs[29]);
state.fp = reinterpret_cast<Address>(mcontext.gregs[30]);
#endif // V8_HOST_ARCH_*
+#elif defined(__MACH__)
+#if V8_HOST_ARCH_X64
+#if __DARWIN_UNIX03
+ state.pc = reinterpret_cast<Address>(mcontext->__ss.__rip);
+ state.sp = reinterpret_cast<Address>(mcontext->__ss.__rsp);
+ state.fp = reinterpret_cast<Address>(mcontext->__ss.__rbp);
+#else // !__DARWIN_UNIX03
+ state.pc = reinterpret_cast<Address>(mcontext->ss.rip);
+ state.sp = reinterpret_cast<Address>(mcontext->ss.rsp);
+ state.fp = reinterpret_cast<Address>(mcontext->ss.rbp);
+#endif // __DARWIN_UNIX03
+#elif V8_HOST_ARCH_IA32
+#if __DARWIN_UNIX03
+ state.pc = reinterpret_cast<Address>(mcontext->__ss.__eip);
+ state.sp = reinterpret_cast<Address>(mcontext->__ss.__esp);
+ state.fp = reinterpret_cast<Address>(mcontext->__ss.__ebp);
+#else // !__DARWIN_UNIX03
+ state.pc = reinterpret_cast<Address>(mcontext->ss.eip);
+ state.sp = reinterpret_cast<Address>(mcontext->ss.esp);
+ state.fp = reinterpret_cast<Address>(mcontext->ss.ebp);
+#endif // __DARWIN_UNIX03
+#endif // V8_HOST_ARCH_IA32
#elif defined(__FreeBSD__)
#if V8_HOST_ARCH_IA32
state.pc = reinterpret_cast<Address>(mcontext.mc_eip);
@@ -482,7 +482,7 @@ class SamplerThread : public Thread {
Sampler* sampler = active_samplers_.at(i);
if (!sampler->isolate()->IsInitialized()) continue;
if (!sampler->IsProfiling()) continue;
- SampleContext(sampler);
+ sampler->DoSample();
}
}
OS::Sleep(interval_);
@@ -490,107 +490,6 @@ class SamplerThread : public Thread {
}
private:
-#if defined(USE_SIGNALS)
-
- void SampleContext(Sampler* sampler) {
- sampler->platform_data()->SendProfilingSignal();
- }
-
-#elif defined(__MACH__)
-
- void SampleContext(Sampler* sampler) {
- thread_act_t profiled_thread = sampler->platform_data()->profiled_thread();
-
-#if defined(USE_SIMULATOR)
- SimulatorHelper helper;
- Isolate* isolate = sampler->isolate();
- if (!helper.Init(sampler, isolate)) return;
-#endif
-
- if (KERN_SUCCESS != thread_suspend(profiled_thread)) return;
-
-#if V8_HOST_ARCH_X64
- thread_state_flavor_t flavor = x86_THREAD_STATE64;
- x86_thread_state64_t thread_state;
- mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
-#if __DARWIN_UNIX03
-#define REGISTER_FIELD(name) __r ## name
-#else
-#define REGISTER_FIELD(name) r ## name
-#endif // __DARWIN_UNIX03
-#elif V8_HOST_ARCH_IA32
- thread_state_flavor_t flavor = i386_THREAD_STATE;
- i386_thread_state_t thread_state;
- mach_msg_type_number_t count = i386_THREAD_STATE_COUNT;
-#if __DARWIN_UNIX03
-#define REGISTER_FIELD(name) __e ## name
-#else
-#define REGISTER_FIELD(name) e ## name
-#endif // __DARWIN_UNIX03
-#else
-#error Unsupported Mac OS X host architecture.
-#endif // V8_HOST_ARCH
-
- if (thread_get_state(profiled_thread,
- flavor,
- reinterpret_cast<natural_t*>(&thread_state),
- &count) == KERN_SUCCESS) {
- RegisterState state;
-#if defined(USE_SIMULATOR)
- helper.FillRegisters(&state);
-#else
- state.pc = reinterpret_cast<Address>(thread_state.REGISTER_FIELD(ip));
- state.sp = reinterpret_cast<Address>(thread_state.REGISTER_FIELD(sp));
- state.fp = reinterpret_cast<Address>(thread_state.REGISTER_FIELD(bp));
-#endif // USE_SIMULATOR
-#undef REGISTER_FIELD
- sampler->SampleStack(state);
- }
- thread_resume(profiled_thread);
- }
-
-#elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
-
- void SampleContext(Sampler* sampler) {
- HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
- if (profiled_thread == NULL) return;
-
- Isolate* isolate = sampler->isolate();
-#if defined(USE_SIMULATOR)
- SimulatorHelper helper;
- if (!helper.Init(sampler, isolate)) return;
-#endif
-
- const DWORD kSuspendFailed = static_cast<DWORD>(-1);
- if (SuspendThread(profiled_thread) == kSuspendFailed) return;
-
- // Context used for sampling the register state of the profiled thread.
- CONTEXT context;
- memset(&context, 0, sizeof(context));
- context.ContextFlags = CONTEXT_FULL;
- if (GetThreadContext(profiled_thread, &context) != 0) {
- RegisterState state;
-#if defined(USE_SIMULATOR)
- helper.FillRegisters(&state);
-#else
-#if V8_HOST_ARCH_X64
- state.pc = reinterpret_cast<Address>(context.Rip);
- state.sp = reinterpret_cast<Address>(context.Rsp);
- state.fp = reinterpret_cast<Address>(context.Rbp);
-#else
- state.pc = reinterpret_cast<Address>(context.Eip);
- state.sp = reinterpret_cast<Address>(context.Esp);
- state.fp = reinterpret_cast<Address>(context.Ebp);
-#endif
-#endif // USE_SIMULATOR
- sampler->SampleStack(state);
- }
- ResumeThread(profiled_thread);
- }
-
-#endif // USE_SIGNALS
-
-
// Protects the process wide state below.
static Mutex* mutex_;
static SamplerThread* instance_;
@@ -606,14 +505,6 @@ Mutex* SamplerThread::mutex_ = NULL;
SamplerThread* SamplerThread::instance_ = NULL;
-#if defined(USE_SIGNALS)
-void Sampler::PlatformData::SendProfilingSignal() const {
- if (!SignalHandler::Installed()) return;
- pthread_kill(vm_tid_, SIGPROF);
-}
-#endif
-
-
//
// StackTracer implementation
//
@@ -726,10 +617,52 @@ bool Sampler::CanSampleOnProfilerEventsProcessorThread() {
}
-void Sampler::DoSample() {
#if defined(USE_SIGNALS)
- platform_data()->SendProfilingSignal();
+
+void Sampler::DoSample() {
+ if (!SignalHandler::Installed()) return;
+ pthread_kill(platform_data()->vm_tid(), SIGPROF);
+}
+
+#elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
+
+void Sampler::DoSample() {
+ HANDLE profiled_thread = platform_data()->profiled_thread();
+ if (profiled_thread == NULL) return;
+
+#if defined(USE_SIMULATOR)
+ SimulatorHelper helper;
+ if (!helper.Init(this, isolate())) return;
#endif
+
+ const DWORD kSuspendFailed = static_cast<DWORD>(-1);
+ if (SuspendThread(profiled_thread) == kSuspendFailed) return;
+
+ // Context used for sampling the register state of the profiled thread.
+ CONTEXT context;
+ memset(&context, 0, sizeof(context));
+ context.ContextFlags = CONTEXT_FULL;
+ if (GetThreadContext(profiled_thread, &context) != 0) {
+ RegisterState state;
+#if defined(USE_SIMULATOR)
+ helper.FillRegisters(&state);
+#else
+#if V8_HOST_ARCH_X64
+ state.pc = reinterpret_cast<Address>(context.Rip);
+ state.sp = reinterpret_cast<Address>(context.Rsp);
+ state.fp = reinterpret_cast<Address>(context.Rbp);
+#else
+ state.pc = reinterpret_cast<Address>(context.Eip);
+ state.sp = reinterpret_cast<Address>(context.Esp);
+ state.fp = reinterpret_cast<Address>(context.Ebp);
+#endif
+#endif // USE_SIMULATOR
+ SampleStack(state);
+ }
+ ResumeThread(profiled_thread);
}
+#endif // USE_SIGNALS
+
+
} } // namespace v8::internal
« no previous file with comments | « src/cpu-profiler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698