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

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: 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 29 matching lines...) Expand all
40 } 40 }
41 return it->second; 41 return it->second;
42 } 42 }
43 43
44 44
45 const char* const CodeEntry::kEmptyNamePrefix = ""; 45 const char* const CodeEntry::kEmptyNamePrefix = "";
46 const char* const CodeEntry::kEmptyResourceName = ""; 46 const char* const CodeEntry::kEmptyResourceName = "";
47 const char* const CodeEntry::kEmptyBailoutReason = ""; 47 const char* const CodeEntry::kEmptyBailoutReason = "";
48 const char* const CodeEntry::kNoDeoptReason = ""; 48 const char* const CodeEntry::kNoDeoptReason = "";
49 49
50 const char* const CodeEntry::kProgramEntryName = "(program)";
51 const char* const CodeEntry::kIdleEntryName = "(idle)";
52 const char* const CodeEntry::kGarbageCollectorEntryName = "(garbage collector)";
53 const char* const CodeEntry::kUnresolvedFunctionName = "(unresolved function)";
54
55 base::LazyDynamicInstance<CodeEntry, CodeEntry::ProgramEntryCreateTrait>::type
56 CodeEntry::kProgramEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
57
58 base::LazyDynamicInstance<CodeEntry, CodeEntry::IdleEntryCreateTrait>::type
59 CodeEntry::kIdleEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
60
61 base::LazyDynamicInstance<CodeEntry, CodeEntry::GCEntryCreateTrait>::type
62 CodeEntry::kGCEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
63
64 base::LazyDynamicInstance<CodeEntry,
65 CodeEntry::UnresolvedEntryCreateTrait>::type
66 CodeEntry::kUnresolvedEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
67
68 CodeEntry* CodeEntry::ProgramEntryCreateTrait::Create() {
69 return new CodeEntry(Logger::FUNCTION_TAG, CodeEntry::kProgramEntryName);
70 }
71
72 CodeEntry* CodeEntry::IdleEntryCreateTrait::Create() {
73 return new CodeEntry(Logger::FUNCTION_TAG, CodeEntry::kIdleEntryName);
74 }
75
76 CodeEntry* CodeEntry::GCEntryCreateTrait::Create() {
77 return new CodeEntry(Logger::BUILTIN_TAG,
78 CodeEntry::kGarbageCollectorEntryName);
79 }
80
81 CodeEntry* CodeEntry::UnresolvedEntryCreateTrait::Create() {
82 return new CodeEntry(Logger::FUNCTION_TAG,
83 CodeEntry::kUnresolvedFunctionName);
84 }
50 85
51 CodeEntry::~CodeEntry() { 86 CodeEntry::~CodeEntry() {
52 delete line_info_; 87 delete line_info_;
53 for (auto location : inline_locations_) { 88 for (auto location : inline_locations_) {
54 for (auto entry : location.second) { 89 for (auto entry : location.second) {
55 delete entry; 90 delete entry;
56 } 91 }
57 } 92 }
58 } 93 }
59 94
(...skipping 366 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(Heap* heap) 470 CpuProfilesCollection::CpuProfilesCollection(Heap* heap)
436 : function_and_resource_names_(heap), 471 : resource_names_(heap),
437 isolate_(heap->isolate()), 472 isolate_(heap->isolate()),
438 current_profiles_semaphore_(1) {} 473 current_profiles_semaphore_(1) {}
439 474
440
441 static void DeleteCodeEntry(CodeEntry** entry_ptr) {
442 delete *entry_ptr;
443 }
444
445
446 static void DeleteCpuProfile(CpuProfile** profile_ptr) { 475 static void DeleteCpuProfile(CpuProfile** profile_ptr) {
447 delete *profile_ptr; 476 delete *profile_ptr;
448 } 477 }
449 478
450 479
451 CpuProfilesCollection::~CpuProfilesCollection() { 480 CpuProfilesCollection::~CpuProfilesCollection() {
452 finished_profiles_.Iterate(DeleteCpuProfile); 481 finished_profiles_.Iterate(DeleteCpuProfile);
453 current_profiles_.Iterate(DeleteCpuProfile); 482 current_profiles_.Iterate(DeleteCpuProfile);
454 code_entries_.Iterate(DeleteCodeEntry);
455 } 483 }
456 484
457 485
458 bool CpuProfilesCollection::StartProfiling(const char* title, 486 bool CpuProfilesCollection::StartProfiling(const char* title,
459 bool record_samples) { 487 bool record_samples) {
460 current_profiles_semaphore_.Wait(); 488 current_profiles_semaphore_.Wait();
461 if (current_profiles_.length() >= kMaxSimultaneousProfiles) { 489 if (current_profiles_.length() >= kMaxSimultaneousProfiles) {
462 current_profiles_semaphore_.Signal(); 490 current_profiles_semaphore_.Signal();
463 return false; 491 return false;
464 } 492 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 // As starting / stopping profiles is rare relatively to this 549 // As starting / stopping profiles is rare relatively to this
522 // method, we don't bother minimizing the duration of lock holding, 550 // method, we don't bother minimizing the duration of lock holding,
523 // e.g. copying contents of the list to a local vector. 551 // e.g. copying contents of the list to a local vector.
524 current_profiles_semaphore_.Wait(); 552 current_profiles_semaphore_.Wait();
525 for (int i = 0; i < current_profiles_.length(); ++i) { 553 for (int i = 0; i < current_profiles_.length(); ++i) {
526 current_profiles_[i]->AddPath(timestamp, path, src_line, update_stats); 554 current_profiles_[i]->AddPath(timestamp, path, src_line, update_stats);
527 } 555 }
528 current_profiles_semaphore_.Signal(); 556 current_profiles_semaphore_.Signal();
529 } 557 }
530 558
531
532 CodeEntry* CpuProfilesCollection::NewCodeEntry(
533 Logger::LogEventsAndTags tag, const char* name, const char* name_prefix,
534 const char* resource_name, int line_number, int column_number,
535 JITLineInfoTable* line_info, Address instruction_start) {
536 CodeEntry* code_entry =
537 new CodeEntry(tag, name, name_prefix, resource_name, line_number,
538 column_number, line_info, instruction_start);
539 code_entries_.Add(code_entry);
540 return code_entry;
541 }
542
543
544 const char* const ProfileGenerator::kProgramEntryName =
545 "(program)";
546 const char* const ProfileGenerator::kIdleEntryName =
547 "(idle)";
548 const char* const ProfileGenerator::kGarbageCollectorEntryName =
549 "(garbage collector)";
550 const char* const ProfileGenerator::kUnresolvedFunctionName =
551 "(unresolved function)";
552
553
554 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles) 559 ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles)
555 : profiles_(profiles), 560 : profiles_(profiles) {}
556 program_entry_(
557 profiles->NewCodeEntry(Logger::FUNCTION_TAG, kProgramEntryName)),
558 idle_entry_(
559 profiles->NewCodeEntry(Logger::FUNCTION_TAG, kIdleEntryName)),
560 gc_entry_(
561 profiles->NewCodeEntry(Logger::BUILTIN_TAG,
562 kGarbageCollectorEntryName)),
563 unresolved_entry_(
564 profiles->NewCodeEntry(Logger::FUNCTION_TAG,
565 kUnresolvedFunctionName)) {
566 }
567
568 561
569 void ProfileGenerator::RecordTickSample(const TickSample& sample) { 562 void ProfileGenerator::RecordTickSample(const TickSample& sample) {
570 std::vector<CodeEntry*> entries; 563 std::vector<CodeEntry*> entries;
571 // Conservatively reserve space for stack frames + pc + function + vm-state. 564 // Conservatively reserve space for stack frames + pc + function + vm-state.
572 // 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.
573 entries.reserve(sample.frames_count + 3); 566 entries.reserve(sample.frames_count + 3);
574 567
575 // The ProfileNode knows nothing about all versions of generated code for 568 // The ProfileNode knows nothing about all versions of generated code for
576 // the same JS function. The line number information associated with 569 // the same JS function. The line number information associated with
577 // 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
610 603
611 if (pc_entry->builtin_id() == Builtins::kFunctionPrototypeApply || 604 if (pc_entry->builtin_id() == Builtins::kFunctionPrototypeApply ||
612 pc_entry->builtin_id() == Builtins::kFunctionPrototypeCall) { 605 pc_entry->builtin_id() == Builtins::kFunctionPrototypeCall) {
613 // When current function is either the Function.prototype.apply or the 606 // When current function is either the Function.prototype.apply or the
614 // Function.prototype.call builtin the top frame is either frame of 607 // Function.prototype.call builtin the top frame is either frame of
615 // the calling JS function or internal frame. 608 // the calling JS function or internal frame.
616 // 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
617 // 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
618 // 'unresolved' entry. 611 // 'unresolved' entry.
619 if (!sample.has_external_callback) { 612 if (!sample.has_external_callback) {
620 entries.push_back(unresolved_entry_); 613 entries.push_back(CodeEntry::unresolved_entry());
621 } 614 }
622 } 615 }
623 } 616 }
624 } 617 }
625 618
626 for (const Address *stack_pos = sample.stack, 619 for (const Address *stack_pos = sample.stack,
627 *stack_end = stack_pos + sample.frames_count; 620 *stack_end = stack_pos + sample.frames_count;
628 stack_pos != stack_end; ++stack_pos) { 621 stack_pos != stack_end; ++stack_pos) {
629 CodeEntry* entry = code_map_.FindEntry(*stack_pos); 622 CodeEntry* entry = code_map_.FindEntry(*stack_pos);
630 623
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 } 660 }
668 661
669 profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line, 662 profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line,
670 sample.update_stats); 663 sample.update_stats);
671 } 664 }
672 665
673 666
674 CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) { 667 CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
675 switch (tag) { 668 switch (tag) {
676 case GC: 669 case GC:
677 return gc_entry_; 670 return CodeEntry::gc_entry();
678 case JS: 671 case JS:
679 case COMPILER: 672 case COMPILER:
680 // DOM events handlers are reported as OTHER / EXTERNAL entries. 673 // DOM events handlers are reported as OTHER / EXTERNAL entries.
681 // To avoid confusing people, let's put all these entries into 674 // To avoid confusing people, let's put all these entries into
682 // one bucket. 675 // one bucket.
683 case OTHER: 676 case OTHER:
684 case EXTERNAL: 677 case EXTERNAL:
685 return program_entry_; 678 return CodeEntry::program_entry();
686 case IDLE: 679 case IDLE:
687 return idle_entry_; 680 return CodeEntry::idle_entry();
688 default: return NULL; 681 default: return NULL;
689 } 682 }
690 } 683 }
691 684
692 } // namespace internal 685 } // namespace internal
693 } // namespace v8 686 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698