| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/sampler.h" | 5 #include "src/sampler.h" |
| 6 | 6 |
| 7 #if V8_OS_POSIX && !V8_OS_CYGWIN | 7 #if V8_OS_POSIX && !V8_OS_CYGWIN |
| 8 | 8 |
| 9 #define USE_SIGNALS | 9 #define USE_SIGNALS |
| 10 | 10 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 bool SignalHandler::signal_handler_installed_ = false; | 328 bool SignalHandler::signal_handler_installed_ = false; |
| 329 | 329 |
| 330 | 330 |
| 331 // As Native Client does not support signal handling, profiling is disabled. | 331 // As Native Client does not support signal handling, profiling is disabled. |
| 332 #if !V8_OS_NACL | 332 #if !V8_OS_NACL |
| 333 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, | 333 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, |
| 334 void* context) { | 334 void* context) { |
| 335 USE(info); | 335 USE(info); |
| 336 if (signal != SIGPROF) return; | 336 if (signal != SIGPROF) return; |
| 337 Isolate* isolate = Isolate::UnsafeCurrent(); | 337 Isolate* isolate = Isolate::UnsafeCurrent(); |
| 338 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { | 338 if (isolate == NULL || !isolate->IsInUse()) { |
| 339 // We require a fully initialized and entered isolate. | 339 // We require a fully initialized and entered isolate. |
| 340 return; | 340 return; |
| 341 } | 341 } |
| 342 if (v8::Locker::IsActive() && | 342 if (v8::Locker::IsActive() && |
| 343 !isolate->thread_manager()->IsLockedByCurrentThread()) { | 343 !isolate->thread_manager()->IsLockedByCurrentThread()) { |
| 344 return; | 344 return; |
| 345 } | 345 } |
| 346 | 346 |
| 347 Sampler* sampler = isolate->logger()->sampler(); | 347 Sampler* sampler = isolate->logger()->sampler(); |
| 348 if (sampler == NULL) return; | 348 if (sampler == NULL) return; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 // Implement Thread::Run(). | 535 // Implement Thread::Run(). |
| 536 virtual void Run() { | 536 virtual void Run() { |
| 537 while (true) { | 537 while (true) { |
| 538 { | 538 { |
| 539 base::LockGuard<base::Mutex> lock_guard(mutex_); | 539 base::LockGuard<base::Mutex> lock_guard(mutex_); |
| 540 if (active_samplers_.is_empty()) break; | 540 if (active_samplers_.is_empty()) break; |
| 541 // When CPU profiling is enabled both JavaScript and C++ code is | 541 // When CPU profiling is enabled both JavaScript and C++ code is |
| 542 // profiled. We must not suspend. | 542 // profiled. We must not suspend. |
| 543 for (int i = 0; i < active_samplers_.length(); ++i) { | 543 for (int i = 0; i < active_samplers_.length(); ++i) { |
| 544 Sampler* sampler = active_samplers_.at(i); | 544 Sampler* sampler = active_samplers_.at(i); |
| 545 if (!sampler->isolate()->IsInitialized()) continue; | |
| 546 if (!sampler->IsProfiling()) continue; | 545 if (!sampler->IsProfiling()) continue; |
| 547 sampler->DoSample(); | 546 sampler->DoSample(); |
| 548 } | 547 } |
| 549 } | 548 } |
| 550 base::OS::Sleep(interval_); | 549 base::OS::Sleep(interval_); |
| 551 } | 550 } |
| 552 } | 551 } |
| 553 | 552 |
| 554 private: | 553 private: |
| 555 // Protects the process wide state below. | 554 // Protects the process wide state below. |
| 556 static base::Mutex* mutex_; | 555 static base::Mutex* mutex_; |
| 557 static SamplerThread* instance_; | 556 static SamplerThread* instance_; |
| 558 | 557 |
| 559 const int interval_; | 558 const int interval_; |
| 560 List<Sampler*> active_samplers_; | 559 List<Sampler*> active_samplers_; |
| 561 | 560 |
| 562 DISALLOW_COPY_AND_ASSIGN(SamplerThread); | 561 DISALLOW_COPY_AND_ASSIGN(SamplerThread); |
| 563 }; | 562 }; |
| 564 | 563 |
| 565 | 564 |
| 566 base::Mutex* SamplerThread::mutex_ = NULL; | 565 base::Mutex* SamplerThread::mutex_ = NULL; |
| 567 SamplerThread* SamplerThread::instance_ = NULL; | 566 SamplerThread* SamplerThread::instance_ = NULL; |
| 568 | 567 |
| 569 | 568 |
| 570 // | 569 // |
| 571 // StackTracer implementation | 570 // StackTracer implementation |
| 572 // | 571 // |
| 573 DISABLE_ASAN void TickSample::Init(Isolate* isolate, | 572 DISABLE_ASAN void TickSample::Init(Isolate* isolate, |
| 574 const v8::RegisterState& regs) { | 573 const v8::RegisterState& regs) { |
| 575 DCHECK(isolate->IsInitialized()); | |
| 576 timestamp = base::TimeTicks::HighResolutionNow(); | 574 timestamp = base::TimeTicks::HighResolutionNow(); |
| 577 pc = reinterpret_cast<Address>(regs.pc); | 575 pc = reinterpret_cast<Address>(regs.pc); |
| 578 state = isolate->current_vm_state(); | 576 state = isolate->current_vm_state(); |
| 579 | 577 |
| 580 // Avoid collecting traces while doing GC. | 578 // Avoid collecting traces while doing GC. |
| 581 if (state == GC) return; | 579 if (state == GC) return; |
| 582 | 580 |
| 583 Address js_entry_sp = isolate->js_entry_sp(); | 581 Address js_entry_sp = isolate->js_entry_sp(); |
| 584 if (js_entry_sp == 0) return; // Not executing JS now. | 582 if (js_entry_sp == 0) return; // Not executing JS now. |
| 585 | 583 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 605 SampleInfo info; | 603 SampleInfo info; |
| 606 GetStackSample(isolate, regs, reinterpret_cast<void**>(&stack[0]), | 604 GetStackSample(isolate, regs, reinterpret_cast<void**>(&stack[0]), |
| 607 kMaxFramesCount, &info); | 605 kMaxFramesCount, &info); |
| 608 frames_count = static_cast<unsigned>(info.frames_count); | 606 frames_count = static_cast<unsigned>(info.frames_count); |
| 609 } | 607 } |
| 610 | 608 |
| 611 | 609 |
| 612 void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs, | 610 void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs, |
| 613 void** frames, size_t frames_limit, | 611 void** frames, size_t frames_limit, |
| 614 v8::SampleInfo* sample_info) { | 612 v8::SampleInfo* sample_info) { |
| 615 DCHECK(isolate->IsInitialized()); | |
| 616 sample_info->frames_count = 0; | 613 sample_info->frames_count = 0; |
| 617 sample_info->vm_state = isolate->current_vm_state(); | 614 sample_info->vm_state = isolate->current_vm_state(); |
| 618 if (sample_info->vm_state == GC) return; | 615 if (sample_info->vm_state == GC) return; |
| 619 | 616 |
| 620 Address js_entry_sp = isolate->js_entry_sp(); | 617 Address js_entry_sp = isolate->js_entry_sp(); |
| 621 if (js_entry_sp == 0) return; // Not executing JS now. | 618 if (js_entry_sp == 0) return; // Not executing JS now. |
| 622 | 619 |
| 623 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp), | 620 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp), |
| 624 reinterpret_cast<Address>(regs.sp), js_entry_sp); | 621 reinterpret_cast<Address>(regs.sp), js_entry_sp); |
| 625 size_t i = 0; | 622 size_t i = 0; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 #endif // USE_SIMULATOR | 751 #endif // USE_SIMULATOR |
| 755 SampleStack(state); | 752 SampleStack(state); |
| 756 } | 753 } |
| 757 ResumeThread(profiled_thread); | 754 ResumeThread(profiled_thread); |
| 758 } | 755 } |
| 759 | 756 |
| 760 #endif // USE_SIGNALS | 757 #endif // USE_SIGNALS |
| 761 | 758 |
| 762 | 759 |
| 763 } } // namespace v8::internal | 760 } } // namespace v8::internal |
| OLD | NEW |