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