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

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: rebase 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
« no previous file with comments | « src/profiler/profile-generator.h ('k') | src/profiler/profiler-listener.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 } 461 }
427 462
428 void CodeMap::Print() { 463 void CodeMap::Print() {
429 for (auto it = code_map_.begin(); it != code_map_.end(); ++it) { 464 for (auto it = code_map_.begin(); it != code_map_.end(); ++it) {
430 base::OS::Print("%p %5d %s\n", static_cast<void*>(it->first), 465 base::OS::Print("%p %5d %s\n", static_cast<void*>(it->first),
431 it->second.size, it->second.entry->name()); 466 it->second.size, it->second.entry->name());
432 } 467 }
433 } 468 }
434 469
435 CpuProfilesCollection::CpuProfilesCollection(Isolate* isolate) 470 CpuProfilesCollection::CpuProfilesCollection(Isolate* isolate)
436 : function_and_resource_names_(isolate->heap()), 471 : resource_names_(isolate->heap()),
437 profiler_(nullptr), 472 profiler_(nullptr),
438 current_profiles_semaphore_(1) {} 473 current_profiles_semaphore_(1) {}
439 474
440 static void DeleteCodeEntry(CodeEntry** entry_ptr) {
441 delete *entry_ptr;
442 }
443
444
445 static void DeleteCpuProfile(CpuProfile** profile_ptr) { 475 static void DeleteCpuProfile(CpuProfile** profile_ptr) {
446 delete *profile_ptr; 476 delete *profile_ptr;
447 } 477 }
448 478
449 479
450 CpuProfilesCollection::~CpuProfilesCollection() { 480 CpuProfilesCollection::~CpuProfilesCollection() {
451 finished_profiles_.Iterate(DeleteCpuProfile); 481 finished_profiles_.Iterate(DeleteCpuProfile);
452 current_profiles_.Iterate(DeleteCpuProfile); 482 current_profiles_.Iterate(DeleteCpuProfile);
453 code_entries_.Iterate(DeleteCodeEntry);
454 } 483 }
455 484
456 485
457 bool CpuProfilesCollection::StartProfiling(const char* title, 486 bool CpuProfilesCollection::StartProfiling(const char* title,
458 bool record_samples) { 487 bool record_samples) {
459 current_profiles_semaphore_.Wait(); 488 current_profiles_semaphore_.Wait();
460 if (current_profiles_.length() >= kMaxSimultaneousProfiles) { 489 if (current_profiles_.length() >= kMaxSimultaneousProfiles) {
461 current_profiles_semaphore_.Signal(); 490 current_profiles_semaphore_.Signal();
462 return false; 491 return false;
463 } 492 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 // As starting / stopping profiles is rare relatively to this 549 // As starting / stopping profiles is rare relatively to this
521 // method, we don't bother minimizing the duration of lock holding, 550 // method, we don't bother minimizing the duration of lock holding,
522 // e.g. copying contents of the list to a local vector. 551 // e.g. copying contents of the list to a local vector.
523 current_profiles_semaphore_.Wait(); 552 current_profiles_semaphore_.Wait();
524 for (int i = 0; i < current_profiles_.length(); ++i) { 553 for (int i = 0; i < current_profiles_.length(); ++i) {
525 current_profiles_[i]->AddPath(timestamp, path, src_line, update_stats); 554 current_profiles_[i]->AddPath(timestamp, path, src_line, update_stats);
526 } 555 }
527 current_profiles_semaphore_.Signal(); 556 current_profiles_semaphore_.Signal();
528 } 557 }
529 558
530 CodeEntry* CpuProfilesCollection::NewCodeEntry(
531 CodeEventListener::LogEventsAndTags tag, const char* name,
532 const char* name_prefix, const char* resource_name, int line_number,
533 int column_number, JITLineInfoTable* line_info, Address instruction_start) {
534 CodeEntry* code_entry =
535 new CodeEntry(tag, name, name_prefix, resource_name, line_number,
536 column_number, line_info, instruction_start);
537 code_entries_.Add(code_entry);
538 return code_entry;
539 }
540
541
542 const char* const ProfileGenerator::kProgramEntryName =
543 "(program)";
544 const char* const ProfileGenerator::kIdleEntryName =
545 "(idle)";
546 const char* const ProfileGenerator::kGarbageCollectorEntryName =
547 "(garbage collector)";
548 const char* const ProfileGenerator::kUnresolvedFunctionName =
549 "(unresolved function)";
550
551 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles) 559 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles)
552 : profiles_(profiles), 560 : profiles_(profiles) {}
553 program_entry_(profiles->NewCodeEntry(CodeEventListener::FUNCTION_TAG,
554 kProgramEntryName)),
555 idle_entry_(profiles->NewCodeEntry(CodeEventListener::FUNCTION_TAG,
556 kIdleEntryName)),
557 gc_entry_(profiles->NewCodeEntry(CodeEventListener::BUILTIN_TAG,
558 kGarbageCollectorEntryName)),
559 unresolved_entry_(profiles->NewCodeEntry(CodeEventListener::FUNCTION_TAG,
560 kUnresolvedFunctionName)) {}
561 561
562 void ProfileGenerator::RecordTickSample(const TickSample& sample) { 562 void ProfileGenerator::RecordTickSample(const TickSample& sample) {
563 std::vector<CodeEntry*> entries; 563 std::vector<CodeEntry*> entries;
564 // Conservatively reserve space for stack frames + pc + function + vm-state. 564 // Conservatively reserve space for stack frames + pc + function + vm-state.
565 // There could in fact be more of them because of inlined entries. 565 // There could in fact be more of them because of inlined entries.
566 entries.reserve(sample.frames_count + 3); 566 entries.reserve(sample.frames_count + 3);
567 567
568 // The ProfileNode knows nothing about all versions of generated code for 568 // The ProfileNode knows nothing about all versions of generated code for
569 // the same JS function. The line number information associated with 569 // the same JS function. The line number information associated with
570 // the latest version of generated code is used to find a source line number 570 // 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
603 603
604 if (pc_entry->builtin_id() == Builtins::kFunctionPrototypeApply || 604 if (pc_entry->builtin_id() == Builtins::kFunctionPrototypeApply ||
605 pc_entry->builtin_id() == Builtins::kFunctionPrototypeCall) { 605 pc_entry->builtin_id() == Builtins::kFunctionPrototypeCall) {
606 // When current function is either the Function.prototype.apply or the 606 // When current function is either the Function.prototype.apply or the
607 // Function.prototype.call builtin the top frame is either frame of 607 // Function.prototype.call builtin the top frame is either frame of
608 // the calling JS function or internal frame. 608 // the calling JS function or internal frame.
609 // In the latter case we know the caller for sure but in the 609 // In the latter case we know the caller for sure but in the
610 // former case we don't so we simply replace the frame with 610 // former case we don't so we simply replace the frame with
611 // 'unresolved' entry. 611 // 'unresolved' entry.
612 if (!sample.has_external_callback) { 612 if (!sample.has_external_callback) {
613 entries.push_back(unresolved_entry_); 613 entries.push_back(CodeEntry::unresolved_entry());
614 } 614 }
615 } 615 }
616 } 616 }
617 } 617 }
618 618
619 for (const Address *stack_pos = sample.stack, 619 for (const Address *stack_pos = sample.stack,
620 *stack_end = stack_pos + sample.frames_count; 620 *stack_end = stack_pos + sample.frames_count;
621 stack_pos != stack_end; ++stack_pos) { 621 stack_pos != stack_end; ++stack_pos) {
622 CodeEntry* entry = code_map_.FindEntry(*stack_pos); 622 CodeEntry* entry = code_map_.FindEntry(*stack_pos);
623 623
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 } 660 }
661 661
662 profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line, 662 profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line,
663 sample.update_stats); 663 sample.update_stats);
664 } 664 }
665 665
666 666
667 CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) { 667 CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
668 switch (tag) { 668 switch (tag) {
669 case GC: 669 case GC:
670 return gc_entry_; 670 return CodeEntry::gc_entry();
671 case JS: 671 case JS:
672 case COMPILER: 672 case COMPILER:
673 // DOM events handlers are reported as OTHER / EXTERNAL entries. 673 // DOM events handlers are reported as OTHER / EXTERNAL entries.
674 // To avoid confusing people, let's put all these entries into 674 // To avoid confusing people, let's put all these entries into
675 // one bucket. 675 // one bucket.
676 case OTHER: 676 case OTHER:
677 case EXTERNAL: 677 case EXTERNAL:
678 return program_entry_; 678 return CodeEntry::program_entry();
679 case IDLE: 679 case IDLE:
680 return idle_entry_; 680 return CodeEntry::idle_entry();
681 default: return NULL; 681 default: return NULL;
682 } 682 }
683 } 683 }
684 684
685 } // namespace internal 685 } // namespace internal
686 } // namespace v8 686 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/profile-generator.h ('k') | src/profiler/profiler-listener.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698