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

Unified Diff: src/sampler.cc

Issue 15957005: Extract common sampling code into SampleHelper (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 7 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 | « no previous file | 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 25478a61ddad530d8a5ceb80b6087adb15746c61..efac288ee72c0870e5d1bee9b04290e94ac7ec1f 100644
--- a/src/sampler.cc
+++ b/src/sampler.cc
@@ -145,23 +145,130 @@ enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 };
namespace v8 {
namespace internal {
-#if defined(USE_SIGNALS)
+namespace {
-class Sampler::PlatformData : public Malloced {
+class PlatformDataCommon : public Malloced {
public:
- PlatformData()
- : vm_tid_(pthread_self()),
- profiled_thread_id_(ThreadId::Current()) {}
+ PlatformDataCommon() : profiled_thread_id_(ThreadId::Current()) {}
+ ThreadId profiled_thread_id() { return profiled_thread_id_; }
+
+ protected:
+ ~PlatformDataCommon() {}
+
+ private:
+ ThreadId profiled_thread_id_;
+};
+
+} // namespace
+#if defined(USE_SIGNALS)
+
+class Sampler::PlatformData : public PlatformDataCommon {
+ public:
+ PlatformData() : vm_tid_(pthread_self()) {}
pthread_t vm_tid() const { return vm_tid_; }
- ThreadId profiled_thread_id() { return profiled_thread_id_; }
private:
pthread_t vm_tid_;
- ThreadId profiled_thread_id_;
+};
+
+#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__)
+
+// ----------------------------------------------------------------------------
+// Win32 profiler support. On Cygwin we use the same sampler implementation as
+// on Win32.
+
+class Sampler::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
+ // for some reason doesn't work in Chrome's sandbox.
+ PlatformData()
+ : profiled_thread_(OpenThread(THREAD_GET_CONTEXT |
+ THREAD_SUSPEND_RESUME |
+ THREAD_QUERY_INFORMATION,
+ false,
+ GetCurrentThreadId())) {}
+
+ ~PlatformData() {
+ if (profiled_thread_ != NULL) {
+ CloseHandle(profiled_thread_);
+ profiled_thread_ = NULL;
+ }
+ }
+
+ HANDLE profiled_thread() { return profiled_thread_; }
+
+ private:
+ HANDLE profiled_thread_;
+};
+#endif
+
+
+class SampleHelper {
+ public:
+ inline TickSample* Init(Sampler* sampler, Isolate* isolate) {
+#if defined(USE_SIMULATOR)
+ ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
+ Isolate::PerIsolateThreadData* per_thread_data = isolate->
+ FindPerThreadDataForThread(thread_id);
+ if (!per_thread_data) return NULL;
+ simulator_ = per_thread_data->simulator();
+ // Check if there is active simulator before allocating TickSample.
+ if (!simulator_) return NULL;
+#endif // USE_SIMULATOR
+ TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
+ if (sample == NULL) sample = &sample_obj;
+ return sample;
+ }
+
+#if defined(USE_SIMULATOR)
+ inline void FillRegisters(TickSample* sample) {
+ sample->pc = reinterpret_cast<Address>(simulator_->get_pc());
+ sample->sp = reinterpret_cast<Address>(simulator_->get_register(
+ Simulator::sp));
+#if V8_TARGET_ARCH_ARM
+ sample->fp = reinterpret_cast<Address>(simulator_->get_register(
+ Simulator::r11));
+#elif V8_TARGET_ARCH_MIPS
+ sample->fp = reinterpret_cast<Address>(simulator_->get_register(
+ Simulator::fp));
+#endif
+ }
+#endif // USE_SIMULATOR
+
+ private:
+#if defined(USE_SIMULATOR)
+ Simulator* simulator_;
+#endif
+ TickSample sample_obj;
};
+#if defined(USE_SIGNALS)
+
class SignalHandler : public AllStatic {
public:
static inline void EnsureInstalled() {
@@ -217,30 +324,12 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
Sampler* sampler = isolate->logger()->sampler();
if (sampler == NULL || !sampler->IsActive()) return;
-#if defined(USE_SIMULATOR)
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
- ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
- Isolate::PerIsolateThreadData* per_thread_data = isolate->
- FindPerThreadDataForThread(thread_id);
- if (!per_thread_data) return;
- Simulator* sim = per_thread_data->simulator();
- // Check if there is active simulator before allocating TickSample.
- if (!sim) return;
-#endif
-#endif // USE_SIMULATOR
-
- TickSample sample_obj;
- TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
- if (sample == NULL) sample = &sample_obj;
+ SampleHelper helper;
+ TickSample* sample = helper.Init(sampler, isolate);
+ if (sample == NULL) return;
#if defined(USE_SIMULATOR)
- sample->pc = reinterpret_cast<Address>(sim->get_pc());
- sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp));
-#if V8_TARGET_ARCH_ARM
- sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11));
-#elif V8_TARGET_ARCH_MIPS
- sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp));
-#endif // V8_TARGET_ARCH_*
+ helper.FillRegisters(sample);
#else
// Extracting the sample from the context is extremely machine dependent.
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
@@ -321,65 +410,6 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
#endif // __native_client__
}
-#elif defined(__MACH__)
-class Sampler::PlatformData : public Malloced {
- public:
- PlatformData()
- : profiled_thread_(mach_thread_self()),
- profiled_thread_id_(ThreadId::Current()) {}
-
- ~PlatformData() {
- // Deallocate Mach port for thread.
- mach_port_deallocate(mach_task_self(), profiled_thread_);
- }
-
- thread_act_t profiled_thread() { return profiled_thread_; }
- ThreadId profiled_thread_id() { return profiled_thread_id_; }
-
- 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_;
- ThreadId profiled_thread_id_;
-};
-
-#elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
-
-// ----------------------------------------------------------------------------
-// Win32 profiler support. On Cygwin we use the same sampler implementation as
-// on Win32.
-
-class Sampler::PlatformData : public Malloced {
- 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
- // for some reason doesn't work in Chrome's sandbox.
- PlatformData()
- : profiled_thread_(OpenThread(THREAD_GET_CONTEXT |
- THREAD_SUSPEND_RESUME |
- THREAD_QUERY_INFORMATION,
- false,
- GetCurrentThreadId())),
- profiled_thread_id_(ThreadId::Current()) {}
-
- ~PlatformData() {
- if (profiled_thread_ != NULL) {
- CloseHandle(profiled_thread_);
- profiled_thread_ = NULL;
- }
- }
-
- HANDLE profiled_thread() { return profiled_thread_; }
- ThreadId profiled_thread_id() { return profiled_thread_id_; }
-
- private:
- HANDLE profiled_thread_;
- ThreadId profiled_thread_id_;
-};
-
#endif
@@ -476,20 +506,10 @@ class SamplerThread : public Thread {
void SampleContext(Sampler* sampler) {
thread_act_t profiled_thread = sampler->platform_data()->profiled_thread();
Isolate* isolate = sampler->isolate();
-#if defined(USE_SIMULATOR)
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
- ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
- Isolate::PerIsolateThreadData* per_thread_data = isolate->
- FindPerThreadDataForThread(thread_id);
- if (!per_thread_data) return;
- Simulator* sim = per_thread_data->simulator();
- // Check if there is active simulator before allocating TickSample.
- if (!sim) return;
-#endif
-#endif // USE_SIMULATOR
- TickSample sample_obj;
- TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
- if (sample == NULL) sample = &sample_obj;
+
+ SampleHelper helper;
+ TickSample* sample = helper.Init(sampler, isolate);
+ if (sample == NULL) return;
if (KERN_SUCCESS != thread_suspend(profiled_thread)) return;
@@ -521,13 +541,7 @@ class SamplerThread : public Thread {
&count) == KERN_SUCCESS) {
sample->state = isolate->current_vm_state();
#if defined(USE_SIMULATOR)
- sample->pc = reinterpret_cast<Address>(sim->get_pc());
- sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp));
-#if V8_TARGET_ARCH_ARM
- sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11));
-#elif V8_TARGET_ARCH_MIPS
- sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp));
-#endif
+ helper.FillRegisters(sample);
#else
sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
@@ -546,40 +560,22 @@ class SamplerThread : public Thread {
HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
if (profiled_thread == NULL) return;
- // Context used for sampling the register state of the profiled thread.
- CONTEXT context;
- memset(&context, 0, sizeof(context));
-
Isolate* isolate = sampler->isolate();
-#if defined(USE_SIMULATOR)
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
- ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
- Isolate::PerIsolateThreadData* per_thread_data = isolate->
- FindPerThreadDataForThread(thread_id);
- if (!per_thread_data) return;
- Simulator* sim = per_thread_data->simulator();
- // Check if there is active simulator before allocating TickSample.
- if (!sim) return;
-#endif
-#endif // USE_SIMULATOR
- TickSample sample_obj;
- TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
- if (sample == NULL) sample = &sample_obj;
+ SampleHelper helper;
+ TickSample* sample = helper.Init(sampler, isolate);
+ if (sample == NULL) return;
- static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
+ const DWORD kSuspendFailed = static_cast<DWORD>(-1);
if (SuspendThread(profiled_thread) == kSuspendFailed) return;
sample->state = isolate->current_vm_state();
+ // 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) {
#if defined(USE_SIMULATOR)
- sample->pc = reinterpret_cast<Address>(sim->get_pc());
- sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp));
-#if V8_TARGET_ARCH_ARM
- sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11));
-#elif V8_TARGET_ARCH_MIPS
- sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp));
-#endif
+ helper.FillRegisters(sample);
#else
#if V8_HOST_ARCH_X64
sample->pc = reinterpret_cast<Address>(context.Rip);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698