OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium 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 "content/renderer/devtools/v8_sampling_profiler.h" | 5 #include "content/renderer/devtools/v8_sampling_profiler.h" |
6 | 6 |
7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
8 #include <signal.h> | 8 #include <signal.h> |
9 #define USE_SIGNALS | 9 #define USE_SIGNALS |
10 #endif | 10 #endif |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 static scoped_ptr<Sampler> CreateForCurrentThread(); | 110 static scoped_ptr<Sampler> CreateForCurrentThread(); |
111 static Sampler* GetInstance() { return tls_instance_.Pointer()->Get(); } | 111 static Sampler* GetInstance() { return tls_instance_.Pointer()->Get(); } |
112 | 112 |
113 // These methods are called from the sampling thread. | 113 // These methods are called from the sampling thread. |
114 void Start(); | 114 void Start(); |
115 void Stop(); | 115 void Stop(); |
116 void Sample(); | 116 void Sample(); |
117 | 117 |
118 void DoSample(const v8::RegisterState& state); | 118 void DoSample(const v8::RegisterState& state); |
119 | 119 |
| 120 void SetEventsToCollectForTest(int code_added_events, int sample_events) { |
| 121 code_added_events_to_collect_for_test_ = code_added_events; |
| 122 sample_events_to_collect_for_test_ = sample_events; |
| 123 } |
| 124 |
120 bool EventsCollectedForTest() const { | 125 bool EventsCollectedForTest() const { |
121 return base::subtle::NoBarrier_Load(&code_added_events_count_) != 0 || | 126 return base::subtle::NoBarrier_Load(&code_added_events_count_) >= |
122 base::subtle::NoBarrier_Load(&samples_count_) != 0; | 127 code_added_events_to_collect_for_test_ && |
| 128 base::subtle::NoBarrier_Load(&samples_count_) >= |
| 129 sample_events_to_collect_for_test_; |
123 } | 130 } |
124 | 131 |
125 private: | 132 private: |
126 Sampler(); | 133 Sampler(); |
127 | 134 |
128 static void InstallJitCodeEventHandler(Isolate* isolate, void* data); | 135 static void InstallJitCodeEventHandler(Isolate* isolate, void* data); |
129 static void HandleJitCodeEvent(const v8::JitCodeEvent* event); | 136 static void HandleJitCodeEvent(const v8::JitCodeEvent* event); |
130 static scoped_refptr<ConvertableToTraceFormat> JitCodeEventToTraceFormat( | 137 static scoped_refptr<ConvertableToTraceFormat> JitCodeEventToTraceFormat( |
131 const v8::JitCodeEvent* event); | 138 const v8::JitCodeEvent* event); |
132 static base::PlatformThreadHandle GetCurrentThreadHandle(); | 139 static base::PlatformThreadHandle GetCurrentThreadHandle(); |
133 | 140 |
134 void InjectPendingEvents(); | 141 void InjectPendingEvents(); |
135 | 142 |
136 static const unsigned kNumberOfSamples = 10; | 143 static const unsigned kNumberOfSamples = 10; |
137 typedef LockFreeCircularQueue<SampleRecord, kNumberOfSamples> SamplingQueue; | 144 typedef LockFreeCircularQueue<SampleRecord, kNumberOfSamples> SamplingQueue; |
138 | 145 |
139 base::PlatformThreadId thread_id_; | 146 base::PlatformThreadId thread_id_; |
140 base::PlatformThreadHandle thread_handle_; | 147 base::PlatformThreadHandle thread_handle_; |
141 Isolate* isolate_; | 148 Isolate* isolate_; |
142 scoped_ptr<SamplingQueue> samples_data_; | 149 scoped_ptr<SamplingQueue> samples_data_; |
143 base::subtle::Atomic32 code_added_events_count_; | 150 base::subtle::Atomic32 code_added_events_count_; |
144 base::subtle::Atomic32 samples_count_; | 151 base::subtle::Atomic32 samples_count_; |
| 152 int code_added_events_to_collect_for_test_; |
| 153 int sample_events_to_collect_for_test_; |
145 | 154 |
146 static base::LazyInstance<base::ThreadLocalPointer<Sampler>>::Leaky | 155 static base::LazyInstance<base::ThreadLocalPointer<Sampler>>::Leaky |
147 tls_instance_; | 156 tls_instance_; |
148 }; | 157 }; |
149 | 158 |
150 base::LazyInstance<base::ThreadLocalPointer<Sampler>>::Leaky | 159 base::LazyInstance<base::ThreadLocalPointer<Sampler>>::Leaky |
151 Sampler::tls_instance_ = LAZY_INSTANCE_INITIALIZER; | 160 Sampler::tls_instance_ = LAZY_INSTANCE_INITIALIZER; |
152 | 161 |
153 Sampler::Sampler() | 162 Sampler::Sampler() |
154 : thread_id_(base::PlatformThread::CurrentId()), | 163 : thread_id_(base::PlatformThread::CurrentId()), |
155 thread_handle_(Sampler::GetCurrentThreadHandle()), | 164 thread_handle_(Sampler::GetCurrentThreadHandle()), |
156 isolate_(Isolate::GetCurrent()), | 165 isolate_(Isolate::GetCurrent()), |
157 code_added_events_count_(0), | 166 code_added_events_count_(0), |
158 samples_count_(0) { | 167 samples_count_(0), |
| 168 code_added_events_to_collect_for_test_(0), |
| 169 sample_events_to_collect_for_test_(0) { |
159 DCHECK(isolate_); | 170 DCHECK(isolate_); |
160 DCHECK(!GetInstance()); | 171 DCHECK(!GetInstance()); |
161 tls_instance_.Pointer()->Set(this); | 172 tls_instance_.Pointer()->Set(this); |
162 } | 173 } |
163 | 174 |
164 Sampler::~Sampler() { | 175 Sampler::~Sampler() { |
165 DCHECK(GetInstance()); | 176 DCHECK(GetInstance()); |
166 tls_instance_.Pointer()->Set(nullptr); | 177 tls_instance_.Pointer()->Set(nullptr); |
167 } | 178 } |
168 | 179 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 | 217 |
207 void Sampler::DoSample(const v8::RegisterState& state) { | 218 void Sampler::DoSample(const v8::RegisterState& state) { |
208 // Called in the sampled thread signal handler. | 219 // Called in the sampled thread signal handler. |
209 // Because of that it is not allowed to do any memory allocation here. | 220 // Because of that it is not allowed to do any memory allocation here. |
210 base::TimeTicks timestamp = base::TimeTicks::NowFromSystemTraceTime(); | 221 base::TimeTicks timestamp = base::TimeTicks::NowFromSystemTraceTime(); |
211 SampleRecord* record = samples_data_->StartEnqueue(); | 222 SampleRecord* record = samples_data_->StartEnqueue(); |
212 if (!record) | 223 if (!record) |
213 return; | 224 return; |
214 record->Collect(isolate_, timestamp, state); | 225 record->Collect(isolate_, timestamp, state); |
215 samples_data_->FinishEnqueue(); | 226 samples_data_->FinishEnqueue(); |
216 base::subtle::NoBarrier_AtomicIncrement(&samples_count_, 1); | |
217 } | 227 } |
218 | 228 |
219 void Sampler::InjectPendingEvents() { | 229 void Sampler::InjectPendingEvents() { |
220 SampleRecord* record = samples_data_->Peek(); | 230 SampleRecord* record = samples_data_->Peek(); |
221 while (record) { | 231 while (record) { |
222 TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP1( | 232 TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP1( |
223 TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"), "V8Sample", thread_id_, | 233 TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"), "V8Sample", thread_id_, |
224 (record->timestamp() - base::TimeTicks()).InMicroseconds(), "data", | 234 (record->timestamp() - base::TimeTicks()).InMicroseconds(), "data", |
225 record->ToTraceFormat()); | 235 record->ToTraceFormat()); |
226 samples_data_->Remove(); | 236 samples_data_->Remove(); |
227 record = samples_data_->Peek(); | 237 record = samples_data_->Peek(); |
| 238 base::subtle::NoBarrier_AtomicIncrement(&samples_count_, 1); |
228 } | 239 } |
229 } | 240 } |
230 | 241 |
231 // static | 242 // static |
232 void Sampler::InstallJitCodeEventHandler(Isolate* isolate, void* data) { | 243 void Sampler::InstallJitCodeEventHandler(Isolate* isolate, void* data) { |
233 // Called on the sampled V8 thread. | 244 // Called on the sampled V8 thread. |
234 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"), | 245 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profile"), |
235 "Sampler::InstallJitCodeEventHandler"); | 246 "Sampler::InstallJitCodeEventHandler"); |
236 v8::JitCodeEventHandler handler = | 247 v8::JitCodeEventHandler handler = |
237 reinterpret_cast<v8::JitCodeEventHandler>(data); | 248 reinterpret_cast<v8::JitCodeEventHandler>(data); |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 base::Unretained(this))); | 552 base::Unretained(this))); |
542 } | 553 } |
543 | 554 |
544 void V8SamplingProfiler::OnTraceLogDisabled() { | 555 void V8SamplingProfiler::OnTraceLogDisabled() { |
545 if (!sampling_thread_.get()) | 556 if (!sampling_thread_.get()) |
546 return; | 557 return; |
547 sampling_thread_->Stop(); | 558 sampling_thread_->Stop(); |
548 sampling_thread_.reset(); | 559 sampling_thread_.reset(); |
549 } | 560 } |
550 | 561 |
551 void V8SamplingProfiler::EnableSamplingEventForTesting() { | 562 void V8SamplingProfiler::EnableSamplingEventForTesting(int code_added_events, |
| 563 int sample_events) { |
| 564 render_thread_sampler_->SetEventsToCollectForTest(code_added_events, |
| 565 sample_events); |
552 waitable_event_for_testing_.reset(new base::WaitableEvent(false, false)); | 566 waitable_event_for_testing_.reset(new base::WaitableEvent(false, false)); |
553 } | 567 } |
554 | 568 |
555 void V8SamplingProfiler::WaitSamplingEventForTesting() { | 569 void V8SamplingProfiler::WaitSamplingEventForTesting() { |
556 waitable_event_for_testing_->Wait(); | 570 waitable_event_for_testing_->Wait(); |
557 } | 571 } |
558 | 572 |
559 } // namespace blink | 573 } // namespace blink |
OLD | NEW |