| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/profile-generator.h" | 5 #include "src/profiler/profile-generator.h" |
| 6 | 6 |
| 7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/global-handles.h" | 10 #include "src/global-handles.h" |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 : title_(title), | 405 : title_(title), |
| 406 record_samples_(record_samples), | 406 record_samples_(record_samples), |
| 407 start_time_(base::TimeTicks::HighResolutionNow()), | 407 start_time_(base::TimeTicks::HighResolutionNow()), |
| 408 top_down_(profiler->isolate()), | 408 top_down_(profiler->isolate()), |
| 409 profiler_(profiler), | 409 profiler_(profiler), |
| 410 streaming_next_sample_(0) { | 410 streaming_next_sample_(0) { |
| 411 auto value = TracedValue::Create(); | 411 auto value = TracedValue::Create(); |
| 412 value->SetDouble("startTime", | 412 value->SetDouble("startTime", |
| 413 (start_time_ - base::TimeTicks()).InMicroseconds()); | 413 (start_time_ - base::TimeTicks()).InMicroseconds()); |
| 414 TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"), | 414 TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"), |
| 415 "CpuProfile", this, "data", std::move(value)); | 415 "Profile", this, "data", std::move(value)); |
| 416 } | 416 } |
| 417 | 417 |
| 418 void CpuProfile::AddPath(base::TimeTicks timestamp, | 418 void CpuProfile::AddPath(base::TimeTicks timestamp, |
| 419 const std::vector<CodeEntry*>& path, int src_line, | 419 const std::vector<CodeEntry*>& path, int src_line, |
| 420 bool update_stats) { | 420 bool update_stats) { |
| 421 ProfileNode* top_frame_node = | 421 ProfileNode* top_frame_node = |
| 422 top_down_.AddPathFromEnd(path, src_line, update_stats); | 422 top_down_.AddPathFromEnd(path, src_line, update_stats); |
| 423 if (record_samples_ && !timestamp.IsNull()) { | 423 if (record_samples_ && !timestamp.IsNull()) { |
| 424 timestamps_.Add(timestamp); | 424 timestamps_.Add(timestamp); |
| 425 samples_.Add(top_frame_node); | 425 samples_.Add(top_frame_node); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 459 } |
| 460 } | 460 } |
| 461 | 461 |
| 462 } // namespace | 462 } // namespace |
| 463 | 463 |
| 464 void CpuProfile::StreamPendingTraceEvents() { | 464 void CpuProfile::StreamPendingTraceEvents() { |
| 465 std::vector<const ProfileNode*> pending_nodes = top_down_.TakePendingNodes(); | 465 std::vector<const ProfileNode*> pending_nodes = top_down_.TakePendingNodes(); |
| 466 if (pending_nodes.empty() && !samples_.length()) return; | 466 if (pending_nodes.empty() && !samples_.length()) return; |
| 467 auto value = TracedValue::Create(); | 467 auto value = TracedValue::Create(); |
| 468 | 468 |
| 469 if (!pending_nodes.empty()) { | 469 if (!pending_nodes.empty() || streaming_next_sample_ != samples_.length()) { |
| 470 value->BeginArray("nodes"); | 470 value->BeginDictionary("cpuProfile"); |
| 471 for (auto node : pending_nodes) { | 471 if (!pending_nodes.empty()) { |
| 472 value->BeginDictionary(); | 472 value->BeginArray("nodes"); |
| 473 BuildNodeValue(node, value.get()); | 473 for (auto node : pending_nodes) { |
| 474 value->EndDictionary(); | 474 value->BeginDictionary(); |
| 475 BuildNodeValue(node, value.get()); |
| 476 value->EndDictionary(); |
| 477 } |
| 478 value->EndArray(); |
| 475 } | 479 } |
| 476 value->EndArray(); | 480 if (streaming_next_sample_ != samples_.length()) { |
| 481 value->BeginArray("samples"); |
| 482 for (int i = streaming_next_sample_; i < samples_.length(); ++i) { |
| 483 value->AppendInteger(samples_[i]->id()); |
| 484 } |
| 485 value->EndArray(); |
| 486 } |
| 487 value->EndDictionary(); |
| 477 } | 488 } |
| 478 | |
| 479 if (streaming_next_sample_ != samples_.length()) { | 489 if (streaming_next_sample_ != samples_.length()) { |
| 480 value->BeginArray("samples"); | |
| 481 for (int i = streaming_next_sample_; i < samples_.length(); ++i) { | |
| 482 value->AppendInteger(samples_[i]->id()); | |
| 483 } | |
| 484 value->EndArray(); | |
| 485 value->BeginArray("timeDeltas"); | 490 value->BeginArray("timeDeltas"); |
| 486 base::TimeTicks lastTimestamp = | 491 base::TimeTicks lastTimestamp = |
| 487 streaming_next_sample_ ? timestamps_[streaming_next_sample_ - 1] | 492 streaming_next_sample_ ? timestamps_[streaming_next_sample_ - 1] |
| 488 : start_time(); | 493 : start_time(); |
| 489 for (int i = streaming_next_sample_; i < timestamps_.length(); ++i) { | 494 for (int i = streaming_next_sample_; i < timestamps_.length(); ++i) { |
| 490 value->AppendInteger( | 495 value->AppendInteger( |
| 491 static_cast<int>((timestamps_[i] - lastTimestamp).InMicroseconds())); | 496 static_cast<int>((timestamps_[i] - lastTimestamp).InMicroseconds())); |
| 492 lastTimestamp = timestamps_[i]; | 497 lastTimestamp = timestamps_[i]; |
| 493 } | 498 } |
| 494 value->EndArray(); | 499 value->EndArray(); |
| 495 DCHECK(samples_.length() == timestamps_.length()); | 500 DCHECK(samples_.length() == timestamps_.length()); |
| 496 streaming_next_sample_ = samples_.length(); | 501 streaming_next_sample_ = samples_.length(); |
| 497 } | 502 } |
| 498 | 503 |
| 499 TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"), | 504 TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"), |
| 500 "CpuProfileChunk", this, "data", | 505 "ProfileChunk", this, "data", std::move(value)); |
| 501 std::move(value)); | |
| 502 } | 506 } |
| 503 | 507 |
| 504 void CpuProfile::FinishProfile() { | 508 void CpuProfile::FinishProfile() { |
| 505 end_time_ = base::TimeTicks::HighResolutionNow(); | 509 end_time_ = base::TimeTicks::HighResolutionNow(); |
| 506 StreamPendingTraceEvents(); | 510 StreamPendingTraceEvents(); |
| 507 auto value = TracedValue::Create(); | 511 auto value = TracedValue::Create(); |
| 508 value->SetDouble("endTime", (end_time_ - base::TimeTicks()).InMicroseconds()); | 512 value->SetDouble("endTime", (end_time_ - base::TimeTicks()).InMicroseconds()); |
| 509 TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"), | 513 TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"), |
| 510 "CpuProfileChunk", this, "data", | 514 "ProfileChunk", this, "data", std::move(value)); |
| 511 std::move(value)); | |
| 512 } | 515 } |
| 513 | 516 |
| 514 void CpuProfile::Print() { | 517 void CpuProfile::Print() { |
| 515 base::OS::Print("[Top down]:\n"); | 518 base::OS::Print("[Top down]:\n"); |
| 516 top_down_.Print(); | 519 top_down_.Print(); |
| 517 } | 520 } |
| 518 | 521 |
| 519 void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) { | 522 void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) { |
| 520 DeleteAllCoveredCode(addr, addr + size); | 523 DeleteAllCoveredCode(addr, addr + size); |
| 521 code_map_.insert({addr, CodeEntryInfo(entry, size)}); | 524 code_map_.insert({addr, CodeEntryInfo(entry, size)}); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 case EXTERNAL: | 770 case EXTERNAL: |
| 768 return CodeEntry::program_entry(); | 771 return CodeEntry::program_entry(); |
| 769 case IDLE: | 772 case IDLE: |
| 770 return CodeEntry::idle_entry(); | 773 return CodeEntry::idle_entry(); |
| 771 default: return NULL; | 774 default: return NULL; |
| 772 } | 775 } |
| 773 } | 776 } |
| 774 | 777 |
| 775 } // namespace internal | 778 } // namespace internal |
| 776 } // namespace v8 | 779 } // namespace v8 |
| OLD | NEW |