Chromium Code Reviews| Index: src/profile-generator.cc |
| diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
| index b1b163b50ecdf2d59173eef568c84878fb50becf..5a645435a5355c001fac9c469f93a8ad47a83cf3 100644 |
| --- a/src/profile-generator.cc |
| +++ b/src/profile-generator.cc |
| @@ -531,13 +531,16 @@ void CodeMap::DeleteAllCoveredCode(Address start, Address end) { |
| } |
| -CodeEntry* CodeMap::FindEntry(Address addr) { |
| +CodeEntry* CodeMap::FindEntry(Address addr, Address* start) { |
| CodeTree::Locator locator; |
| if (tree_.FindGreatestLessThan(addr, &locator)) { |
| // locator.key() <= addr. Need to check that addr is within entry. |
| const CodeEntryInfo& entry = locator.value(); |
| - if (addr < (locator.key() + entry.size)) |
| + if (addr < (locator.key() + entry.size)) { |
| + if (start) |
| + *start = locator.key(); |
| return entry.entry; |
| + } |
| } |
| return NULL; |
| } |
| @@ -898,7 +901,24 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { |
| CodeEntry** entry = entries.start(); |
| memset(entry, 0, entries.length() * sizeof(*entry)); |
| if (sample.pc != NULL) { |
| - *entry++ = code_map_.FindEntry(sample.pc); |
| + Address start; |
| + CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start); |
| + // If pc is in the function code before it setup stack frame or after the |
| + // frame was destroyed SafeStackTraceFrameIterator incorrectly thinks that |
| + // ebp cotains return address of the current function and skips caller's |
| + // frame. Check for this case and just skip such samples. |
| + if (pc_entry && pc_entry->frame_setup_offset() != -1) { |
| + Code* code = Code::cast(HeapObject::FromAddress(start)); |
| + Address instruction_start = code->instruction_start(); |
| + // Frame setup code is at least 4 bytes. |
| + if (sample.pc < instruction_start + pc_entry->frame_setup_offset() + 4) |
| + return; |
|
loislo
2013/04/26 13:36:56
looks like you are skipping the other stack traces
yurys
2013/04/26 13:43:51
Yes, this is intentional, the comment above descri
|
| + Address frame_destroy = instruction_start + |
| + pc_entry->frame_destroy_offset(); |
| + if (frame_destroy < sample.pc && sample.pc < frame_destroy + 4) |
| + return; |
|
loislo
2013/04/26 13:36:56
ditto
yurys
2013/04/26 13:43:51
See above.
|
| + } |
| + *entry++ = pc_entry; |
|
loislo
2013/04/26 13:36:56
sounds like you are adding zero entry if the mappi
yurys
2013/04/26 13:43:51
This part didn't change, it is normal case - pc co
|
| if (sample.has_external_callback) { |
| // Don't use PC when in external callback code, as it can point |