Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: src/profiler/sampler.cc

Issue 1952393002: Split TickSample and Sampler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 26 matching lines...) Expand all
37 #endif 37 #endif
38 38
39 #elif V8_OS_WIN || V8_OS_CYGWIN 39 #elif V8_OS_WIN || V8_OS_CYGWIN
40 40
41 #include "src/base/win32-headers.h" 41 #include "src/base/win32-headers.h"
42 42
43 #endif 43 #endif
44 44
45 #include "src/atomic-utils.h" 45 #include "src/atomic-utils.h"
46 #include "src/base/platform/platform.h" 46 #include "src/base/platform/platform.h"
47 #include "src/flags.h"
48 #include "src/frames-inl.h"
49 #include "src/log.h"
50 #include "src/profiler/cpu-profiler-inl.h" 47 #include "src/profiler/cpu-profiler-inl.h"
48 #include "src/profiler/tick-sample.h"
51 #include "src/simulator.h" 49 #include "src/simulator.h"
52 #include "src/v8threads.h" 50 #include "src/v8threads.h"
53 #include "src/vm-state-inl.h"
54 51
55 52
56 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) 53 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T)
57 54
58 // Not all versions of Android's C library provide ucontext_t. 55 // Not all versions of Android's C library provide ucontext_t.
59 // Detect this and provide custom but compatible definitions. Note that these 56 // Detect this and provide custom but compatible definitions. Note that these
60 // follow the GLibc naming convention to access register values from 57 // follow the GLibc naming convention to access register values from
61 // mcontext_t. 58 // mcontext_t.
62 // 59 //
63 // See http://code.google.com/p/android/issues/detail?id=34784 60 // See http://code.google.com/p/android/issues/detail?id=34784
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 ThreadId profiled_thread_id() { return profiled_thread_id_; } 165 ThreadId profiled_thread_id() { return profiled_thread_id_; }
169 166
170 protected: 167 protected:
171 ~PlatformDataCommon() {} 168 ~PlatformDataCommon() {}
172 169
173 private: 170 private:
174 ThreadId profiled_thread_id_; 171 ThreadId profiled_thread_id_;
175 }; 172 };
176 173
177 174
178 bool IsSamePage(byte* ptr1, byte* ptr2) {
179 const uint32_t kPageSize = 4096;
180 uintptr_t mask = ~static_cast<uintptr_t>(kPageSize - 1);
181 return (reinterpret_cast<uintptr_t>(ptr1) & mask) ==
182 (reinterpret_cast<uintptr_t>(ptr2) & mask);
183 }
184
185
186 // Check if the code at specified address could potentially be a
187 // frame setup code.
188 bool IsNoFrameRegion(Address address) {
189 struct Pattern {
190 int bytes_count;
191 byte bytes[8];
192 int offsets[4];
193 };
194 byte* pc = reinterpret_cast<byte*>(address);
195 static Pattern patterns[] = {
196 #if V8_HOST_ARCH_IA32
197 // push %ebp
198 // mov %esp,%ebp
199 {3, {0x55, 0x89, 0xe5}, {0, 1, -1}},
200 // pop %ebp
201 // ret N
202 {2, {0x5d, 0xc2}, {0, 1, -1}},
203 // pop %ebp
204 // ret
205 {2, {0x5d, 0xc3}, {0, 1, -1}},
206 #elif V8_HOST_ARCH_X64
207 // pushq %rbp
208 // movq %rsp,%rbp
209 {4, {0x55, 0x48, 0x89, 0xe5}, {0, 1, -1}},
210 // popq %rbp
211 // ret N
212 {2, {0x5d, 0xc2}, {0, 1, -1}},
213 // popq %rbp
214 // ret
215 {2, {0x5d, 0xc3}, {0, 1, -1}},
216 #endif
217 {0, {}, {}}
218 };
219 for (Pattern* pattern = patterns; pattern->bytes_count; ++pattern) {
220 for (int* offset_ptr = pattern->offsets; *offset_ptr != -1; ++offset_ptr) {
221 int offset = *offset_ptr;
222 if (!offset || IsSamePage(pc, pc - offset)) {
223 MSAN_MEMORY_IS_INITIALIZED(pc - offset, pattern->bytes_count);
224 if (!memcmp(pc - offset, pattern->bytes, pattern->bytes_count))
225 return true;
226 } else {
227 // It is not safe to examine bytes on another page as it might not be
228 // allocated thus causing a SEGFAULT.
229 // Check the pattern part that's on the same page and
230 // pessimistically assume it could be the entire pattern match.
231 MSAN_MEMORY_IS_INITIALIZED(pc, pattern->bytes_count - offset);
232 if (!memcmp(pc, pattern->bytes + offset, pattern->bytes_count - offset))
233 return true;
234 }
235 }
236 }
237 return false;
238 }
239
240 typedef List<Sampler*> SamplerList; 175 typedef List<Sampler*> SamplerList;
241 176
242 #if defined(USE_SIGNALS) 177 #if defined(USE_SIGNALS)
243 class AtomicGuard { 178 class AtomicGuard {
244 public: 179 public:
245 explicit AtomicGuard(AtomicValue<int>* atomic, bool is_block = true) 180 explicit AtomicGuard(AtomicValue<int>* atomic, bool is_block = true)
246 : atomic_(atomic), 181 : atomic_(atomic),
247 is_success_(false) { 182 is_success_(false) {
248 do { 183 do {
249 // Use Acquire_Load to gain mutual exclusion. 184 // Use Acquire_Load to gain mutual exclusion.
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); 733 SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value);
799 for (int i = 0; i < samplers->length(); ++i) { 734 for (int i = 0; i < samplers->length(); ++i) {
800 Sampler* sampler = samplers->at(i); 735 Sampler* sampler = samplers->at(i);
801 CollectSample(context, sampler); 736 CollectSample(context, sampler);
802 } 737 }
803 } 738 }
804 #endif // !V8_OS_NACL 739 #endif // !V8_OS_NACL
805 #endif // USE_SIGNALs 740 #endif // USE_SIGNALs
806 741
807 742
808 //
809 // StackTracer implementation
810 //
811 DISABLE_ASAN void TickSample::Init(Isolate* isolate,
812 const v8::RegisterState& regs,
813 RecordCEntryFrame record_c_entry_frame,
814 bool update_stats) {
815 timestamp = base::TimeTicks::HighResolutionNow();
816 pc = reinterpret_cast<Address>(regs.pc);
817 state = isolate->current_vm_state();
818 this->update_stats = update_stats;
819
820 // Avoid collecting traces while doing GC.
821 if (state == GC) return;
822
823 Address js_entry_sp = isolate->js_entry_sp();
824 if (js_entry_sp == 0) return; // Not executing JS now.
825
826 if (pc && IsNoFrameRegion(pc)) {
827 // Can't collect stack. Mark the sample as spoiled.
828 timestamp = base::TimeTicks();
829 pc = 0;
830 return;
831 }
832
833 ExternalCallbackScope* scope = isolate->external_callback_scope();
834 Address handler = Isolate::handler(isolate->thread_local_top());
835 // If there is a handler on top of the external callback scope then
836 // we have already entrered JavaScript again and the external callback
837 // is not the top function.
838 if (scope && scope->scope_address() < handler) {
839 external_callback_entry = *scope->callback_entrypoint_address();
840 has_external_callback = true;
841 } else {
842 // sp register may point at an arbitrary place in memory, make
843 // sure MSAN doesn't complain about it.
844 MSAN_MEMORY_IS_INITIALIZED(regs.sp, sizeof(Address));
845 // Sample potential return address value for frameless invocation of
846 // stubs (we'll figure out later, if this value makes sense).
847 tos = Memory::Address_at(reinterpret_cast<Address>(regs.sp));
848 has_external_callback = false;
849 }
850
851 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
852 reinterpret_cast<Address>(regs.sp), js_entry_sp);
853 top_frame_type = it.top_frame_type();
854
855 SampleInfo info;
856 GetStackSample(isolate, regs, record_c_entry_frame,
857 reinterpret_cast<void**>(&stack[0]), kMaxFramesCount, &info);
858 frames_count = static_cast<unsigned>(info.frames_count);
859 if (!frames_count) {
860 // It is executing JS but failed to collect a stack trace.
861 // Mark the sample as spoiled.
862 timestamp = base::TimeTicks();
863 pc = 0;
864 }
865 }
866
867
868 void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs,
869 RecordCEntryFrame record_c_entry_frame,
870 void** frames, size_t frames_limit,
871 v8::SampleInfo* sample_info) {
872 sample_info->frames_count = 0;
873 sample_info->vm_state = isolate->current_vm_state();
874 if (sample_info->vm_state == GC) return;
875
876 Address js_entry_sp = isolate->js_entry_sp();
877 if (js_entry_sp == 0) return; // Not executing JS now.
878
879 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
880 reinterpret_cast<Address>(regs.sp), js_entry_sp);
881 size_t i = 0;
882 if (record_c_entry_frame == kIncludeCEntryFrame && !it.done() &&
883 it.top_frame_type() == StackFrame::EXIT) {
884 frames[i++] = isolate->c_function();
885 }
886 while (!it.done() && i < frames_limit) {
887 if (it.frame()->is_interpreted()) {
888 // For interpreted frames use the bytecode array pointer as the pc.
889 InterpretedFrame* frame = static_cast<InterpretedFrame*>(it.frame());
890 // Since the sampler can interrupt execution at any point the
891 // bytecode_array might be garbage, so don't dereference it.
892 Address bytecode_array =
893 reinterpret_cast<Address>(frame->GetBytecodeArray()) - kHeapObjectTag;
894 frames[i++] = bytecode_array + BytecodeArray::kHeaderSize +
895 frame->GetBytecodeOffset();
896 } else {
897 frames[i++] = it.frame()->pc();
898 }
899 it.Advance();
900 }
901 sample_info->frames_count = i;
902 }
903
904
905 void Sampler::SetUp() { 743 void Sampler::SetUp() {
906 #if defined(USE_SIGNALS) 744 #if defined(USE_SIGNALS)
907 SignalHandler::SetUp(); 745 SignalHandler::SetUp();
908 #endif 746 #endif
909 SamplerThread::SetUp(); 747 SamplerThread::SetUp();
910 } 748 }
911 749
912 750
913 void Sampler::TearDown() { 751 void Sampler::TearDown() {
914 SamplerThread::TearDown(); 752 SamplerThread::TearDown();
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 SampleStack(state); 868 SampleStack(state);
1031 } 869 }
1032 ResumeThread(profiled_thread); 870 ResumeThread(profiled_thread);
1033 } 871 }
1034 872
1035 #endif // USE_SIGNALS 873 #endif // USE_SIGNALS
1036 874
1037 875
1038 } // namespace internal 876 } // namespace internal
1039 } // namespace v8 877 } // namespace v8
OLDNEW
« src/profiler/sampler.h ('K') | « src/profiler/sampler.h ('k') | src/profiler/tick-sample.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698