Index: runtime/vm/profiler.cc |
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc |
index 9398bbba7528c845e6f4ebf5a163c0bf9a54514b..b52c5b4863e612788fad10e65c1fb14866c887e4 100644 |
--- a/runtime/vm/profiler.cc |
+++ b/runtime/vm/profiler.cc |
@@ -566,9 +566,20 @@ class CodeRegion : public ZoneAllocated { |
PrintOverwrittenCode(&obj); |
} else if (kind() == kTagCode) { |
if (name() == NULL) { |
- const char* tag_name = start() == 0 ? "root" : VMTag::TagName(start()); |
- ASSERT(tag_name != NULL); |
- SetName(tag_name); |
+ if (UserTags::IsUserTag(start())) { |
+ const char* tag_name = UserTags::TagName(start()); |
+ ASSERT(tag_name != NULL); |
+ SetName(tag_name); |
+ } else if (VMTag::IsVMTag(start()) || |
+ VMTag::IsRuntimeEntryTag(start()) || |
+ VMTag::IsNativeEntryTag(start())) { |
+ const char* tag_name = VMTag::TagName(start()); |
+ ASSERT(tag_name != NULL); |
+ SetName(tag_name); |
+ } else { |
+ ASSERT(start() == 0); |
+ SetName("root"); |
+ } |
} |
PrintTagCode(&obj); |
} else { |
@@ -934,6 +945,8 @@ class CodeRegionTableBuilder : public SampleVisitor { |
CreateTag(VMTag::kRuntimeTagId); |
} |
CreateTag(sample->vm_tag()); |
+ // Make sure user tag is created. |
+ CreateUserTag(sample->user_tag()); |
// Exclusive tick for bottom frame. |
Tick(sample->At(0), true, timestamp); |
// Inclusive tick for all frames. |
@@ -969,6 +982,25 @@ class CodeRegionTableBuilder : public SampleVisitor { |
region->set_creation_serial(visited()); |
} |
+ void CreateUserTag(uword tag) { |
+ if (tag == 0) { |
+ // None set. |
+ return; |
+ } |
+ intptr_t index = tag_code_table_->FindIndex(tag); |
+ if (index >= 0) { |
+ // Already created. |
+ return; |
+ } |
+ CodeRegion* region = new CodeRegion(CodeRegion::kTagCode, |
+ tag, |
+ tag + 1, |
+ 0); |
+ index = tag_code_table_->InsertCodeRegion(region); |
+ ASSERT(index >= 0); |
+ region->set_creation_serial(visited()); |
+ } |
+ |
void Tick(uword pc, bool exclusive, int64_t timestamp) { |
CodeRegionTable::TickResult r; |
intptr_t serial = exclusive ? -1 : visited(); |
@@ -1108,6 +1140,12 @@ class CodeRegionExclusiveTrieBuilder : public SampleVisitor { |
root_->Tick(); |
CodeRegionTrieNode* current = root_; |
if (use_tags()) { |
+ intptr_t user_tag_index = FindTagIndex(sample->user_tag()); |
+ if (user_tag_index >= 0) { |
+ current = current->GetChild(user_tag_index); |
+ // Give the tag a tick. |
+ current->Tick(); |
+ } |
if (VMTag::IsNativeEntryTag(sample->vm_tag())) { |
// Insert a dummy kNativeTagId node. |
intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId); |
@@ -1151,7 +1189,13 @@ class CodeRegionExclusiveTrieBuilder : public SampleVisitor { |
private: |
intptr_t FindTagIndex(uword tag) const { |
+ if (tag == 0) { |
+ return -1; |
+ } |
intptr_t index = tag_code_table_->FindIndex(tag); |
+ if (index <= 0) { |
+ return -1; |
+ } |
ASSERT(index >= 0); |
ASSERT((tag_code_table_->At(index))->contains(tag)); |
return tag_code_table_offset_ + index; |
@@ -1523,6 +1567,9 @@ class ProfilerNativeStackWalker : public ValueObject { |
VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc)); |
} |
sample_->SetAt(i, reinterpret_cast<uword>(pc)); |
+ if (fp == NULL) { |
+ return i + 1; |
+ } |
if (!ValidFramePointer(fp)) { |
return i + 1; |
} |
@@ -1530,9 +1577,18 @@ class ProfilerNativeStackWalker : public ValueObject { |
previous_fp = fp; |
fp = CallerFP(fp); |
intptr_t step = fp - previous_fp; |
- if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) { |
+ if (fp == NULL) { |
+ return i + 1; |
+ } |
+ if ((step >= kMaxStep)) { |
// Frame pointer step is too large. |
+ return i + 1; |
+ } |
+ if ((fp <= previous_fp)) { |
// Frame pointer did not move to a higher address. |
+ return i + 1; |
+ } |
+ if (!ValidFramePointer(fp)) { |
// Frame pointer is outside of isolate stack bounds. |
return i + 1; |
} |
@@ -1610,6 +1666,7 @@ void Profiler::RecordSampleInterruptCallback( |
Sample* sample = sample_buffer->ReserveSample(); |
sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); |
sample->set_vm_tag(isolate->vm_tag()); |
+ sample->set_user_tag(isolate->user_tag()); |
if (FLAG_profile_native_stack) { |
// Collect native and Dart frames. |
uword stack_lower = 0; |