Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: src/profiler/profile-generator.cc

Issue 2053523003: Refactor CpuProfiler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Move CpuProfilerManager to .cc Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/ast/scopeinfo.h" 7 #include "src/ast/scopeinfo.h"
8 #include "src/base/adapters.h" 8 #include "src/base/adapters.h"
9 #include "src/debug/debug.h" 9 #include "src/debug/debug.h"
10 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
(...skipping 30 matching lines...) Expand all
41 } 41 }
42 return it->second; 42 return it->second;
43 } 43 }
44 44
45 45
46 const char* const CodeEntry::kEmptyNamePrefix = ""; 46 const char* const CodeEntry::kEmptyNamePrefix = "";
47 const char* const CodeEntry::kEmptyResourceName = ""; 47 const char* const CodeEntry::kEmptyResourceName = "";
48 const char* const CodeEntry::kEmptyBailoutReason = ""; 48 const char* const CodeEntry::kEmptyBailoutReason = "";
49 const char* const CodeEntry::kNoDeoptReason = ""; 49 const char* const CodeEntry::kNoDeoptReason = "";
50 50
51 const char* const CodeEntry::kProgramEntryName = "(program)";
52 const char* const CodeEntry::kIdleEntryName = "(idle)";
53 const char* const CodeEntry::kGarbageCollectorEntryName = "(garbage collector)";
54 const char* const CodeEntry::kUnresolvedFunctionName = "(unresolved function)";
55
56 base::LazyDynamicInstance<CodeEntry, CodeEntry::ProgramEntryCreateTrait>::type
57 CodeEntry::kProgramEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
58
59 base::LazyDynamicInstance<CodeEntry, CodeEntry::IdleEntryCreateTrait>::type
60 CodeEntry::kIdleEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
61
62 base::LazyDynamicInstance<CodeEntry, CodeEntry::GCEntryCreateTrait>::type
63 CodeEntry::kGCEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
64
65 base::LazyDynamicInstance<CodeEntry,
66 CodeEntry::UnresolvedEntryCreateTrait>::type
67 CodeEntry::kUnresolvedEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
68
69 CodeEntry* CodeEntry::ProgramEntryCreateTrait::Create() {
70 return new CodeEntry(Logger::FUNCTION_TAG, CodeEntry::kProgramEntryName);
71 }
72
73 CodeEntry* CodeEntry::IdleEntryCreateTrait::Create() {
74 return new CodeEntry(Logger::FUNCTION_TAG, CodeEntry::kIdleEntryName);
75 }
76
77 CodeEntry* CodeEntry::GCEntryCreateTrait::Create() {
78 return new CodeEntry(Logger::BUILTIN_TAG,
79 CodeEntry::kGarbageCollectorEntryName);
80 }
81
82 CodeEntry* CodeEntry::UnresolvedEntryCreateTrait::Create() {
83 return new CodeEntry(Logger::FUNCTION_TAG,
84 CodeEntry::kUnresolvedFunctionName);
85 }
51 86
52 CodeEntry::~CodeEntry() { 87 CodeEntry::~CodeEntry() {
53 delete line_info_; 88 delete line_info_;
54 for (auto location : inline_locations_) { 89 for (auto location : inline_locations_) {
55 for (auto entry : location.second) { 90 for (auto entry : location.second) {
56 delete entry; 91 delete entry;
57 } 92 }
58 } 93 }
59 } 94 }
60 95
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 base::OS::Print("%p %5d %s\n", static_cast<void*>(key), value.size, 487 base::OS::Print("%p %5d %s\n", static_cast<void*>(key), value.size,
453 value.entry->name()); 488 value.entry->name());
454 } 489 }
455 490
456 491
457 void CodeMap::Print() { 492 void CodeMap::Print() {
458 CodeTreePrinter printer; 493 CodeTreePrinter printer;
459 tree_.ForEach(&printer); 494 tree_.ForEach(&printer);
460 } 495 }
461 496
462
463 CpuProfilesCollection::CpuProfilesCollection(Heap* heap) 497 CpuProfilesCollection::CpuProfilesCollection(Heap* heap)
464 : function_and_resource_names_(heap), 498 : resource_names_(heap),
465 isolate_(heap->isolate()), 499 isolate_(heap->isolate()),
466 current_profiles_semaphore_(1) {} 500 current_profiles_semaphore_(1) {}
467 501
468
469 static void DeleteCodeEntry(CodeEntry** entry_ptr) {
470 delete *entry_ptr;
471 }
472
473
474 static void DeleteCpuProfile(CpuProfile** profile_ptr) { 502 static void DeleteCpuProfile(CpuProfile** profile_ptr) {
475 delete *profile_ptr; 503 delete *profile_ptr;
476 } 504 }
477 505
478 506
479 CpuProfilesCollection::~CpuProfilesCollection() { 507 CpuProfilesCollection::~CpuProfilesCollection() {
480 finished_profiles_.Iterate(DeleteCpuProfile); 508 finished_profiles_.Iterate(DeleteCpuProfile);
481 current_profiles_.Iterate(DeleteCpuProfile); 509 current_profiles_.Iterate(DeleteCpuProfile);
482 code_entries_.Iterate(DeleteCodeEntry);
483 } 510 }
484 511
485 512
486 bool CpuProfilesCollection::StartProfiling(const char* title, 513 bool CpuProfilesCollection::StartProfiling(const char* title,
487 bool record_samples) { 514 bool record_samples) {
488 current_profiles_semaphore_.Wait(); 515 current_profiles_semaphore_.Wait();
489 if (current_profiles_.length() >= kMaxSimultaneousProfiles) { 516 if (current_profiles_.length() >= kMaxSimultaneousProfiles) {
490 current_profiles_semaphore_.Signal(); 517 current_profiles_semaphore_.Signal();
491 return false; 518 return false;
492 } 519 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 // As starting / stopping profiles is rare relatively to this 576 // As starting / stopping profiles is rare relatively to this
550 // method, we don't bother minimizing the duration of lock holding, 577 // method, we don't bother minimizing the duration of lock holding,
551 // e.g. copying contents of the list to a local vector. 578 // e.g. copying contents of the list to a local vector.
552 current_profiles_semaphore_.Wait(); 579 current_profiles_semaphore_.Wait();
553 for (int i = 0; i < current_profiles_.length(); ++i) { 580 for (int i = 0; i < current_profiles_.length(); ++i) {
554 current_profiles_[i]->AddPath(timestamp, path, src_line, update_stats); 581 current_profiles_[i]->AddPath(timestamp, path, src_line, update_stats);
555 } 582 }
556 current_profiles_semaphore_.Signal(); 583 current_profiles_semaphore_.Signal();
557 } 584 }
558 585
559
560 CodeEntry* CpuProfilesCollection::NewCodeEntry(
561 Logger::LogEventsAndTags tag, const char* name, const char* name_prefix,
562 const char* resource_name, int line_number, int column_number,
563 JITLineInfoTable* line_info, Address instruction_start) {
564 CodeEntry* code_entry =
565 new CodeEntry(tag, name, name_prefix, resource_name, line_number,
566 column_number, line_info, instruction_start);
567 code_entries_.Add(code_entry);
568 return code_entry;
569 }
570
571
572 const char* const ProfileGenerator::kProgramEntryName =
573 "(program)";
574 const char* const ProfileGenerator::kIdleEntryName =
575 "(idle)";
576 const char* const ProfileGenerator::kGarbageCollectorEntryName =
577 "(garbage collector)";
578 const char* const ProfileGenerator::kUnresolvedFunctionName =
579 "(unresolved function)";
580
581
582 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles) 586 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles)
583 : profiles_(profiles), 587 : profiles_(profiles) {}
584 program_entry_(
585 profiles->NewCodeEntry(Logger::FUNCTION_TAG, kProgramEntryName)),
586 idle_entry_(
587 profiles->NewCodeEntry(Logger::FUNCTION_TAG, kIdleEntryName)),
588 gc_entry_(
589 profiles->NewCodeEntry(Logger::BUILTIN_TAG,
590 kGarbageCollectorEntryName)),
591 unresolved_entry_(
592 profiles->NewCodeEntry(Logger::FUNCTION_TAG,
593 kUnresolvedFunctionName)) {
594 }
595
596 588
597 void ProfileGenerator::RecordTickSample(const TickSample& sample) { 589 void ProfileGenerator::RecordTickSample(const TickSample& sample) {
598 std::vector<CodeEntry*> entries; 590 std::vector<CodeEntry*> entries;
599 // Conservatively reserve space for stack frames + pc + function + vm-state. 591 // Conservatively reserve space for stack frames + pc + function + vm-state.
600 // There could in fact be more of them because of inlined entries. 592 // There could in fact be more of them because of inlined entries.
601 entries.reserve(sample.frames_count + 3); 593 entries.reserve(sample.frames_count + 3);
602 594
603 // The ProfileNode knows nothing about all versions of generated code for 595 // The ProfileNode knows nothing about all versions of generated code for
604 // the same JS function. The line number information associated with 596 // the same JS function. The line number information associated with
605 // the latest version of generated code is used to find a source line number 597 // the latest version of generated code is used to find a source line number
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 630
639 if (pc_entry->builtin_id() == Builtins::kFunctionPrototypeApply || 631 if (pc_entry->builtin_id() == Builtins::kFunctionPrototypeApply ||
640 pc_entry->builtin_id() == Builtins::kFunctionPrototypeCall) { 632 pc_entry->builtin_id() == Builtins::kFunctionPrototypeCall) {
641 // When current function is either the Function.prototype.apply or the 633 // When current function is either the Function.prototype.apply or the
642 // Function.prototype.call builtin the top frame is either frame of 634 // Function.prototype.call builtin the top frame is either frame of
643 // the calling JS function or internal frame. 635 // the calling JS function or internal frame.
644 // In the latter case we know the caller for sure but in the 636 // In the latter case we know the caller for sure but in the
645 // former case we don't so we simply replace the frame with 637 // former case we don't so we simply replace the frame with
646 // 'unresolved' entry. 638 // 'unresolved' entry.
647 if (!sample.has_external_callback) { 639 if (!sample.has_external_callback) {
648 entries.push_back(unresolved_entry_); 640 entries.push_back(CodeEntry::unresolved_entry());
649 } 641 }
650 } 642 }
651 } 643 }
652 } 644 }
653 645
654 for (const Address *stack_pos = sample.stack, 646 for (const Address *stack_pos = sample.stack,
655 *stack_end = stack_pos + sample.frames_count; 647 *stack_end = stack_pos + sample.frames_count;
656 stack_pos != stack_end; ++stack_pos) { 648 stack_pos != stack_end; ++stack_pos) {
657 CodeEntry* entry = code_map_.FindEntry(*stack_pos); 649 CodeEntry* entry = code_map_.FindEntry(*stack_pos);
658 650
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 } 687 }
696 688
697 profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line, 689 profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line,
698 sample.update_stats); 690 sample.update_stats);
699 } 691 }
700 692
701 693
702 CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) { 694 CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
703 switch (tag) { 695 switch (tag) {
704 case GC: 696 case GC:
705 return gc_entry_; 697 return CodeEntry::gc_entry();
706 case JS: 698 case JS:
707 case COMPILER: 699 case COMPILER:
708 // DOM events handlers are reported as OTHER / EXTERNAL entries. 700 // DOM events handlers are reported as OTHER / EXTERNAL entries.
709 // To avoid confusing people, let's put all these entries into 701 // To avoid confusing people, let's put all these entries into
710 // one bucket. 702 // one bucket.
711 case OTHER: 703 case OTHER:
712 case EXTERNAL: 704 case EXTERNAL:
713 return program_entry_; 705 return CodeEntry::program_entry();
714 case IDLE: 706 case IDLE:
715 return idle_entry_; 707 return CodeEntry::idle_entry();
716 default: return NULL; 708 default: return NULL;
717 } 709 }
718 } 710 }
719 711
720 } // namespace internal 712 } // namespace internal
721 } // namespace v8 713 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698