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

Unified Diff: src/sampler.cc

Issue 422593003: Initial GetSample implementation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Moved the thread pausing logic inside Sampler::GetSample Created 6 years, 5 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
« include/v8-sampler.h ('K') | « src/sampler.h ('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 0ed4b379626a9746038b6e05b1661cee522f4f1f..c7e7c0f2b6723aed1d90d4e36d25feab12d8b991 100644
--- a/src/sampler.cc
+++ b/src/sampler.cc
@@ -42,6 +42,8 @@
#endif
+#include "include/v8-sampler.h"
+
#include "src/v8.h"
#include "src/base/platform/platform.h"
@@ -269,8 +271,16 @@ class SimulatorHelper {
class SignalHandler : public AllStatic {
public:
- static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); }
- static void TearDown() { delete mutex_; }
+ static void SetUp() {
+ if (!mutex_) mutex_ = new base::Mutex();
+ if (!register_state_semaphore_)
+ register_state_semaphore_ = new base::Semaphore(0);
+ }
+
+ static void TearDown() {
+ delete mutex_;
+ delete register_state_semaphore_;
+ }
static void IncreaseSamplerCount() {
base::LockGuard<base::Mutex> lock_guard(mutex_);
@@ -286,6 +296,17 @@ class SignalHandler : public AllStatic {
return signal_handler_installed_;
}
+ static RegisterState GetRegisterState() {
+ register_state_semaphore_->Wait();
+ register_state_updated_ = false;
+ return register_state_;
+ }
+
+ static bool WasRegisterStateUpdated() {
+ return register_state_updated_;
+ }
+
+
private:
static void Install() {
struct sigaction sa;
@@ -308,6 +329,18 @@ class SignalHandler : public AllStatic {
}
static void HandleProfilerSignal(int signal, siginfo_t* info, void* context);
+
+ // HandleProfilerSignal puts the state of registers into
+ // register_state_ and then signals on the semaphore,
+ // so that DoSample can use it.
+ static base::Semaphore* register_state_semaphore_;
+ static RegisterState register_state_;
+ // It is not that every time HandleProfilerSignal is invoked,
+ // the register state is guarenteed to be updated.
+ // This provides the SIGPROF sender with the information whether
+ // the handler finished with or without updating the register state.
+ static bool register_state_updated_;
+
// Protects the process wide state below.
static base::Mutex* mutex_;
static int client_count_;
@@ -321,6 +354,9 @@ int SignalHandler::client_count_ = 0;
struct sigaction SignalHandler::old_signal_handler_;
bool SignalHandler::signal_handler_installed_ = false;
+base::Semaphore* SignalHandler::register_state_semaphore_ = NULL;
+RegisterState SignalHandler::register_state_;
+bool SignalHandler::register_state_updated_ = false;
void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
void* context) {
@@ -466,7 +502,9 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
#endif // V8_HOST_ARCH_*
#endif // V8_OS_QNX
#endif // USE_SIMULATOR
- sampler->SampleStack(state);
+ register_state_ = state;
+ register_state_updated_ = true;
+ register_state_semaphore_->Signal();
#endif // V8_OS_NACL
}
@@ -564,7 +602,8 @@ SamplerThread* SamplerThread::instance_ = NULL;
// StackTracer implementation
//
DISABLE_ASAN void TickSample::Init(Isolate* isolate,
- const RegisterState& regs) {
+ const RegisterState& regs,
+ unsigned max_frame_count) {
ASSERT(isolate->IsInitialized());
timestamp = base::TimeTicks::HighResolutionNow();
pc = regs.pc;
@@ -597,7 +636,9 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate,
SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp);
top_frame_type = it.top_frame_type();
unsigned i = 0;
- while (!it.done() && i < TickSample::kMaxFramesCount) {
+ if (max_frame_count > kMaxFramesCount)
+ max_frame_count = kMaxFramesCount;
+ while (!it.done() && i < max_frame_count) {
stack[i++] = it.frame()->pc();
it.Advance();
}
@@ -688,14 +729,33 @@ void Sampler::SampleStack(const RegisterState& state) {
#if defined(USE_SIGNALS)
-void Sampler::DoSample() {
+void Sampler::CaptureRegisterState_() {
if (!SignalHandler::Installed()) return;
pthread_kill(platform_data()->vm_tid(), SIGPROF);
}
-#elif V8_OS_WIN || V8_OS_CYGWIN
void Sampler::DoSample() {
+ CaptureRegisterState_();
+ if (SignalHandler::WasRegisterStateUpdated())
+ SampleStack(SignalHandler::GetRegisterState());
+}
+
+
+void Sampler::GetSample(TickSample* sample, unsigned max_frame_count) {
+ CaptureRegisterState_();
+ if (SignalHandler::WasRegisterStateUpdated())
+ sample->Init(isolate_,
+ SignalHandler::GetRegisterState(),
+ max_frame_count);
+}
+
+#elif V8_OS_WIN || V8_OS_CYGWIN
+
+void Sampler::CaptureRegisterState_(RegisterState* state,
+ bool* captured_successfully) {
+ *captured_successfully = false;
+
HANDLE profiled_thread = platform_data()->profiled_thread();
if (profiled_thread == NULL) return;
@@ -712,25 +772,41 @@ void Sampler::DoSample() {
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);
+ 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);
+ 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);
+ *captured_successfully = true;
}
ResumeThread(profiled_thread);
}
+
+void Sampler::DoSample() {
+ bool register_state_captured;
+ RegisterState state;
+ CaptureRegisterState_(state, register_state_captured);
+ if (register_state_captured) SampleStack(state);
+}
+
+
+void Sampler::GetSample(TickSample* sample, unsigned max_frame_count) {
+ bool register_state_captured;
+ RegisterState state;
+ CaptureRegisterState_(state, register_state_captured);
+ if (register_state_captured)
+ sample->Init(isolate_, state, max_frame_count);
+}
+
#endif // USE_SIGNALS
« include/v8-sampler.h ('K') | « src/sampler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698