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/profiler/sampler.h" | 5 #include "src/profiler/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 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 state = isolate->current_vm_state(); | 664 state = isolate->current_vm_state(); |
665 this->update_stats = update_stats; | 665 this->update_stats = update_stats; |
666 | 666 |
667 // Avoid collecting traces while doing GC. | 667 // Avoid collecting traces while doing GC. |
668 if (state == GC) return; | 668 if (state == GC) return; |
669 | 669 |
670 Address js_entry_sp = isolate->js_entry_sp(); | 670 Address js_entry_sp = isolate->js_entry_sp(); |
671 if (js_entry_sp == 0) return; // Not executing JS now. | 671 if (js_entry_sp == 0) return; // Not executing JS now. |
672 | 672 |
673 if (pc && IsNoFrameRegion(pc)) { | 673 if (pc && IsNoFrameRegion(pc)) { |
| 674 // Can't collect stack. Mark the sample as spoiled. |
| 675 timestamp = base::TimeTicks(); |
674 pc = 0; | 676 pc = 0; |
675 return; | 677 return; |
676 } | 678 } |
677 | 679 |
678 ExternalCallbackScope* scope = isolate->external_callback_scope(); | 680 ExternalCallbackScope* scope = isolate->external_callback_scope(); |
679 Address handler = Isolate::handler(isolate->thread_local_top()); | 681 Address handler = Isolate::handler(isolate->thread_local_top()); |
680 // If there is a handler on top of the external callback scope then | 682 // If there is a handler on top of the external callback scope then |
681 // we have already entrered JavaScript again and the external callback | 683 // we have already entrered JavaScript again and the external callback |
682 // is not the top function. | 684 // is not the top function. |
683 if (scope && scope->scope_address() < handler) { | 685 if (scope && scope->scope_address() < handler) { |
(...skipping 10 matching lines...) Expand all Loading... |
694 } | 696 } |
695 | 697 |
696 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp), | 698 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp), |
697 reinterpret_cast<Address>(regs.sp), js_entry_sp); | 699 reinterpret_cast<Address>(regs.sp), js_entry_sp); |
698 top_frame_type = it.top_frame_type(); | 700 top_frame_type = it.top_frame_type(); |
699 | 701 |
700 SampleInfo info; | 702 SampleInfo info; |
701 GetStackSample(isolate, regs, record_c_entry_frame, | 703 GetStackSample(isolate, regs, record_c_entry_frame, |
702 reinterpret_cast<void**>(&stack[0]), kMaxFramesCount, &info); | 704 reinterpret_cast<void**>(&stack[0]), kMaxFramesCount, &info); |
703 frames_count = static_cast<unsigned>(info.frames_count); | 705 frames_count = static_cast<unsigned>(info.frames_count); |
| 706 if (!frames_count) { |
| 707 // It is executing JS but failed to collect a stack trace. |
| 708 // Mark the sample as spoiled. |
| 709 timestamp = base::TimeTicks(); |
| 710 pc = 0; |
| 711 } |
704 } | 712 } |
705 | 713 |
706 | 714 |
707 void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs, | 715 void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs, |
708 RecordCEntryFrame record_c_entry_frame, | 716 RecordCEntryFrame record_c_entry_frame, |
709 void** frames, size_t frames_limit, | 717 void** frames, size_t frames_limit, |
710 v8::SampleInfo* sample_info) { | 718 v8::SampleInfo* sample_info) { |
711 sample_info->frames_count = 0; | 719 sample_info->frames_count = 0; |
712 sample_info->vm_state = isolate->current_vm_state(); | 720 sample_info->vm_state = isolate->current_vm_state(); |
713 if (sample_info->vm_state == GC) return; | 721 if (sample_info->vm_state == GC) return; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 #endif | 798 #endif |
791 base::NoBarrier_AtomicIncrement(&profiling_, -1); | 799 base::NoBarrier_AtomicIncrement(&profiling_, -1); |
792 } | 800 } |
793 | 801 |
794 | 802 |
795 void Sampler::SampleStack(const v8::RegisterState& state) { | 803 void Sampler::SampleStack(const v8::RegisterState& state) { |
796 TickSample* sample = isolate_->cpu_profiler()->StartTickSample(); | 804 TickSample* sample = isolate_->cpu_profiler()->StartTickSample(); |
797 TickSample sample_obj; | 805 TickSample sample_obj; |
798 if (sample == NULL) sample = &sample_obj; | 806 if (sample == NULL) sample = &sample_obj; |
799 sample->Init(isolate_, state, TickSample::kIncludeCEntryFrame, true); | 807 sample->Init(isolate_, state, TickSample::kIncludeCEntryFrame, true); |
800 if (is_counting_samples_) { | 808 if (is_counting_samples_ && !sample->timestamp.IsNull()) { |
801 if (sample->state == JS) ++js_sample_count_; | 809 if (sample->state == JS) ++js_sample_count_; |
802 if (sample->state == EXTERNAL) ++external_sample_count_; | 810 if (sample->state == EXTERNAL) ++external_sample_count_; |
803 } | 811 } |
804 Tick(sample); | 812 Tick(sample); |
805 if (sample != &sample_obj) { | 813 if (sample != &sample_obj) { |
806 isolate_->cpu_profiler()->FinishTickSample(); | 814 isolate_->cpu_profiler()->FinishTickSample(); |
807 } | 815 } |
808 } | 816 } |
809 | 817 |
810 | 818 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 SampleStack(state); | 859 SampleStack(state); |
852 } | 860 } |
853 ResumeThread(profiled_thread); | 861 ResumeThread(profiled_thread); |
854 } | 862 } |
855 | 863 |
856 #endif // USE_SIGNALS | 864 #endif // USE_SIGNALS |
857 | 865 |
858 | 866 |
859 } // namespace internal | 867 } // namespace internal |
860 } // namespace v8 | 868 } // namespace v8 |
OLD | NEW |