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

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

Issue 6551011: Fix CPU profiling for Crankshaft. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 tag_ = source.tag_; 149 tag_ = source.tag_;
150 name_prefix_ = source.name_prefix_; 150 name_prefix_ = source.name_prefix_;
151 name_ = source.name_; 151 name_ = source.name_;
152 resource_name_ = source.resource_name_; 152 resource_name_ = source.resource_name_;
153 line_number_ = source.line_number_; 153 line_number_ = source.line_number_;
154 } 154 }
155 155
156 156
157 uint32_t CodeEntry::GetCallUid() const { 157 uint32_t CodeEntry::GetCallUid() const {
158 uint32_t hash = ComputeIntegerHash(tag_); 158 uint32_t hash = ComputeIntegerHash(tag_);
159 hash ^= ComputeIntegerHash( 159 if (shared_id_ != 0) {
160 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_prefix_))); 160 hash ^= ComputeIntegerHash(
161 hash ^= ComputeIntegerHash( 161 static_cast<uint32_t>(shared_id_));
162 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_))); 162 } else {
163 hash ^= ComputeIntegerHash( 163 hash ^= ComputeIntegerHash(
164 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(resource_name_))); 164 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_prefix_)));
165 hash ^= ComputeIntegerHash(line_number_); 165 hash ^= ComputeIntegerHash(
166 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_)));
167 hash ^= ComputeIntegerHash(
168 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(resource_name_)));
169 hash ^= ComputeIntegerHash(line_number_);
170 }
166 return hash; 171 return hash;
167 } 172 }
168 173
169 174
170 bool CodeEntry::IsSameAs(CodeEntry* entry) const { 175 bool CodeEntry::IsSameAs(CodeEntry* entry) const {
171 return this == entry 176 return this == entry
172 || (tag_ == entry->tag_ 177 || (tag_ == entry->tag_
173 && name_prefix_ == entry->name_prefix_ 178 && shared_id_ == entry->shared_id_
174 && name_ == entry->name_ 179 && (shared_id_ != 0
175 && resource_name_ == entry->resource_name_ 180 || (name_prefix_ == entry->name_prefix_
176 && line_number_ == entry->line_number_); 181 && name_ == entry->name_
182 && resource_name_ == entry->resource_name_
183 && line_number_ == entry->line_number_)));
177 } 184 }
178 185
179 186
180 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) { 187 ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
181 HashMap::Entry* map_entry = 188 HashMap::Entry* map_entry =
182 children_.Lookup(entry, CodeEntryHash(entry), false); 189 children_.Lookup(entry, CodeEntryHash(entry), false);
183 return map_entry != NULL ? 190 return map_entry != NULL ?
184 reinterpret_cast<ProfileNode*>(map_entry->value) : NULL; 191 reinterpret_cast<ProfileNode*>(map_entry->value) : NULL;
185 } 192 }
186 193
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 458
452 459
453 void CpuProfile::Print() { 460 void CpuProfile::Print() {
454 OS::Print("[Top down]:\n"); 461 OS::Print("[Top down]:\n");
455 top_down_.Print(); 462 top_down_.Print();
456 OS::Print("[Bottom up]:\n"); 463 OS::Print("[Bottom up]:\n");
457 bottom_up_.Print(); 464 bottom_up_.Print();
458 } 465 }
459 466
460 467
468 const CodeEntry* CodeMap::kSfiCodeEntry = NULL;
461 const CodeMap::CodeTreeConfig::Key CodeMap::CodeTreeConfig::kNoKey = NULL; 469 const CodeMap::CodeTreeConfig::Key CodeMap::CodeTreeConfig::kNoKey = NULL;
462 const CodeMap::CodeTreeConfig::Value CodeMap::CodeTreeConfig::kNoValue = 470 const CodeMap::CodeTreeConfig::Value CodeMap::CodeTreeConfig::kNoValue =
463 CodeMap::CodeEntryInfo(NULL, 0); 471 CodeMap::CodeEntryInfo(NULL, 0);
464 472
465 473
466 void CodeMap::AddAlias(Address start, CodeEntry* entry, Address code_start) {
467 CodeTree::Locator locator;
468 if (tree_.Find(code_start, &locator)) {
469 const CodeEntryInfo& code_info = locator.value();
470 if (tree_.Insert(start, &locator)) {
471 entry->CopyData(*code_info.entry);
472 locator.set_value(CodeEntryInfo(entry, code_info.size));
473 }
474 }
475 }
476
477
478 CodeEntry* CodeMap::FindEntry(Address addr) { 474 CodeEntry* CodeMap::FindEntry(Address addr) {
479 CodeTree::Locator locator; 475 CodeTree::Locator locator;
480 if (tree_.FindGreatestLessThan(addr, &locator)) { 476 if (tree_.FindGreatestLessThan(addr, &locator)) {
481 // locator.key() <= addr. Need to check that addr is within entry. 477 // locator.key() <= addr. Need to check that addr is within entry.
482 const CodeEntryInfo& entry = locator.value(); 478 const CodeEntryInfo& entry = locator.value();
483 if (addr < (locator.key() + entry.size)) 479 if (addr < (locator.key() + entry.size))
484 return entry.entry; 480 return entry.entry;
485 } 481 }
486 return NULL; 482 return NULL;
487 } 483 }
488 484
489 485
486 int CodeMap::GetSFITag(Address addr) {
487 CodeTree::Locator locator;
488 // For SFI entries, 'size' field is used to store their IDs.
489 if (tree_.Find(addr, &locator)) {
490 const CodeEntryInfo& entry = locator.value();
491 ASSERT(entry.entry == kSfiCodeEntry);
492 return entry.size;
493 } else {
494 tree_.Insert(addr, &locator);
495 int tag = next_sfi_tag_++;
496 locator.set_value(
497 CodeEntryInfo(const_cast<CodeEntry*>(kSfiCodeEntry), tag));
498 return tag;
499 }
500 }
501
502
490 void CodeMap::CodeTreePrinter::Call( 503 void CodeMap::CodeTreePrinter::Call(
491 const Address& key, const CodeMap::CodeEntryInfo& value) { 504 const Address& key, const CodeMap::CodeEntryInfo& value) {
492 OS::Print("%p %5d %s\n", key, value.size, value.entry->name()); 505 OS::Print("%p %5d %s\n", key, value.size, value.entry->name());
493 } 506 }
494 507
495 508
496 void CodeMap::Print() { 509 void CodeMap::Print() {
497 CodeTreePrinter printer; 510 CodeTreePrinter printer;
498 tree_.ForEach(&printer); 511 tree_.ForEach(&printer);
499 } 512 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 "args_count: ", 721 "args_count: ",
709 GetName(args_count), 722 GetName(args_count),
710 "", 723 "",
711 v8::CpuProfileNode::kNoLineNumberInfo, 724 v8::CpuProfileNode::kNoLineNumberInfo,
712 TokenEnumerator::kInheritsSecurityToken); 725 TokenEnumerator::kInheritsSecurityToken);
713 code_entries_.Add(entry); 726 code_entries_.Add(entry);
714 return entry; 727 return entry;
715 } 728 }
716 729
717 730
718 CodeEntry* CpuProfilesCollection::NewCodeEntry(int security_token_id) {
719 CodeEntry* entry = new CodeEntry(security_token_id);
720 code_entries_.Add(entry);
721 return entry;
722 }
723
724
725 void CpuProfilesCollection::AddPathToCurrentProfiles( 731 void CpuProfilesCollection::AddPathToCurrentProfiles(
726 const Vector<CodeEntry*>& path) { 732 const Vector<CodeEntry*>& path) {
727 // As starting / stopping profiles is rare relatively to this 733 // As starting / stopping profiles is rare relatively to this
728 // method, we don't bother minimizing the duration of lock holding, 734 // method, we don't bother minimizing the duration of lock holding,
729 // e.g. copying contents of the list to a local vector. 735 // e.g. copying contents of the list to a local vector.
730 current_profiles_semaphore_->Wait(); 736 current_profiles_semaphore_->Wait();
731 for (int i = 0; i < current_profiles_.length(); ++i) { 737 for (int i = 0; i < current_profiles_.length(); ++i) {
732 current_profiles_[i]->AddPath(path); 738 current_profiles_[i]->AddPath(path);
733 } 739 }
734 current_profiles_semaphore_->Signal(); 740 current_profiles_semaphore_->Signal();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 // entries vector with NULL values. 787 // entries vector with NULL values.
782 CodeEntry** entry = entries.start(); 788 CodeEntry** entry = entries.start();
783 memset(entry, 0, entries.length() * sizeof(*entry)); 789 memset(entry, 0, entries.length() * sizeof(*entry));
784 if (sample.pc != NULL) { 790 if (sample.pc != NULL) {
785 *entry++ = code_map_.FindEntry(sample.pc); 791 *entry++ = code_map_.FindEntry(sample.pc);
786 792
787 if (sample.function != NULL) { 793 if (sample.function != NULL) {
788 *entry = code_map_.FindEntry(sample.function); 794 *entry = code_map_.FindEntry(sample.function);
789 if (*entry != NULL && !(*entry)->is_js_function()) { 795 if (*entry != NULL && !(*entry)->is_js_function()) {
790 *entry = NULL; 796 *entry = NULL;
791 } else {
792 CodeEntry* pc_entry = *entries.start();
793 if (pc_entry == NULL) {
794 *entry = NULL;
795 } else if (pc_entry->is_js_function()) {
796 // Use function entry in favor of pc entry, as function
797 // entry has security token.
798 *entries.start() = NULL;
799 }
800 } 797 }
801 entry++; 798 entry++;
802 } 799 }
803 800
804 for (const Address *stack_pos = sample.stack, 801 for (const Address *stack_pos = sample.stack,
805 *stack_end = stack_pos + sample.frames_count; 802 *stack_end = stack_pos + sample.frames_count;
806 stack_pos != stack_end; 803 stack_pos != stack_end;
807 ++stack_pos) { 804 ++stack_pos) {
808 *entry++ = code_map_.FindEntry(*stack_pos); 805 *entry++ = code_map_.FindEntry(*stack_pos);
809 } 806 }
(...skipping 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after
2833 2830
2834 2831
2835 String* GetConstructorNameForHeapProfile(JSObject* object) { 2832 String* GetConstructorNameForHeapProfile(JSObject* object) {
2836 if (object->IsJSFunction()) return Heap::closure_symbol(); 2833 if (object->IsJSFunction()) return Heap::closure_symbol();
2837 return object->constructor_name(); 2834 return object->constructor_name();
2838 } 2835 }
2839 2836
2840 } } // namespace v8::internal 2837 } } // namespace v8::internal
2841 2838
2842 #endif // ENABLE_LOGGING_AND_PROFILING 2839 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698