Commit 3ca49d9a authored by lpy's avatar lpy Committed by Commit bot

Split Ticker into two samplers.

Currently there are two logic in Ticker, one is to try to request a
pre-allocated TickSample from CpuProfiler and then initialize it, and if the
request fails, it will initialize a local TickSample. The other is it will pass
an initialized TickSample to Profiler to log into v8.log.

This patch splits Ticker into two samplers, the first one remains in log.cc to
collect samples and pass to Profiler for logging, the second one will be called
by ProfilerEventsProcessor, and only use the circular queue only.

BUG=v8:4789
LOG=N

Review-Url: https://codereview.chromium.org/2108393002
Cr-Commit-Position: refs/heads/master@{#37506}
parent b7533337
......@@ -644,6 +644,7 @@ class Ticker: public sampler::Sampler {
}
void SampleStack(const v8::RegisterState& state) override {
if (!profiler_) return;
v8::Isolate* v8_isolate = isolate();
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
#if defined(USE_SIMULATOR)
......@@ -651,18 +652,9 @@ class Ticker: public sampler::Sampler {
const_cast<v8::RegisterState*>(&state)))
return;
#endif
TickSample* sample = isolate->cpu_profiler()->StartTickSample();
TickSample sample_obj;
if (sample == NULL) sample = &sample_obj;
sample->Init(isolate, state, TickSample::kIncludeCEntryFrame, true);
if (is_counting_samples_ && !sample->timestamp.IsNull()) {
if (sample->state == JS) ++js_sample_count_;
if (sample->state == EXTERNAL) ++external_sample_count_;
}
if (profiler_) profiler_->Insert(sample);
if (sample != &sample_obj) {
isolate->cpu_profiler()->FinishTickSample();
}
TickSample sample;
sample.Init(isolate, state, TickSample::kIncludeCEntryFrame, true);
profiler_->Insert(&sample);
}
private:
......
......@@ -50,17 +50,6 @@ void ReportBuiltinEventRecord::UpdateCodeMap(CodeMap* code_map) {
}
TickSample* CpuProfiler::StartTickSample() {
if (is_profiling_) return processor_->StartTickSample();
return NULL;
}
void CpuProfiler::FinishTickSample() {
processor_->FinishTickSample();
}
TickSample* ProfilerEventsProcessor::StartTickSample() {
void* address = ticks_buffer_.StartEnqueue();
if (address == NULL) return NULL;
......
......@@ -19,21 +19,51 @@ namespace internal {
static const int kProfilerStackSize = 64 * KB;
class CpuSampler : public sampler::Sampler {
public:
CpuSampler(Isolate* isolate, ProfilerEventsProcessor* processor)
: sampler::Sampler(reinterpret_cast<v8::Isolate*>(isolate)),
processor_(processor) {}
void SampleStack(const v8::RegisterState& state) override {
v8::Isolate* v8_isolate = isolate();
Isolate* i_isolate = reinterpret_cast<Isolate*>(v8_isolate);
#if defined(USE_SIMULATOR)
v8::RegisterState regs;
if (!SimulatorHelper::FillRegisters(i_isolate, &regs)) return;
#else
const v8::RegisterState& regs = state;
#endif
TickSample* sample = processor_->StartTickSample();
if (sample == NULL) return;
sample->Init(i_isolate, regs, TickSample::kIncludeCEntryFrame, true);
if (is_counting_samples_ && !sample->timestamp.IsNull()) {
if (sample->state == JS) ++js_sample_count_;
if (sample->state == EXTERNAL) ++external_sample_count_;
}
processor_->FinishTickSample();
}
private:
ProfilerEventsProcessor* processor_;
};
ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator,
sampler::Sampler* sampler,
ProfilerEventsProcessor::ProfilerEventsProcessor(Isolate* isolate,
ProfileGenerator* generator,
base::TimeDelta period)
: Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)),
generator_(generator),
sampler_(sampler),
sampler_(new CpuSampler(isolate, this)),
running_(1),
period_(period),
last_code_event_id_(0),
last_processed_code_event_id_(0) {}
ProfilerEventsProcessor::~ProfilerEventsProcessor() {}
last_processed_code_event_id_(0) {
sampler_->IncreaseProfilingDepth();
}
ProfilerEventsProcessor::~ProfilerEventsProcessor() {
sampler_->DecreaseProfilingDepth();
}
void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) {
event.generic.order = last_code_event_id_.Increment(1);
......@@ -283,9 +313,8 @@ void CpuProfiler::StartProcessorIfNotStarted() {
// Disable logging when using the new implementation.
saved_is_logging_ = logger->is_logging_;
logger->is_logging_ = false;
sampler::Sampler* sampler = logger->sampler();
generator_.reset(new ProfileGenerator(profiles_.get()));
processor_.reset(new ProfilerEventsProcessor(generator_.get(), sampler,
processor_.reset(new ProfilerEventsProcessor(isolate_, generator_.get(),
sampling_interval_));
logger->SetUpProfilerListener();
ProfilerListener* profiler_listener = logger->profiler_listener();
......@@ -301,8 +330,6 @@ void CpuProfiler::StartProcessorIfNotStarted() {
logger->LogAccessorCallbacks();
LogBuiltins();
// Enable stack sampling.
sampler->SetHasProcessingThread(true);
sampler->IncreaseProfilingDepth();
processor_->AddCurrentStack(isolate_);
processor_->StartSynchronously();
}
......@@ -336,8 +363,6 @@ void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
void CpuProfiler::StopProcessor() {
Logger* logger = isolate_->logger();
sampler::Sampler* sampler =
reinterpret_cast<sampler::Sampler*>(logger->ticker_);
is_profiling_ = false;
isolate_->set_is_profiling(false);
ProfilerListener* profiler_listener = logger->profiler_listener();
......@@ -346,8 +371,6 @@ void CpuProfiler::StopProcessor() {
logger->TearDownProfilerListener();
processor_.reset();
generator_.reset();
sampler->SetHasProcessingThread(false);
sampler->DecreaseProfilingDepth();
logger->is_logging_ = saved_is_logging_;
}
......
......@@ -133,8 +133,7 @@ class CodeEventsContainer {
// methods called by event producers: VM and stack sampler threads.
class ProfilerEventsProcessor : public base::Thread {
public:
ProfilerEventsProcessor(ProfileGenerator* generator,
sampler::Sampler* sampler,
ProfilerEventsProcessor(Isolate* isolate, ProfileGenerator* generator,
base::TimeDelta period);
virtual ~ProfilerEventsProcessor();
......@@ -160,6 +159,8 @@ class ProfilerEventsProcessor : public base::Thread {
void* operator new(size_t size);
void operator delete(void* ptr);
sampler::Sampler* sampler() { return sampler_.get(); }
private:
// Called from events processing thread (Run() method.)
bool ProcessCodeEvent();
......@@ -172,7 +173,7 @@ class ProfilerEventsProcessor : public base::Thread {
SampleProcessingResult ProcessOneSample();
ProfileGenerator* generator_;
sampler::Sampler* sampler_;
std::unique_ptr<sampler::Sampler> sampler_;
base::Atomic32 running_;
const base::TimeDelta period_; // Samples & code events processing period.
LockedQueue<CodeEventsContainer> events_buffer_;
......@@ -209,10 +210,6 @@ class CpuProfiler : public CodeEventObserver {
void CodeEventHandler(const CodeEventsContainer& evt_rec) override;
// Invoked from stack sampler (thread or signal handler.)
inline TickSample* StartTickSample();
inline void FinishTickSample();
bool is_profiling() const { return is_profiling_; }
ProfileGenerator* generator() const { return generator_.get(); }
......
......@@ -71,7 +71,7 @@ TEST(StartStop) {
CpuProfilesCollection profiles(CcTest::i_isolate());
ProfileGenerator generator(&profiles);
std::unique_ptr<ProfilerEventsProcessor> processor(
new ProfilerEventsProcessor(&generator, nullptr,
new ProfilerEventsProcessor(CcTest::i_isolate(), &generator,
v8::base::TimeDelta::FromMicroseconds(100)));
processor->Start();
processor->StopSynchronously();
......@@ -155,8 +155,9 @@ TEST(CodeEvents) {
CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate);
ProfileGenerator* generator = new ProfileGenerator(profiles);
ProfilerEventsProcessor* processor = new ProfilerEventsProcessor(
generator, nullptr, v8::base::TimeDelta::FromMicroseconds(100));
ProfilerEventsProcessor* processor =
new ProfilerEventsProcessor(CcTest::i_isolate(), generator,
v8::base::TimeDelta::FromMicroseconds(100));
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
......@@ -223,8 +224,9 @@ TEST(TickEvents) {
CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate);
ProfileGenerator* generator = new ProfileGenerator(profiles);
ProfilerEventsProcessor* processor = new ProfilerEventsProcessor(
generator, nullptr, v8::base::TimeDelta::FromMicroseconds(100));
ProfilerEventsProcessor* processor =
new ProfilerEventsProcessor(CcTest::i_isolate(), generator,
v8::base::TimeDelta::FromMicroseconds(100));
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
......@@ -295,8 +297,9 @@ TEST(Issue1398) {
CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate);
ProfileGenerator* generator = new ProfileGenerator(profiles);
ProfilerEventsProcessor* processor = new ProfilerEventsProcessor(
generator, nullptr, v8::base::TimeDelta::FromMicroseconds(100));
ProfilerEventsProcessor* processor =
new ProfilerEventsProcessor(CcTest::i_isolate(), generator,
v8::base::TimeDelta::FromMicroseconds(100));
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
......@@ -437,8 +440,9 @@ static v8::CpuProfile* RunProfiler(v8::Local<v8::Context> env,
cpu_profiler->SetSamplingInterval(100);
cpu_profiler->StartProfiling(profile_name, collect_samples);
v8::sampler::Sampler* sampler =
reinterpret_cast<i::Isolate*>(env->GetIsolate())->logger()->sampler();
v8::internal::CpuProfiler* i_cpu_profiler =
reinterpret_cast<v8::internal::CpuProfiler*>(cpu_profiler);
v8::sampler::Sampler* sampler = i_cpu_profiler->processor()->sampler();
sampler->StartCountingSamples();
do {
function->Call(env, env->Global(), argc, argv).ToLocalChecked();
......@@ -1038,8 +1042,9 @@ static void TickLines(bool optimize) {
CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate);
ProfileGenerator* generator = new ProfileGenerator(profiles);
ProfilerEventsProcessor* processor = new ProfilerEventsProcessor(
generator, nullptr, v8::base::TimeDelta::FromMicroseconds(100));
ProfilerEventsProcessor* processor =
new ProfilerEventsProcessor(CcTest::i_isolate(), generator,
v8::base::TimeDelta::FromMicroseconds(100));
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment