| 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 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 public: | 99 public: |
| 100 static const int kMaxFramesCountLog2 = 8; | 100 static const int kMaxFramesCountLog2 = 8; |
| 101 static const unsigned kMaxFramesCount = (1u << kMaxFramesCountLog2) - 1; | 101 static const unsigned kMaxFramesCount = (1u << kMaxFramesCountLog2) - 1; |
| 102 | 102 |
| 103 SampleRecord() {} | 103 SampleRecord() {} |
| 104 | 104 |
| 105 base::TimeTicks timestamp() const { return timestamp_; } | 105 base::TimeTicks timestamp() const { return timestamp_; } |
| 106 void Collect(v8::Isolate* isolate, | 106 void Collect(v8::Isolate* isolate, |
| 107 base::TimeTicks timestamp, | 107 base::TimeTicks timestamp, |
| 108 const v8::RegisterState& state); | 108 const v8::RegisterState& state); |
| 109 scoped_refptr<ConvertableToTraceFormat> ToTraceFormat() const; | 109 scoped_ptr<ConvertableToTraceFormat> ToTraceFormat() const; |
| 110 | 110 |
| 111 private: | 111 private: |
| 112 base::TimeTicks timestamp_; | 112 base::TimeTicks timestamp_; |
| 113 unsigned vm_state_ : 4; | 113 unsigned vm_state_ : 4; |
| 114 unsigned frames_count_ : kMaxFramesCountLog2; | 114 unsigned frames_count_ : kMaxFramesCountLog2; |
| 115 const void* frames_[kMaxFramesCount]; | 115 const void* frames_[kMaxFramesCount]; |
| 116 | 116 |
| 117 DISALLOW_COPY_AND_ASSIGN(SampleRecord); | 117 DISALLOW_COPY_AND_ASSIGN(SampleRecord); |
| 118 }; | 118 }; |
| 119 | 119 |
| 120 void SampleRecord::Collect(v8::Isolate* isolate, | 120 void SampleRecord::Collect(v8::Isolate* isolate, |
| 121 base::TimeTicks timestamp, | 121 base::TimeTicks timestamp, |
| 122 const v8::RegisterState& state) { | 122 const v8::RegisterState& state) { |
| 123 v8::SampleInfo sample_info; | 123 v8::SampleInfo sample_info; |
| 124 isolate->GetStackSample(state, (void**)frames_, kMaxFramesCount, | 124 isolate->GetStackSample(state, (void**)frames_, kMaxFramesCount, |
| 125 &sample_info); | 125 &sample_info); |
| 126 timestamp_ = timestamp; | 126 timestamp_ = timestamp; |
| 127 frames_count_ = sample_info.frames_count; | 127 frames_count_ = sample_info.frames_count; |
| 128 vm_state_ = sample_info.vm_state; | 128 vm_state_ = sample_info.vm_state; |
| 129 } | 129 } |
| 130 | 130 |
| 131 scoped_refptr<ConvertableToTraceFormat> SampleRecord::ToTraceFormat() const { | 131 scoped_ptr<ConvertableToTraceFormat> SampleRecord::ToTraceFormat() const { |
| 132 scoped_refptr<TracedValue> data(new TracedValue()); | 132 scoped_ptr<base::trace_event::TracedValue> data( |
| 133 new base::trace_event::TracedValue()); |
| 133 const char* vm_state = nullptr; | 134 const char* vm_state = nullptr; |
| 134 switch (vm_state_) { | 135 switch (vm_state_) { |
| 135 case v8::StateTag::JS: | 136 case v8::StateTag::JS: |
| 136 vm_state = "js"; | 137 vm_state = "js"; |
| 137 break; | 138 break; |
| 138 case v8::StateTag::GC: | 139 case v8::StateTag::GC: |
| 139 vm_state = "gc"; | 140 vm_state = "gc"; |
| 140 break; | 141 break; |
| 141 case v8::StateTag::COMPILER: | 142 case v8::StateTag::COMPILER: |
| 142 vm_state = "compiler"; | 143 vm_state = "compiler"; |
| 143 break; | 144 break; |
| 144 case v8::StateTag::OTHER: | 145 case v8::StateTag::OTHER: |
| 145 vm_state = "other"; | 146 vm_state = "other"; |
| 146 break; | 147 break; |
| 147 case v8::StateTag::EXTERNAL: | 148 case v8::StateTag::EXTERNAL: |
| 148 vm_state = "external"; | 149 vm_state = "external"; |
| 149 break; | 150 break; |
| 150 case v8::StateTag::IDLE: | 151 case v8::StateTag::IDLE: |
| 151 vm_state = "idle"; | 152 vm_state = "idle"; |
| 152 break; | 153 break; |
| 153 default: | 154 default: |
| 154 NOTREACHED(); | 155 NOTREACHED(); |
| 155 } | 156 } |
| 156 data->SetString("vm_state", vm_state); | 157 data->SetString("vm_state", vm_state); |
| 157 data->BeginArray("stack"); | 158 data->BeginArray("stack"); |
| 158 for (unsigned i = 0; i < frames_count_; ++i) { | 159 for (unsigned i = 0; i < frames_count_; ++i) { |
| 159 data->AppendString(PtrToString(frames_[i])); | 160 data->AppendString(PtrToString(frames_[i])); |
| 160 } | 161 } |
| 161 data->EndArray(); | 162 data->EndArray(); |
| 162 return data; | 163 return std::move(data); |
| 163 } | 164 } |
| 164 | 165 |
| 165 } // namespace | 166 } // namespace |
| 166 | 167 |
| 167 // The class implements a sampler responsible for sampling a single thread. | 168 // The class implements a sampler responsible for sampling a single thread. |
| 168 class Sampler { | 169 class Sampler { |
| 169 public: | 170 public: |
| 170 ~Sampler(); | 171 ~Sampler(); |
| 171 | 172 |
| 172 static scoped_ptr<Sampler> CreateForCurrentThread(); | 173 static scoped_ptr<Sampler> CreateForCurrentThread(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 189 code_added_events_to_collect_for_test_ && | 190 code_added_events_to_collect_for_test_ && |
| 190 base::subtle::NoBarrier_Load(&samples_count_) >= | 191 base::subtle::NoBarrier_Load(&samples_count_) >= |
| 191 sample_events_to_collect_for_test_; | 192 sample_events_to_collect_for_test_; |
| 192 } | 193 } |
| 193 | 194 |
| 194 private: | 195 private: |
| 195 Sampler(); | 196 Sampler(); |
| 196 | 197 |
| 197 static void InstallJitCodeEventHandler(Isolate* isolate, void* data); | 198 static void InstallJitCodeEventHandler(Isolate* isolate, void* data); |
| 198 static void HandleJitCodeEvent(const v8::JitCodeEvent* event); | 199 static void HandleJitCodeEvent(const v8::JitCodeEvent* event); |
| 199 static scoped_refptr<ConvertableToTraceFormat> JitCodeEventToTraceFormat( | 200 static scoped_ptr<ConvertableToTraceFormat> JitCodeEventToTraceFormat( |
| 200 const v8::JitCodeEvent* event); | 201 const v8::JitCodeEvent* event); |
| 201 | 202 |
| 202 void InjectPendingEvents(); | 203 void InjectPendingEvents(); |
| 203 | 204 |
| 204 static const unsigned kNumberOfSamples = 10; | 205 static const unsigned kNumberOfSamples = 10; |
| 205 typedef LockFreeCircularQueue<SampleRecord, kNumberOfSamples> SamplingQueue; | 206 typedef LockFreeCircularQueue<SampleRecord, kNumberOfSamples> SamplingQueue; |
| 206 | 207 |
| 207 PlatformData platform_data_; | 208 PlatformData platform_data_; |
| 208 Isolate* isolate_; | 209 Isolate* isolate_; |
| 209 scoped_ptr<SamplingQueue> samples_data_; | 210 scoped_ptr<SamplingQueue> samples_data_; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 break; | 353 break; |
| 353 | 354 |
| 354 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: | 355 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: |
| 355 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: | 356 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: |
| 356 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: | 357 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: |
| 357 break; | 358 break; |
| 358 } | 359 } |
| 359 } | 360 } |
| 360 | 361 |
| 361 // static | 362 // static |
| 362 scoped_refptr<ConvertableToTraceFormat> Sampler::JitCodeEventToTraceFormat( | 363 scoped_ptr<ConvertableToTraceFormat> Sampler::JitCodeEventToTraceFormat( |
| 363 const v8::JitCodeEvent* event) { | 364 const v8::JitCodeEvent* event) { |
| 364 switch (event->type) { | 365 switch (event->type) { |
| 365 case v8::JitCodeEvent::CODE_ADDED: { | 366 case v8::JitCodeEvent::CODE_ADDED: { |
| 366 scoped_refptr<TracedValue> data(new TracedValue()); | 367 scoped_ptr<base::trace_event::TracedValue> data( |
| 368 new base::trace_event::TracedValue()); |
| 367 data->SetString("code_start", PtrToString(event->code_start)); | 369 data->SetString("code_start", PtrToString(event->code_start)); |
| 368 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); | 370 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); |
| 369 data->SetString("name", std::string(event->name.str, event->name.len)); | 371 data->SetString("name", std::string(event->name.str, event->name.len)); |
| 370 if (!event->script.IsEmpty()) { | 372 if (!event->script.IsEmpty()) { |
| 371 data->SetInteger("script_id", event->script->GetId()); | 373 data->SetInteger("script_id", event->script->GetId()); |
| 372 } | 374 } |
| 373 return data; | 375 return std::move(data); |
| 374 } | 376 } |
| 375 | 377 |
| 376 case v8::JitCodeEvent::CODE_MOVED: { | 378 case v8::JitCodeEvent::CODE_MOVED: { |
| 377 scoped_refptr<TracedValue> data(new TracedValue()); | 379 scoped_ptr<base::trace_event::TracedValue> data( |
| 380 new base::trace_event::TracedValue()); |
| 378 data->SetString("code_start", PtrToString(event->code_start)); | 381 data->SetString("code_start", PtrToString(event->code_start)); |
| 379 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); | 382 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); |
| 380 data->SetString("new_code_start", PtrToString(event->new_code_start)); | 383 data->SetString("new_code_start", PtrToString(event->new_code_start)); |
| 381 return data; | 384 return std::move(data); |
| 382 } | 385 } |
| 383 | 386 |
| 384 case v8::JitCodeEvent::CODE_REMOVED: { | 387 case v8::JitCodeEvent::CODE_REMOVED: { |
| 385 scoped_refptr<TracedValue> data(new TracedValue()); | 388 scoped_ptr<base::trace_event::TracedValue> data( |
| 389 new base::trace_event::TracedValue()); |
| 386 data->SetString("code_start", PtrToString(event->code_start)); | 390 data->SetString("code_start", PtrToString(event->code_start)); |
| 387 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); | 391 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); |
| 388 return data; | 392 return std::move(data); |
| 389 } | 393 } |
| 390 | 394 |
| 391 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: | 395 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: |
| 392 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: | 396 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: |
| 393 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: | 397 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: |
| 394 return nullptr; | 398 return nullptr; |
| 395 } | 399 } |
| 396 return nullptr; | 400 return nullptr; |
| 397 } | 401 } |
| 398 | 402 |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 render_thread_sampler_->SetEventsToCollectForTest(code_added_events, | 640 render_thread_sampler_->SetEventsToCollectForTest(code_added_events, |
| 637 sample_events); | 641 sample_events); |
| 638 waitable_event_for_testing_.reset(new base::WaitableEvent(false, false)); | 642 waitable_event_for_testing_.reset(new base::WaitableEvent(false, false)); |
| 639 } | 643 } |
| 640 | 644 |
| 641 void V8SamplingProfiler::WaitSamplingEventForTesting() { | 645 void V8SamplingProfiler::WaitSamplingEventForTesting() { |
| 642 waitable_event_for_testing_->Wait(); | 646 waitable_event_for_testing_->Wait(); |
| 643 } | 647 } |
| 644 | 648 |
| 645 } // namespace content | 649 } // namespace content |
| OLD | NEW |