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

Unified Diff: src/sampler.cc

Issue 422593003: Initial GetSample implementation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Moved thread logic out of GetSample Created 6 years, 3 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
« src/sampler.h ('K') | « src/sampler.h ('k') | test/cctest/cctest.gyp » ('j') | 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..36bce177a79a6ab23aa10499936459cf090360e5 100644
--- a/src/sampler.cc
+++ b/src/sampler.cc
@@ -1,7 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-
alph 2014/09/17 11:55:43 plz revert.
#include "src/sampler.h"
#if V8_OS_POSIX && !V8_OS_CYGWIN
@@ -44,6 +43,7 @@
#include "src/v8.h"
+#include "src/base/logging.h"
#include "src/base/platform/platform.h"
#include "src/cpu-profiler-inl.h"
#include "src/flags.h"
@@ -269,8 +269,24 @@ 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_ != NULL && sampling_semaphore_ != NULL)
+ return; // Already setup
alph 2014/09/17 11:55:42 no need for the comment.
+
+ ASSERT_EQ(NULL, mutex_);
+ ASSERT_EQ(NULL, sampling_semaphore_);
+
+ mutex_ = new base::Mutex();
+ sampling_semaphore_ = new base::Semaphore(0);
+ }
+
+ static void TearDown() {
+ delete mutex_;
+ delete sampling_semaphore_;
+
+ mutex_ = NULL;
+ sampling_semaphore_ = NULL;
+ }
static void IncreaseSamplerCount() {
base::LockGuard<base::Mutex> lock_guard(mutex_);
@@ -308,14 +324,45 @@ class SignalHandler : public AllStatic {
}
static void HandleProfilerSignal(int signal, siginfo_t* info, void* context);
+
+ // The SIGPROF could have come from DoSample or from GetSample.
+ // GetSample is the internal endpoint for the public
+ // GetSample API, which aims to bypass all the internal buffers
+ // and return just one sample instead, rightaway.
+ //
+ // The origin of SIGPROF is determined by FLAG_new_sampler_api
+ //
+ // TODO(gholap): Eventually, get rid of DoSample.
+ // Only GetSample should remain.
+ // Then, get rid of FLAG_new_sampler_api too.
+
+ // This is the sample which will be filled by the call from GetSample.
+ static TickSample sample_;
+
+ // GetSample waits synchronously till the SIGPROF handler returns.
+ // this semaphore is used to signal GetSample.
+ static base::Semaphore* sampling_semaphore_;
+
+ // It is not that every time HandleProfilerSignal is invoked,
+ // it succeeds in obtaining a sample.
+ // This provides GetSample with the information whether
+ // the handler finished with or without getting the sample.
+ static bool sample_available_;
+
// Protects the process wide state below.
static base::Mutex* mutex_;
static int client_count_;
static bool signal_handler_installed_;
static struct sigaction old_signal_handler_;
+
+ friend class Sampler;
};
+TickSample SignalHandler::sample_;
+base::Semaphore* SignalHandler::sampling_semaphore_ = NULL;
+bool SignalHandler::sample_available_ = false;
+
base::Mutex* SignalHandler::mutex_ = NULL;
int SignalHandler::client_count_ = 0;
struct sigaction SignalHandler::old_signal_handler_;
@@ -329,6 +376,11 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
// is disabled.
return;
#else
+ // Even if we return prematurely,
+ // we need to signal the sampling_semaphore_
+ sample_available_ = false;
+ ScopedSemaphore scoped_semaphore(sampling_semaphore_);
+
USE(info);
if (signal != SIGPROF) return;
Isolate* isolate = Isolate::UncheckedReentrantCurrent();
@@ -466,7 +518,12 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
#endif // V8_HOST_ARCH_*
#endif // V8_OS_QNX
#endif // USE_SIMULATOR
- sampler->SampleStack(state);
+ if (FLAG_new_sampler_api) {
+ sample_.Init(sampler->isolate(), state);
+ sample_available_ = true;
+ } else {
+ sampler->SampleStack(state);
+ }
#endif // V8_OS_NACL
}
@@ -569,6 +626,7 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate,
timestamp = base::TimeTicks::HighResolutionNow();
pc = regs.pc;
state = isolate->current_vm_state();
+ frames_count = 0;
// Avoid collecting traces while doing GC.
if (state == GC) return;
@@ -621,6 +679,16 @@ void Sampler::TearDown() {
}
+void Sampler::SetUpForNewSamplingAPI() {
+#if defined(USE_SIGNALS)
+ SignalHandler::SetUp();
+ if (!SignalHandler::Installed())
+ SignalHandler::Install();
+#endif
+ // Nothing needs to be done for windows.
+}
+
+
Sampler::Sampler(Isolate* isolate, int interval)
: isolate_(isolate),
interval_(interval),
@@ -693,8 +761,34 @@ void Sampler::DoSample() {
pthread_kill(platform_data()->vm_tid(), SIGPROF);
}
+
+void Sampler::GetSample(v8::Sample* sample) {
+ SignalHandler::sampling_semaphore_->Wait();
+ if (SignalHandler::sample_available_) {
+ sample = new(sample) v8::Sample(
+ &SignalHandler::sample_.stack[0],
+ &SignalHandler::sample_.stack[SignalHandler::sample_.frames_count]);
+ }
+ else {
+ sample = new(sample) v8::Sample();
+ }
+}
+
#elif V8_OS_WIN || V8_OS_CYGWIN
+#if V8_HOST_ARCH_X64
+#define CONTEXT_TO_STATE(context, state) \
+ state.pc = reinterpret_cast<Address>(context.Rip); \
+ state.sp = reinterpret_cast<Address>(context.Rsp); \
+ state.fp = reinterpret_cast<Address>(context.Rbp)
+#else
+#define CONTEXT_TO_STATE(context, state) \
+ state.pc = reinterpret_cast<Address>(context.Eip); \
+ state.sp = reinterpret_cast<Address>(context.Esp); \
+ state.fp = reinterpret_cast<Address>(context.Ebp)
+#endif
+
+
void Sampler::DoSample() {
HANDLE profiled_thread = platform_data()->profiled_thread();
if (profiled_thread == NULL) return;
@@ -716,21 +810,25 @@ void Sampler::DoSample() {
#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
+ CONTEXT_TO_STATE(context, state);
#endif // USE_SIMULATOR
SampleStack(state);
}
ResumeThread(profiled_thread);
}
+
+void Sampler::GetSample(Isolate* isolate,
+ const CONTEXT& context,
+ v8::Sample* sample) {
+ TickSample tick_sample;
+ RegisterState state;
+ CONTEXT_TO_STATE(context, state);
+ tick_sample.Init(isolate, state);
+ sample = new(sample) v8::Sample(&tick_sample.stack[0],
+ &tick_sample.stack[tick_sample.frames_count]);
+}
+
#endif // USE_SIGNALS
« src/sampler.h ('K') | « src/sampler.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698