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