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 #if defined(USE_SIMULATOR) |
| 32 v8::RegisterState regs; |
| 33 if (!SimulatorHelper::FillRegisters(i_isolate, ®s)) return; |
| 34 #else |
| 35 const v8::RegisterState& regs = state; |
| 36 #endif |
| 37 TickSample* sample = processor_->StartTickSample(); |
| 38 if (sample == NULL) return; |
| 39 sample->Init(i_isolate, regs, TickSample::kIncludeCEntryFrame, true); |
| 40 if (is_counting_samples_ && !sample->timestamp.IsNull()) { |
| 41 if (sample->state == JS) ++js_sample_count_; |
| 42 if (sample->state == EXTERNAL) ++external_sample_count_; |
| 43 } |
| 44 processor_->FinishTickSample(); |
| 45 } |
| 46 |
| 47 private: |
| 48 ProfilerEventsProcessor* processor_; |
| 49 }; |
| 50 |
| 51 ProfilerEventsProcessor::ProfilerEventsProcessor(Isolate* isolate, |
| 52 ProfileGenerator* generator, |
25 base::TimeDelta period) | 53 base::TimeDelta period) |
26 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), | 54 : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)), |
27 generator_(generator), | 55 generator_(generator), |
28 sampler_(sampler), | 56 sampler_(new CpuSampler(isolate, this)), |
29 running_(1), | 57 running_(1), |
30 period_(period), | 58 period_(period), |
31 last_code_event_id_(0), | 59 last_code_event_id_(0), |
32 last_processed_code_event_id_(0) {} | 60 last_processed_code_event_id_(0) { |
| 61 sampler_->IncreaseProfilingDepth(); |
| 62 } |
33 | 63 |
34 | 64 ProfilerEventsProcessor::~ProfilerEventsProcessor() { |
35 ProfilerEventsProcessor::~ProfilerEventsProcessor() {} | 65 sampler_->DecreaseProfilingDepth(); |
36 | 66 } |
37 | 67 |
38 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { | 68 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { |
39 event.generic.order = last_code_event_id_.Increment(1); | 69 event.generic.order = last_code_event_id_.Increment(1); |
40 events_buffer_.Enqueue(event); | 70 events_buffer_.Enqueue(event); |
41 } | 71 } |
42 | 72 |
43 | 73 |
44 void ProfilerEventsProcessor::AddDeoptStack(Isolate* isolate, Address from, | 74 void ProfilerEventsProcessor::AddDeoptStack(Isolate* isolate, Address from, |
45 int fp_to_sp_delta) { | 75 int fp_to_sp_delta) { |
46 TickSampleEventRecord record(last_code_event_id_.Value()); | 76 TickSampleEventRecord record(last_code_event_id_.Value()); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 | 306 |
277 void CpuProfiler::StartProcessorIfNotStarted() { | 307 void CpuProfiler::StartProcessorIfNotStarted() { |
278 if (processor_) { | 308 if (processor_) { |
279 processor_->AddCurrentStack(isolate_); | 309 processor_->AddCurrentStack(isolate_); |
280 return; | 310 return; |
281 } | 311 } |
282 Logger* logger = isolate_->logger(); | 312 Logger* logger = isolate_->logger(); |
283 // Disable logging when using the new implementation. | 313 // Disable logging when using the new implementation. |
284 saved_is_logging_ = logger->is_logging_; | 314 saved_is_logging_ = logger->is_logging_; |
285 logger->is_logging_ = false; | 315 logger->is_logging_ = false; |
286 sampler::Sampler* sampler = logger->sampler(); | |
287 generator_.reset(new ProfileGenerator(profiles_.get())); | 316 generator_.reset(new ProfileGenerator(profiles_.get())); |
288 processor_.reset(new ProfilerEventsProcessor(generator_.get(), sampler, | 317 processor_.reset(new ProfilerEventsProcessor(isolate_, generator_.get(), |
289 sampling_interval_)); | 318 sampling_interval_)); |
290 logger->SetUpProfilerListener(); | 319 logger->SetUpProfilerListener(); |
291 ProfilerListener* profiler_listener = logger->profiler_listener(); | 320 ProfilerListener* profiler_listener = logger->profiler_listener(); |
292 profiler_listener->AddObserver(this); | 321 profiler_listener->AddObserver(this); |
293 is_profiling_ = true; | 322 is_profiling_ = true; |
294 isolate_->set_is_profiling(true); | 323 isolate_->set_is_profiling(true); |
295 // Enumerate stuff we already have in the heap. | 324 // Enumerate stuff we already have in the heap. |
296 DCHECK(isolate_->heap()->HasBeenSetUp()); | 325 DCHECK(isolate_->heap()->HasBeenSetUp()); |
297 if (!FLAG_prof_browser_mode) { | 326 if (!FLAG_prof_browser_mode) { |
298 logger->LogCodeObjects(); | 327 logger->LogCodeObjects(); |
299 } | 328 } |
300 logger->LogCompiledFunctions(); | 329 logger->LogCompiledFunctions(); |
301 logger->LogAccessorCallbacks(); | 330 logger->LogAccessorCallbacks(); |
302 LogBuiltins(); | 331 LogBuiltins(); |
303 // Enable stack sampling. | 332 // Enable stack sampling. |
304 sampler->SetHasProcessingThread(true); | |
305 sampler->IncreaseProfilingDepth(); | |
306 processor_->AddCurrentStack(isolate_); | 333 processor_->AddCurrentStack(isolate_); |
307 processor_->StartSynchronously(); | 334 processor_->StartSynchronously(); |
308 } | 335 } |
309 | 336 |
310 | 337 |
311 CpuProfile* CpuProfiler::StopProfiling(const char* title) { | 338 CpuProfile* CpuProfiler::StopProfiling(const char* title) { |
312 if (!is_profiling_) return nullptr; | 339 if (!is_profiling_) return nullptr; |
313 StopProcessorIfLastProfile(title); | 340 StopProcessorIfLastProfile(title); |
314 CpuProfile* result = profiles_->StopProfiling(title); | 341 CpuProfile* result = profiles_->StopProfiling(title); |
315 if (result) { | 342 if (result) { |
(...skipping 13 matching lines...) Expand all Loading... |
329 | 356 |
330 void CpuProfiler::StopProcessorIfLastProfile(const char* title) { | 357 void CpuProfiler::StopProcessorIfLastProfile(const char* title) { |
331 if (profiles_->IsLastProfile(title)) { | 358 if (profiles_->IsLastProfile(title)) { |
332 StopProcessor(); | 359 StopProcessor(); |
333 } | 360 } |
334 } | 361 } |
335 | 362 |
336 | 363 |
337 void CpuProfiler::StopProcessor() { | 364 void CpuProfiler::StopProcessor() { |
338 Logger* logger = isolate_->logger(); | 365 Logger* logger = isolate_->logger(); |
339 sampler::Sampler* sampler = | |
340 reinterpret_cast<sampler::Sampler*>(logger->ticker_); | |
341 is_profiling_ = false; | 366 is_profiling_ = false; |
342 isolate_->set_is_profiling(false); | 367 isolate_->set_is_profiling(false); |
343 ProfilerListener* profiler_listener = logger->profiler_listener(); | 368 ProfilerListener* profiler_listener = logger->profiler_listener(); |
344 profiler_listener->RemoveObserver(this); | 369 profiler_listener->RemoveObserver(this); |
345 processor_->StopSynchronously(); | 370 processor_->StopSynchronously(); |
346 logger->TearDownProfilerListener(); | 371 logger->TearDownProfilerListener(); |
347 processor_.reset(); | 372 processor_.reset(); |
348 generator_.reset(); | 373 generator_.reset(); |
349 sampler->SetHasProcessingThread(false); | |
350 sampler->DecreaseProfilingDepth(); | |
351 logger->is_logging_ = saved_is_logging_; | 374 logger->is_logging_ = saved_is_logging_; |
352 } | 375 } |
353 | 376 |
354 | 377 |
355 void CpuProfiler::LogBuiltins() { | 378 void CpuProfiler::LogBuiltins() { |
356 Builtins* builtins = isolate_->builtins(); | 379 Builtins* builtins = isolate_->builtins(); |
357 DCHECK(builtins->is_initialized()); | 380 DCHECK(builtins->is_initialized()); |
358 for (int i = 0; i < Builtins::builtin_count; i++) { | 381 for (int i = 0; i < Builtins::builtin_count; i++) { |
359 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN); | 382 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN); |
360 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; | 383 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; |
361 Builtins::Name id = static_cast<Builtins::Name>(i); | 384 Builtins::Name id = static_cast<Builtins::Name>(i); |
362 rec->start = builtins->builtin(id)->address(); | 385 rec->start = builtins->builtin(id)->address(); |
363 rec->builtin_id = id; | 386 rec->builtin_id = id; |
364 processor_->Enqueue(evt_rec); | 387 processor_->Enqueue(evt_rec); |
365 } | 388 } |
366 } | 389 } |
367 | 390 |
368 } // namespace internal | 391 } // namespace internal |
369 } // namespace v8 | 392 } // namespace v8 |
OLD | NEW |