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

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

Issue 14253015: Skip samples where top function's stack frame is not setup properly (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: mips->mipsel Created 7 years, 7 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "profile-generator-inl.h" 30 #include "profile-generator-inl.h"
31 31
32 #include "compiler.h"
32 #include "global-handles.h" 33 #include "global-handles.h"
33 #include "scopeinfo.h" 34 #include "scopeinfo.h"
34 #include "unicode.h" 35 #include "unicode.h"
35 #include "zone-inl.h" 36 #include "zone-inl.h"
36 #include "debug.h" 37 #include "debug.h"
37 38
38 namespace v8 { 39 namespace v8 {
39 namespace internal { 40 namespace internal {
40 41
41 42
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 size += sizeof(HashMap::Entry) * names_.capacity(); 180 size += sizeof(HashMap::Entry) * names_.capacity();
180 for (HashMap::Entry* p = names_.Start(); p != NULL; p = names_.Next(p)) { 181 for (HashMap::Entry* p = names_.Start(); p != NULL; p = names_.Next(p)) {
181 size += strlen(reinterpret_cast<const char*>(p->value)) + 1; 182 size += strlen(reinterpret_cast<const char*>(p->value)) + 1;
182 } 183 }
183 return size; 184 return size;
184 } 185 }
185 186
186 const char* const CodeEntry::kEmptyNamePrefix = ""; 187 const char* const CodeEntry::kEmptyNamePrefix = "";
187 188
188 189
190 CodeEntry::~CodeEntry() {
191 delete no_frame_ranges_;
192 }
193
194
189 void CodeEntry::CopyData(const CodeEntry& source) { 195 void CodeEntry::CopyData(const CodeEntry& source) {
190 tag_ = source.tag_; 196 tag_ = source.tag_;
191 name_prefix_ = source.name_prefix_; 197 name_prefix_ = source.name_prefix_;
192 name_ = source.name_; 198 name_ = source.name_;
193 resource_name_ = source.resource_name_; 199 resource_name_ = source.resource_name_;
194 line_number_ = source.line_number_; 200 line_number_ = source.line_number_;
195 } 201 }
196 202
197 203
198 uint32_t CodeEntry::GetCallUid() const { 204 uint32_t CodeEntry::GetCallUid() const {
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 CodeTree::Locator locator; 530 CodeTree::Locator locator;
525 if (!tree_.FindGreatestLessThan(addr, &locator)) break; 531 if (!tree_.FindGreatestLessThan(addr, &locator)) break;
526 Address start2 = locator.key(), end2 = start2 + locator.value().size; 532 Address start2 = locator.key(), end2 = start2 + locator.value().size;
527 if (start2 < end && start < end2) to_delete.Add(start2); 533 if (start2 < end && start < end2) to_delete.Add(start2);
528 addr = start2 - 1; 534 addr = start2 - 1;
529 } 535 }
530 for (int i = 0; i < to_delete.length(); ++i) tree_.Remove(to_delete[i]); 536 for (int i = 0; i < to_delete.length(); ++i) tree_.Remove(to_delete[i]);
531 } 537 }
532 538
533 539
534 CodeEntry* CodeMap::FindEntry(Address addr) { 540 CodeEntry* CodeMap::FindEntry(Address addr, Address* start) {
535 CodeTree::Locator locator; 541 CodeTree::Locator locator;
536 if (tree_.FindGreatestLessThan(addr, &locator)) { 542 if (tree_.FindGreatestLessThan(addr, &locator)) {
537 // locator.key() <= addr. Need to check that addr is within entry. 543 // locator.key() <= addr. Need to check that addr is within entry.
538 const CodeEntryInfo& entry = locator.value(); 544 const CodeEntryInfo& entry = locator.value();
539 if (addr < (locator.key() + entry.size)) 545 if (addr < (locator.key() + entry.size)) {
546 if (start) {
547 *start = locator.key();
548 }
540 return entry.entry; 549 return entry.entry;
550 }
541 } 551 }
542 return NULL; 552 return NULL;
543 } 553 }
544 554
545 555
546 int CodeMap::GetSharedId(Address addr) { 556 int CodeMap::GetSharedId(Address addr) {
547 CodeTree::Locator locator; 557 CodeTree::Locator locator;
548 // For shared function entries, 'size' field is used to store their IDs. 558 // For shared function entries, 'size' field is used to store their IDs.
549 if (tree_.Find(addr, &locator)) { 559 if (tree_.Find(addr, &locator)) {
550 const CodeEntryInfo& entry = locator.value(); 560 const CodeEntryInfo& entry = locator.value();
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 901
892 902
893 void ProfileGenerator::RecordTickSample(const TickSample& sample) { 903 void ProfileGenerator::RecordTickSample(const TickSample& sample) {
894 // Allocate space for stack frames + pc + function + vm-state. 904 // Allocate space for stack frames + pc + function + vm-state.
895 ScopedVector<CodeEntry*> entries(sample.frames_count + 3); 905 ScopedVector<CodeEntry*> entries(sample.frames_count + 3);
896 // As actual number of decoded code entries may vary, initialize 906 // As actual number of decoded code entries may vary, initialize
897 // entries vector with NULL values. 907 // entries vector with NULL values.
898 CodeEntry** entry = entries.start(); 908 CodeEntry** entry = entries.start();
899 memset(entry, 0, entries.length() * sizeof(*entry)); 909 memset(entry, 0, entries.length() * sizeof(*entry));
900 if (sample.pc != NULL) { 910 if (sample.pc != NULL) {
901 *entry++ = code_map_.FindEntry(sample.pc); 911 Address start;
912 CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start);
913 // If pc is in the function code before it set up stack frame or after the
914 // frame was destroyed SafeStackTraceFrameIterator incorrectly thinks that
915 // ebp contains return address of the current function and skips caller's
916 // frame. Check for this case and just skip such samples.
917 if (pc_entry) {
918 List<OffsetRange>* ranges = pc_entry->no_frame_ranges();
919 if (ranges) {
920 Code* code = Code::cast(HeapObject::FromAddress(start));
921 int pc_offset = sample.pc - code->instruction_start();
922 for (int i = 0; i < ranges->length(); i++) {
923 OffsetRange& range = ranges->at(i);
924 if (range.from <= pc_offset && pc_offset < range.to) {
925 return;
926 }
927 }
928 }
929 }
930 *entry++ = pc_entry;
902 931
903 if (sample.has_external_callback) { 932 if (sample.has_external_callback) {
904 // Don't use PC when in external callback code, as it can point 933 // Don't use PC when in external callback code, as it can point
905 // inside callback's code, and we will erroneously report 934 // inside callback's code, and we will erroneously report
906 // that a callback calls itself. 935 // that a callback calls itself.
907 *(entries.start()) = NULL; 936 *(entries.start()) = NULL;
908 *entry++ = code_map_.FindEntry(sample.external_callback); 937 *entry++ = code_map_.FindEntry(sample.external_callback);
909 } 938 }
910 939
911 for (const Address* stack_pos = sample.stack, 940 for (const Address* stack_pos = sample.stack,
(...skipping 16 matching lines...) Expand all
928 if (no_symbolized_entries) { 957 if (no_symbolized_entries) {
929 *entry++ = EntryForVMState(sample.state); 958 *entry++ = EntryForVMState(sample.state);
930 } 959 }
931 } 960 }
932 961
933 profiles_->AddPathToCurrentProfiles(entries); 962 profiles_->AddPathToCurrentProfiles(entries);
934 } 963 }
935 964
936 965
937 } } // namespace v8::internal 966 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698