Index: src/profile-generator.cc |
diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
index a7f7a440b4b9313e67fce8aa608273c10bd422e5..858b40b81456b9fd8a523235061b9d265df2c39e 100644 |
--- a/src/profile-generator.cc |
+++ b/src/profile-generator.cc |
@@ -235,6 +235,12 @@ bool CodeEntry::IsSameAs(CodeEntry* entry) const { |
} |
+void CodeEntry::SetBuiltinId(Builtins::Name id) { |
+ tag_ = Logger::BUILTIN_TAG; |
+ builtin_id_ = id; |
+} |
+ |
+ |
ProfileNode* ProfileNode::FindChild(CodeEntry* entry) { |
HashMap::Entry* map_entry = |
children_.Lookup(entry, CodeEntryHash(entry), false); |
@@ -867,33 +873,39 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { |
CodeEntry** entry = entries.start(); |
memset(entry, 0, entries.length() * sizeof(*entry)); |
if (sample.pc != NULL) { |
- Address start; |
- CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start); |
- // If pc is in the function code before it set up stack frame or after the |
- // frame was destroyed SafeStackFrameIterator incorrectly thinks that |
- // ebp contains return address of the current function and skips caller's |
- // frame. Check for this case and just skip such samples. |
- if (pc_entry) { |
- List<OffsetRange>* ranges = pc_entry->no_frame_ranges(); |
- if (ranges) { |
- Code* code = Code::cast(HeapObject::FromAddress(start)); |
- int pc_offset = static_cast<int>(sample.pc - code->instruction_start()); |
- for (int i = 0; i < ranges->length(); i++) { |
- OffsetRange& range = ranges->at(i); |
- if (range.from <= pc_offset && pc_offset < range.to) { |
- return; |
- } |
- } |
- } |
- } |
- *entry++ = pc_entry; |
- |
if (sample.has_external_callback) { |
// Don't use PC when in external callback code, as it can point |
// inside callback's code, and we will erroneously report |
// that a callback calls itself. |
- *(entries.start()) = NULL; |
*entry++ = code_map_.FindEntry(sample.external_callback); |
+ } else { |
+ Address start; |
+ CodeEntry* pc_entry = code_map_.FindEntry(sample.pc, &start); |
+ // If pc is in the function code before it set up stack frame or after the |
+ // frame was destroyed SafeStackFrameIterator incorrectly thinks that |
+ // ebp contains return address of the current function and skips caller's |
+ // frame. Check for this case and just skip such samples. |
+ if (pc_entry) { |
+ List<OffsetRange>* ranges = pc_entry->no_frame_ranges(); |
+ if (ranges) { |
+ Code* code = Code::cast(HeapObject::FromAddress(start)); |
+ int pc_offset = static_cast<int>( |
+ sample.pc - code->instruction_start()); |
+ for (int i = 0; i < ranges->length(); i++) { |
+ OffsetRange& range = ranges->at(i); |
+ if (range.from <= pc_offset && pc_offset < range.to) { |
+ return; |
+ } |
+ } |
+ } |
+ *entry++ = pc_entry; |
+ |
+ if (pc_entry->builtin_id() == Builtins::kFunctionCall) { |
+ // When current function is FunctionCall builtin tos is alway |
loislo
2013/07/01 12:00:20
tipo: alway
|
+ // address of the function that invoked it. |
+ *entry++ = code_map_.FindEntry(sample.tos); |
+ } |
+ } |
} |
for (const Address* stack_pos = sample.stack, |