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 |