| 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 auto data = make_scoped_ptr(new TracedValue()); |
| 133 const char* vm_state = nullptr; | 133 const char* vm_state = nullptr; |
| 134 switch (vm_state_) { | 134 switch (vm_state_) { |
| 135 case v8::StateTag::JS: | 135 case v8::StateTag::JS: |
| 136 vm_state = "js"; | 136 vm_state = "js"; |
| 137 break; | 137 break; |
| 138 case v8::StateTag::GC: | 138 case v8::StateTag::GC: |
| 139 vm_state = "gc"; | 139 vm_state = "gc"; |
| 140 break; | 140 break; |
| 141 case v8::StateTag::COMPILER: | 141 case v8::StateTag::COMPILER: |
| 142 vm_state = "compiler"; | 142 vm_state = "compiler"; |
| 143 break; | 143 break; |
| 144 case v8::StateTag::OTHER: | 144 case v8::StateTag::OTHER: |
| 145 vm_state = "other"; | 145 vm_state = "other"; |
| 146 break; | 146 break; |
| 147 case v8::StateTag::EXTERNAL: | 147 case v8::StateTag::EXTERNAL: |
| 148 vm_state = "external"; | 148 vm_state = "external"; |
| 149 break; | 149 break; |
| 150 case v8::StateTag::IDLE: | 150 case v8::StateTag::IDLE: |
| 151 vm_state = "idle"; | 151 vm_state = "idle"; |
| 152 break; | 152 break; |
| 153 default: | 153 default: |
| 154 NOTREACHED(); | 154 NOTREACHED(); |
| 155 } | 155 } |
| 156 data->SetString("vm_state", vm_state); | 156 data->SetString("vm_state", vm_state); |
| 157 data->BeginArray("stack"); | 157 data->BeginArray("stack"); |
| 158 for (unsigned i = 0; i < frames_count_; ++i) { | 158 for (unsigned i = 0; i < frames_count_; ++i) { |
| 159 data->AppendString(PtrToString(frames_[i])); | 159 data->AppendString(PtrToString(frames_[i])); |
| 160 } | 160 } |
| 161 data->EndArray(); | 161 data->EndArray(); |
| 162 return data; | 162 return std::move(data); |
| 163 } | 163 } |
| 164 | 164 |
| 165 } // namespace | 165 } // namespace |
| 166 | 166 |
| 167 // The class implements a sampler responsible for sampling a single thread. | 167 // The class implements a sampler responsible for sampling a single thread. |
| 168 class Sampler { | 168 class Sampler { |
| 169 public: | 169 public: |
| 170 ~Sampler(); | 170 ~Sampler(); |
| 171 | 171 |
| 172 static scoped_ptr<Sampler> CreateForCurrentThread(); | 172 static scoped_ptr<Sampler> CreateForCurrentThread(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 189 code_added_events_to_collect_for_test_ && | 189 code_added_events_to_collect_for_test_ && |
| 190 base::subtle::NoBarrier_Load(&samples_count_) >= | 190 base::subtle::NoBarrier_Load(&samples_count_) >= |
| 191 sample_events_to_collect_for_test_; | 191 sample_events_to_collect_for_test_; |
| 192 } | 192 } |
| 193 | 193 |
| 194 private: | 194 private: |
| 195 Sampler(); | 195 Sampler(); |
| 196 | 196 |
| 197 static void InstallJitCodeEventHandler(Isolate* isolate, void* data); | 197 static void InstallJitCodeEventHandler(Isolate* isolate, void* data); |
| 198 static void HandleJitCodeEvent(const v8::JitCodeEvent* event); | 198 static void HandleJitCodeEvent(const v8::JitCodeEvent* event); |
| 199 static scoped_refptr<ConvertableToTraceFormat> JitCodeEventToTraceFormat( | 199 static scoped_ptr<ConvertableToTraceFormat> JitCodeEventToTraceFormat( |
| 200 const v8::JitCodeEvent* event); | 200 const v8::JitCodeEvent* event); |
| 201 | 201 |
| 202 void InjectPendingEvents(); | 202 void InjectPendingEvents(); |
| 203 | 203 |
| 204 static const unsigned kNumberOfSamples = 10; | 204 static const unsigned kNumberOfSamples = 10; |
| 205 typedef LockFreeCircularQueue<SampleRecord, kNumberOfSamples> SamplingQueue; | 205 typedef LockFreeCircularQueue<SampleRecord, kNumberOfSamples> SamplingQueue; |
| 206 | 206 |
| 207 PlatformData platform_data_; | 207 PlatformData platform_data_; |
| 208 Isolate* isolate_; | 208 Isolate* isolate_; |
| 209 scoped_ptr<SamplingQueue> samples_data_; | 209 scoped_ptr<SamplingQueue> samples_data_; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 break; | 352 break; |
| 353 | 353 |
| 354 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: | 354 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: |
| 355 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: | 355 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: |
| 356 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: | 356 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: |
| 357 break; | 357 break; |
| 358 } | 358 } |
| 359 } | 359 } |
| 360 | 360 |
| 361 // static | 361 // static |
| 362 scoped_refptr<ConvertableToTraceFormat> Sampler::JitCodeEventToTraceFormat( | 362 scoped_ptr<ConvertableToTraceFormat> Sampler::JitCodeEventToTraceFormat( |
| 363 const v8::JitCodeEvent* event) { | 363 const v8::JitCodeEvent* event) { |
| 364 switch (event->type) { | 364 switch (event->type) { |
| 365 case v8::JitCodeEvent::CODE_ADDED: { | 365 case v8::JitCodeEvent::CODE_ADDED: { |
| 366 scoped_refptr<TracedValue> data(new TracedValue()); | 366 auto data = make_scoped_ptr(new TracedValue); |
| 367 data->SetString("code_start", PtrToString(event->code_start)); | 367 data->SetString("code_start", PtrToString(event->code_start)); |
| 368 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); | 368 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); |
| 369 data->SetString("name", std::string(event->name.str, event->name.len)); | 369 data->SetString("name", std::string(event->name.str, event->name.len)); |
| 370 if (!event->script.IsEmpty()) { | 370 if (!event->script.IsEmpty()) { |
| 371 data->SetInteger("script_id", event->script->GetId()); | 371 data->SetInteger("script_id", event->script->GetId()); |
| 372 } | 372 } |
| 373 return data; | 373 return std::move(data); |
| 374 } | 374 } |
| 375 | 375 |
| 376 case v8::JitCodeEvent::CODE_MOVED: { | 376 case v8::JitCodeEvent::CODE_MOVED: { |
| 377 scoped_refptr<TracedValue> data(new TracedValue()); | 377 auto data = make_scoped_ptr(new TracedValue); |
| 378 data->SetString("code_start", PtrToString(event->code_start)); | 378 data->SetString("code_start", PtrToString(event->code_start)); |
| 379 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); | 379 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); |
| 380 data->SetString("new_code_start", PtrToString(event->new_code_start)); | 380 data->SetString("new_code_start", PtrToString(event->new_code_start)); |
| 381 return data; | 381 return std::move(data); |
| 382 } | 382 } |
| 383 | 383 |
| 384 case v8::JitCodeEvent::CODE_REMOVED: { | 384 case v8::JitCodeEvent::CODE_REMOVED: { |
| 385 scoped_refptr<TracedValue> data(new TracedValue()); | 385 auto data = make_scoped_ptr(new TracedValue); |
| 386 data->SetString("code_start", PtrToString(event->code_start)); | 386 data->SetString("code_start", PtrToString(event->code_start)); |
| 387 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); | 387 data->SetInteger("code_len", static_cast<unsigned>(event->code_len)); |
| 388 return data; | 388 return std::move(data); |
| 389 } | 389 } |
| 390 | 390 |
| 391 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: | 391 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: |
| 392 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: | 392 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: |
| 393 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: | 393 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: |
| 394 return nullptr; | 394 return nullptr; |
| 395 } | 395 } |
| 396 return nullptr; | 396 return nullptr; |
| 397 } | 397 } |
| 398 | 398 |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 render_thread_sampler_->SetEventsToCollectForTest(code_added_events, | 636 render_thread_sampler_->SetEventsToCollectForTest(code_added_events, |
| 637 sample_events); | 637 sample_events); |
| 638 waitable_event_for_testing_.reset(new base::WaitableEvent(false, false)); | 638 waitable_event_for_testing_.reset(new base::WaitableEvent(false, false)); |
| 639 } | 639 } |
| 640 | 640 |
| 641 void V8SamplingProfiler::WaitSamplingEventForTesting() { | 641 void V8SamplingProfiler::WaitSamplingEventForTesting() { |
| 642 waitable_event_for_testing_->Wait(); | 642 waitable_event_for_testing_->Wait(); |
| 643 } | 643 } |
| 644 | 644 |
| 645 } // namespace content | 645 } // namespace content |
| OLD | NEW |