Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/profiler/cpu-profiler.h" | 5 #include "src/profiler/cpu-profiler.h" |
| 6 | 6 |
| 7 #include "src/debug/debug.h" | 7 #include "src/debug/debug.h" |
| 8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
| 9 #include "src/frames-inl.h" | 9 #include "src/frames-inl.h" |
| 10 #include "src/locked-queue-inl.h" | 10 #include "src/locked-queue-inl.h" |
| 11 #include "src/log-inl.h" | 11 #include "src/log-inl.h" |
| 12 #include "src/profiler/cpu-profiler-inl.h" | 12 #include "src/profiler/cpu-profiler-inl.h" |
| 13 #include "src/vm-state-inl.h" | 13 #include "src/vm-state-inl.h" |
| 14 | 14 |
| 15 #include "include/v8-profiler.h" | 15 #include "include/v8-profiler.h" |
| 16 | 16 |
| 17 namespace v8 { | 17 namespace v8 { |
| 18 namespace internal { | 18 namespace internal { |
| 19 | 19 |
| 20 static const int kProfilerStackSize = 64 * KB; | 20 static const int kProfilerStackSize = 64 * KB; |
| 21 | 21 |
| 22 class CpuSampler : public sampler::Sampler { | |
| 23 public: | |
| 24 CpuSampler(Isolate* isolate, ProfilerEventsProcessor* processor) | |
| 25 : sampler::Sampler(reinterpret_cast<v8::Isolate*>(isolate)), | |
| 26 processor_(processor) {} | |
| 22 | 27 |
| 23 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator, | 28 void SampleStack(const v8::RegisterState& state) override { |
| 24 sampler::Sampler* sampler, | 29 v8::Isolate* v8_isolate = isolate(); |
| 30 Isolate* i_isolate = reinterpret_cast<Isolate*>(v8_isolate); | |
| 31 v8::RegisterState regs; | |
| 32 #if defined(USE_SIMULATOR) | |
| 33 if (!SimulatorHelper::FillRegisters(i_isolate, ®s)) return; | |
| 34 #else | |
| 35 regs.pc = state.pc; | |
|
alph
2016/06/30 21:25:10
Why don't you want keep it as it was before?
So in
lpy
2016/06/30 21:34:45
Done.
| |
| 36 regs.fp = state.fp; | |
| 37 regs.sp = state.sp; | |
| 38 #endif | |
| 39 TickSample* sample = processor_->StartTickSample(); | |
| 40 if (sample == NULL) return; | |
| 41 sample->Init(i_isolate, regs, TickSample::kIncludeCEntryFrame, true); | |
| 42 if (is_counting_samples_ && !sample->timestamp.IsNull()) { | |
| 43 if (sample->state == JS) ++js_sample_count_; | |
| 44 if (sample->state == EXTERNAL) ++external_sample_count_; | |
| 45 } | |
| 46 processor_->FinishTickSample(); | |
| 47 } | |
| 48 | |
| 49 private: | |
| 50 ProfilerEventsProcessor* processor_; | |
| 51 }; | |
| 52 | |
| 53 ProfilerEventsProcessor::ProfilerEventsProcessor(Isolate* isolate, | |
| 54 ProfileGenerator* generator, | |
| 25 base::TimeDelta period) | 55 base::TimeDelta period) |
| 26 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), | 56 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), |
| 27 generator_(generator), | 57 generator_(generator), |
| 28 sampler_(sampler), | 58 sampler_(new CpuSampler(isolate, this)), |
| 29 running_(1), | 59 running_(1), |
| 30 period_(period), | 60 period_(period), |
| 31 last_code_event_id_(0), | 61 last_code_event_id_(0), |
| 32 last_processed_code_event_id_(0) {} | 62 last_processed_code_event_id_(0) { |
| 63 sampler_->IncreaseProfilingDepth(); | |
| 64 } | |
| 33 | 65 |
| 34 | 66 ProfilerEventsProcessor::~ProfilerEventsProcessor() { |
| 35 ProfilerEventsProcessor::~ProfilerEventsProcessor() {} | 67 sampler_->DecreaseProfilingDepth(); |
| 36 | 68 } |
| 37 | 69 |
| 38 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { | 70 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { |
| 39 event.generic.order = last_code_event_id_.Increment(1); | 71 event.generic.order = last_code_event_id_.Increment(1); |
| 40 events_buffer_.Enqueue(event); | 72 events_buffer_.Enqueue(event); |
| 41 } | 73 } |
| 42 | 74 |
| 43 | 75 |
| 44 void ProfilerEventsProcessor::AddDeoptStack(Isolate* isolate, Address from, | 76 void ProfilerEventsProcessor::AddDeoptStack(Isolate* isolate, Address from, |
| 45 int fp_to_sp_delta) { | 77 int fp_to_sp_delta) { |
| 46 TickSampleEventRecord record(last_code_event_id_.Value()); | 78 TickSampleEventRecord record(last_code_event_id_.Value()); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 | 308 |
| 277 void CpuProfiler::StartProcessorIfNotStarted() { | 309 void CpuProfiler::StartProcessorIfNotStarted() { |
| 278 if (processor_) { | 310 if (processor_) { |
| 279 processor_->AddCurrentStack(isolate_); | 311 processor_->AddCurrentStack(isolate_); |
| 280 return; | 312 return; |
| 281 } | 313 } |
| 282 Logger* logger = isolate_->logger(); | 314 Logger* logger = isolate_->logger(); |
| 283 // Disable logging when using the new implementation. | 315 // Disable logging when using the new implementation. |
| 284 saved_is_logging_ = logger->is_logging_; | 316 saved_is_logging_ = logger->is_logging_; |
| 285 logger->is_logging_ = false; | 317 logger->is_logging_ = false; |
| 286 sampler::Sampler* sampler = logger->sampler(); | |
| 287 generator_.reset(new ProfileGenerator(profiles_.get())); | 318 generator_.reset(new ProfileGenerator(profiles_.get())); |
| 288 processor_.reset(new ProfilerEventsProcessor(generator_.get(), sampler, | 319 processor_.reset(new ProfilerEventsProcessor(isolate_, generator_.get(), |
| 289 sampling_interval_)); | 320 sampling_interval_)); |
| 290 logger->SetUpProfilerListener(); | 321 logger->SetUpProfilerListener(); |
| 291 ProfilerListener* profiler_listener = logger->profiler_listener(); | 322 ProfilerListener* profiler_listener = logger->profiler_listener(); |
| 292 profiler_listener->AddObserver(this); | 323 profiler_listener->AddObserver(this); |
| 293 is_profiling_ = true; | 324 is_profiling_ = true; |
| 294 isolate_->set_is_profiling(true); | 325 isolate_->set_is_profiling(true); |
| 295 // Enumerate stuff we already have in the heap. | 326 // Enumerate stuff we already have in the heap. |
| 296 DCHECK(isolate_->heap()->HasBeenSetUp()); | 327 DCHECK(isolate_->heap()->HasBeenSetUp()); |
| 297 if (!FLAG_prof_browser_mode) { | 328 if (!FLAG_prof_browser_mode) { |
| 298 logger->LogCodeObjects(); | 329 logger->LogCodeObjects(); |
| 299 } | 330 } |
| 300 logger->LogCompiledFunctions(); | 331 logger->LogCompiledFunctions(); |
| 301 logger->LogAccessorCallbacks(); | 332 logger->LogAccessorCallbacks(); |
| 302 LogBuiltins(); | 333 LogBuiltins(); |
| 303 // Enable stack sampling. | 334 // Enable stack sampling. |
| 304 sampler->SetHasProcessingThread(true); | |
| 305 sampler->IncreaseProfilingDepth(); | |
| 306 processor_->AddCurrentStack(isolate_); | 335 processor_->AddCurrentStack(isolate_); |
| 307 processor_->StartSynchronously(); | 336 processor_->StartSynchronously(); |
| 308 } | 337 } |
| 309 | 338 |
| 310 | 339 |
| 311 CpuProfile* CpuProfiler::StopProfiling(const char* title) { | 340 CpuProfile* CpuProfiler::StopProfiling(const char* title) { |
| 312 if (!is_profiling_) return nullptr; | 341 if (!is_profiling_) return nullptr; |
| 313 StopProcessorIfLastProfile(title); | 342 StopProcessorIfLastProfile(title); |
| 314 CpuProfile* result = profiles_->StopProfiling(title); | 343 CpuProfile* result = profiles_->StopProfiling(title); |
| 315 if (result) { | 344 if (result) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 329 | 358 |
| 330 void CpuProfiler::StopProcessorIfLastProfile(const char* title) { | 359 void CpuProfiler::StopProcessorIfLastProfile(const char* title) { |
| 331 if (profiles_->IsLastProfile(title)) { | 360 if (profiles_->IsLastProfile(title)) { |
| 332 StopProcessor(); | 361 StopProcessor(); |
| 333 } | 362 } |
| 334 } | 363 } |
| 335 | 364 |
| 336 | 365 |
| 337 void CpuProfiler::StopProcessor() { | 366 void CpuProfiler::StopProcessor() { |
| 338 Logger* logger = isolate_->logger(); | 367 Logger* logger = isolate_->logger(); |
| 339 sampler::Sampler* sampler = | |
| 340 reinterpret_cast<sampler::Sampler*>(logger->ticker_); | |
| 341 is_profiling_ = false; | 368 is_profiling_ = false; |
| 342 isolate_->set_is_profiling(false); | 369 isolate_->set_is_profiling(false); |
| 343 ProfilerListener* profiler_listener = logger->profiler_listener(); | 370 ProfilerListener* profiler_listener = logger->profiler_listener(); |
| 344 profiler_listener->RemoveObserver(this); | 371 profiler_listener->RemoveObserver(this); |
| 345 processor_->StopSynchronously(); | 372 processor_->StopSynchronously(); |
| 346 logger->TearDownProfilerListener(); | 373 logger->TearDownProfilerListener(); |
| 347 processor_.reset(); | 374 processor_.reset(); |
| 348 generator_.reset(); | 375 generator_.reset(); |
| 349 sampler->SetHasProcessingThread(false); | |
| 350 sampler->DecreaseProfilingDepth(); | |
| 351 logger->is_logging_ = saved_is_logging_; | 376 logger->is_logging_ = saved_is_logging_; |
| 352 } | 377 } |
| 353 | 378 |
| 354 | 379 |
| 355 void CpuProfiler::LogBuiltins() { | 380 void CpuProfiler::LogBuiltins() { |
| 356 Builtins* builtins = isolate_->builtins(); | 381 Builtins* builtins = isolate_->builtins(); |
| 357 DCHECK(builtins->is_initialized()); | 382 DCHECK(builtins->is_initialized()); |
| 358 for (int i = 0; i < Builtins::builtin_count; i++) { | 383 for (int i = 0; i < Builtins::builtin_count; i++) { |
| 359 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN); | 384 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN); |
| 360 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; | 385 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; |
| 361 Builtins::Name id = static_cast<Builtins::Name>(i); | 386 Builtins::Name id = static_cast<Builtins::Name>(i); |
| 362 rec->start = builtins->builtin(id)->address(); | 387 rec->start = builtins->builtin(id)->address(); |
| 363 rec->builtin_id = id; | 388 rec->builtin_id = id; |
| 364 processor_->Enqueue(evt_rec); | 389 processor_->Enqueue(evt_rec); |
| 365 } | 390 } |
| 366 } | 391 } |
| 367 | 392 |
| 368 } // namespace internal | 393 } // namespace internal |
| 369 } // namespace v8 | 394 } // namespace v8 |
| OLD | NEW |