OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |