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

Unified Diff: runtime/vm/profiler_service.cc

Issue 965593002: Improved profiler view and inclusive profile tree (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/profiler.cc ('k') | runtime/vm/scope_timer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/profiler_service.cc
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index bfd4912fccdb83dd1f484bf0f092eef7010bf2aa..af03a3cca55ba0d464a528a7e8c0db842946a1a7 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -196,25 +196,9 @@ class ProfileFunction : public ZoneAllocated {
}
void PrintToJSONObject(JSONObject* func) {
- if (kind() == kNativeFunction) {
- func->AddProperty("type", "@Function");
- func->AddProperty("name", name());
- func->AddProperty("kind", "Native");
- } else if (kind() == kTagFunction) {
- func->AddProperty("type", "@Function");
- func->AddProperty("kind", "Tag");
- func->AddProperty("name", name());
- } else if (kind() == kUnkownFunction) {
- func->AddProperty("type", "@Function");
- func->AddProperty("name", name());
- func->AddProperty("kind", "Collected");
- } else if (kind() == kStubFunction) {
- func->AddProperty("type", "@Function");
- func->AddProperty("name", name());
- func->AddProperty("kind", "Stub");
- } else {
- UNREACHABLE();
- }
+ func->AddProperty("type", "@Function");
+ func->AddProperty("name", name());
+ func->AddProperty("kind", KindToCString(kind()));
}
void PrintToJSONArray(JSONArray* functions) {
@@ -630,7 +614,7 @@ class CodeRegion : public ZoneAllocated {
ASSERT(kind() == kReusedCode);
JSONObject obj(profile_code_obj, "code");
obj.AddProperty("type", "@Code");
- obj.AddProperty("kind", "Reused");
+ obj.AddProperty("kind", "Collected");
obj.AddProperty("name", name());
obj.AddPropertyF("start", "%" Px "", start());
obj.AddPropertyF("end", "%" Px "", end());
@@ -1394,18 +1378,19 @@ class ProfileFunctionTrieNode : public ZoneAllocated {
};
-class ProfileFunctionExclusiveTrieBuilder : public SampleVisitor {
+class ProfileFunctionTrieBuilder : public SampleVisitor {
public:
- ProfileFunctionExclusiveTrieBuilder(Isolate* isolate,
- CodeRegionTable* live_code_table,
- CodeRegionTable* dead_code_table,
- CodeRegionTable* tag_code_table,
- ProfileFunctionTable* function_table)
+ ProfileFunctionTrieBuilder(Isolate* isolate,
+ CodeRegionTable* live_code_table,
+ CodeRegionTable* dead_code_table,
+ CodeRegionTable* tag_code_table,
+ ProfileFunctionTable* function_table)
: SampleVisitor(isolate),
live_code_table_(live_code_table),
dead_code_table_(dead_code_table),
tag_code_table_(tag_code_table),
function_table_(function_table),
+ inclusive_(false),
trace_(false),
trace_code_filter_(NULL) {
ASSERT(live_code_table_ != NULL);
@@ -1419,20 +1404,46 @@ class ProfileFunctionExclusiveTrieBuilder : public SampleVisitor {
ASSERT(root_index >= 0);
CodeRegion* region = tag_code_table_->At(root_index);
ASSERT(region != NULL);
-
ProfileFunction* function = region->function();
- root_ = new ProfileFunctionTrieNode(function->index());
+ ASSERT(function != NULL);
+
+ exclusive_root_ = new ProfileFunctionTrieNode(function->index());
+ inclusive_root_ = new ProfileFunctionTrieNode(function->index());
}
void VisitSample(Sample* sample) {
+ inclusive_ = false;
+ ProcessSampleExclusive(sample);
+ inclusive_ = true;
+ ProcessSampleInclusive(sample);
+ }
+
+ ProfileFunctionTrieNode* exclusive_root() const {
+ return exclusive_root_;
+ }
+
+ ProfileFunctionTrieNode* inclusive_root() const {
+ return inclusive_root_;
+ }
+
+ ProfilerService::TagOrder tag_order() const {
+ return tag_order_;
+ }
+
+ void set_tag_order(ProfilerService::TagOrder tag_order) {
+ tag_order_ = tag_order;
+ }
+
+ private:
+ void ProcessSampleInclusive(Sample* sample) {
// Give the root a tick.
- root_->Tick();
- ProfileFunctionTrieNode* current = root_;
+ inclusive_root_->Tick();
+ ProfileFunctionTrieNode* current = inclusive_root_;
current = ProcessTags(sample, current);
// Walk the sampled PCs.
- for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
+ for (intptr_t i = FLAG_profile_depth - 1; i >= 0; i--) {
if (sample->At(i) == 0) {
- break;
+ continue;
}
// If we aren't sampled out of an exit frame and this is the top
// frame.
@@ -1443,19 +1454,25 @@ class ProfileFunctionExclusiveTrieBuilder : public SampleVisitor {
}
}
- ProfileFunctionTrieNode* root() const {
- return root_;
- }
-
- ProfilerService::TagOrder tag_order() const {
- return tag_order_;
- }
-
- void set_tag_order(ProfilerService::TagOrder tag_order) {
- tag_order_ = tag_order;
+ void ProcessSampleExclusive(Sample* sample) {
+ // Give the root a tick.
+ exclusive_root_->Tick();
+ ProfileFunctionTrieNode* current = exclusive_root_;
+ current = ProcessTags(sample, current);
+ // Walk the sampled PCs.
+ for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
+ if (sample->At(i) == 0) {
+ break;
+ }
+ // If we aren't sampled out of an exit frame and this is the top
+ // frame.
+ bool exclusive_tick = (i == 0) && !sample->exit_frame_sample();
+ current = ProcessPC(sample->At(i), sample->timestamp(), current,
+ visited(), exclusive_tick,
+ sample->missing_frame_inserted());
+ }
}
- private:
ProfileFunctionTrieNode* ProcessUserTags(Sample* sample,
ProfileFunctionTrieNode* current) {
intptr_t user_tag_index = FindTagIndex(sample->user_tag());
@@ -1569,7 +1586,9 @@ class ProfileFunctionExclusiveTrieBuilder : public SampleVisitor {
OS::Print("[%" Px "] X - %s (%s)\n",
pc, function->name(), region_name);
}
- function->Tick(exclusive, exclusive ? -1 : inclusive_serial);
+ if (!inclusive_) {
+ function->Tick(exclusive, exclusive ? -1 : inclusive_serial);
+ }
current = current->GetChild(function->index());
current->AddCodeObjectIndex(code_index);
current->Tick();
@@ -1583,33 +1602,55 @@ class ProfileFunctionExclusiveTrieBuilder : public SampleVisitor {
return current;
}
-
- for (intptr_t i = 0; i < inlined_functions.length(); i++) {
- Function* inlined_function = inlined_functions[i];
- ASSERT(inlined_function != NULL);
- ASSERT(!inlined_function->IsNull());
- const char* inline_name = inlined_function->ToQualifiedCString();
- if (trace_) {
- OS::Print("[%" Px "] %" Pd " - %s (%s)\n",
- pc, i, inline_name, region_name);
+ if (inclusive_) {
+ for (intptr_t i = inlined_functions.length() - 1; i >= 0; i--) {
+ Function* inlined_function = inlined_functions[i];
+ ASSERT(inlined_function != NULL);
+ ASSERT(!inlined_function->IsNull());
+ current = ProcessInlinedFunction(
+ inlined_function, current, inclusive_serial, exclusive, code_index);
+ exclusive = false;
}
- ProfileFunction* function =
- function_table_->LookupOrAdd(*inlined_function);
- ASSERT(function != NULL);
- function->AddCodeObjectIndex(code_index);
- function->Tick(exclusive, exclusive ? -1 : inclusive_serial);
- exclusive = false;
- current = current->GetChild(function->index());
- current->AddCodeObjectIndex(code_index);
- current->Tick();
- if ((trace_code_filter_ != NULL) &&
- (strstr(region_name, trace_code_filter_) != NULL)) {
- trace_ = true;
- OS::Print("Tracing from: %" Px " [%s] ",
- pc, missing_frame_inserted ? "INSERTED" : "");
- Dump(current);
+ } else {
+ for (intptr_t i = 0; i < inlined_functions.length(); i++) {
+ Function* inlined_function = inlined_functions[i];
+ ASSERT(inlined_function != NULL);
+ ASSERT(!inlined_function->IsNull());
+ const char* inline_name = inlined_function->ToQualifiedCString();
+ if (trace_) {
+ OS::Print("[%" Px "] %" Pd " - %s (%s)\n",
+ pc, i, inline_name, region_name);
+ }
+ current = ProcessInlinedFunction(
+ inlined_function, current, inclusive_serial, exclusive, code_index);
+ exclusive = false;
+ if ((trace_code_filter_ != NULL) &&
+ (strstr(region_name, trace_code_filter_) != NULL)) {
+ trace_ = true;
+ OS::Print("Tracing from: %" Px " [%s] ",
+ pc, missing_frame_inserted ? "INSERTED" : "");
+ Dump(current);
+ }
}
}
+
+ return current;
+ }
+
+ ProfileFunctionTrieNode* ProcessInlinedFunction(
+ Function* inlined_function,
+ ProfileFunctionTrieNode* current,
+ intptr_t inclusive_serial,
+ bool exclusive,
+ intptr_t code_index) {
+ ProfileFunction* function =
+ function_table_->LookupOrAdd(*inlined_function);
+ ASSERT(function != NULL);
+ function->AddCodeObjectIndex(code_index);
+ function->Tick(exclusive, exclusive ? -1 : inclusive_serial);
+ current = current->GetChild(function->index());
+ current->AddCodeObjectIndex(code_index);
+ current->Tick();
return current;
}
@@ -1636,11 +1677,13 @@ class ProfileFunctionExclusiveTrieBuilder : public SampleVisitor {
}
ProfilerService::TagOrder tag_order_;
- ProfileFunctionTrieNode* root_;
+ ProfileFunctionTrieNode* exclusive_root_;
+ ProfileFunctionTrieNode* inclusive_root_;
CodeRegionTable* live_code_table_;
CodeRegionTable* dead_code_table_;
CodeRegionTable* tag_code_table_;
ProfileFunctionTable* function_table_;
+ bool inclusive_;
bool trace_;
const char* trace_code_filter_;
};
@@ -1738,12 +1781,12 @@ class CodeRegionTrieNode : public ZoneAllocated {
};
-class CodeRegionExclusiveTrieBuilder : public SampleVisitor {
+class CodeRegionTrieBuilder : public SampleVisitor {
public:
- CodeRegionExclusiveTrieBuilder(Isolate* isolate,
- CodeRegionTable* live_code_table,
- CodeRegionTable* dead_code_table,
- CodeRegionTable* tag_code_table)
+ CodeRegionTrieBuilder(Isolate* isolate,
+ CodeRegionTable* live_code_table,
+ CodeRegionTable* dead_code_table,
+ CodeRegionTable* tag_code_table)
: SampleVisitor(isolate),
live_code_table_(live_code_table),
dead_code_table_(dead_code_table),
@@ -1758,18 +1801,42 @@ class CodeRegionExclusiveTrieBuilder : public SampleVisitor {
ASSERT(root_index >= 0);
CodeRegion* region = tag_code_table_->At(root_index);
ASSERT(region != NULL);
- root_ = new CodeRegionTrieNode(region->code_table_index());
+
+ exclusive_root_ = new CodeRegionTrieNode(region->code_table_index());
+ inclusive_root_ = new CodeRegionTrieNode(region->code_table_index());
}
void VisitSample(Sample* sample) {
+ ProcessSampleExclusive(sample);
+ ProcessSampleInclusive(sample);
+ }
+
+ CodeRegionTrieNode* inclusive_root() const {
+ return inclusive_root_;
+ }
+
+ CodeRegionTrieNode* exclusive_root() const {
+ return exclusive_root_;
+ }
+
+ ProfilerService::TagOrder tag_order() const {
+ return tag_order_;
+ }
+
+ void set_tag_order(ProfilerService::TagOrder tag_order) {
+ tag_order_ = tag_order;
+ }
+
+ private:
+ void ProcessSampleInclusive(Sample* sample) {
// Give the root a tick.
- root_->Tick();
- CodeRegionTrieNode* current = root_;
+ inclusive_root_->Tick();
+ CodeRegionTrieNode* current = inclusive_root_;
current = ProcessTags(sample, current);
// Walk the sampled PCs.
- for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
+ for (intptr_t i = FLAG_profile_depth - 1; i >= 0; i--) {
if (sample->At(i) == 0) {
- break;
+ continue;
}
intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp());
if (index < 0) {
@@ -1780,19 +1847,25 @@ class CodeRegionExclusiveTrieBuilder : public SampleVisitor {
}
}
- CodeRegionTrieNode* root() const {
- return root_;
- }
-
- ProfilerService::TagOrder tag_order() const {
- return tag_order_;
- }
-
- void set_tag_order(ProfilerService::TagOrder tag_order) {
- tag_order_ = tag_order;
+ void ProcessSampleExclusive(Sample* sample) {
+ // Give the root a tick.
+ exclusive_root_->Tick();
+ CodeRegionTrieNode* current = exclusive_root_;
+ current = ProcessTags(sample, current);
+ // Walk the sampled PCs.
+ for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
+ if (sample->At(i) == 0) {
+ break;
+ }
+ intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp());
+ if (index < 0) {
+ continue;
+ }
+ current = current->GetChild(index);
+ current->Tick();
+ }
}
- private:
CodeRegionTrieNode* ProcessUserTags(Sample* sample,
CodeRegionTrieNode* current) {
intptr_t user_tag_index = FindTagIndex(sample->user_tag());
@@ -1897,7 +1970,8 @@ class CodeRegionExclusiveTrieBuilder : public SampleVisitor {
}
ProfilerService::TagOrder tag_order_;
- CodeRegionTrieNode* root_;
+ CodeRegionTrieNode* exclusive_root_;
+ CodeRegionTrieNode* inclusive_root_;
CodeRegionTable* live_code_table_;
CodeRegionTable* dead_code_table_;
CodeRegionTable* tag_code_table_;
@@ -1983,33 +2057,34 @@ void ProfilerService::PrintJSON(JSONStream* stream, TagOrder tag_order) {
intptr_t total_functions = function_table.Length();
OS::Print("FunctionTable: size=%" Pd "\n", total_functions);
}
- CodeRegionExclusiveTrieBuilder code_trie_builder(isolate,
- &live_code_table,
- &dead_code_table,
- &tag_code_table);
+ CodeRegionTrieBuilder code_trie_builder(isolate,
+ &live_code_table,
+ &dead_code_table,
+ &tag_code_table);
code_trie_builder.set_tag_order(tag_order);
{
// Build CodeRegion trie.
- ScopeTimer sw("CodeRegionExclusiveTrieBuilder", FLAG_trace_profiler);
+ ScopeTimer sw("CodeRegionTrieBuilder", FLAG_trace_profiler);
sample_buffer->VisitSamples(&code_trie_builder);
- code_trie_builder.root()->SortByCount();
+ code_trie_builder.exclusive_root()->SortByCount();
+ code_trie_builder.inclusive_root()->SortByCount();
}
- ProfileFunctionExclusiveTrieBuilder
- function_trie_builder(isolate,
- &live_code_table,
- &dead_code_table,
- &tag_code_table,
- &function_table);
+ ProfileFunctionTrieBuilder function_trie_builder(isolate,
+ &live_code_table,
+ &dead_code_table,
+ &tag_code_table,
+ &function_table);
function_trie_builder.set_tag_order(tag_order);
{
// Build ProfileFunction trie.
- ScopeTimer sw("ProfileFunctionExclusiveTrieBuilder",
+ ScopeTimer sw("ProfileFunctionTrieBuilder",
FLAG_trace_profiler);
sample_buffer->VisitSamples(&function_trie_builder);
- function_trie_builder.root()->SortByCount();
+ function_trie_builder.exclusive_root()->SortByCount();
+ function_trie_builder.inclusive_root()->SortByCount();
}
{
- ScopeTimer sw("CodeTableStream", FLAG_trace_profiler);
+ ScopeTimer sw("CpuProfileJSONStream", FLAG_trace_profiler);
// Serialize to JSON.
JSONObject obj(stream);
obj.AddProperty("type", "_CpuProfile");
@@ -2021,14 +2096,28 @@ void ProfilerService::PrintJSON(JSONStream* stream, TagOrder tag_order) {
obj.AddProperty("timeSpan",
MicrosecondsToSeconds(builder.TimeDeltaMicros()));
{
- JSONArray exclusive_trie(&obj, "exclusiveCodeTrie");
- CodeRegionTrieNode* root = code_trie_builder.root();
+ JSONArray code_trie(&obj, "exclusiveCodeTrie");
+ CodeRegionTrieNode* root = code_trie_builder.exclusive_root();
ASSERT(root != NULL);
- root->PrintToJSONArray(&exclusive_trie);
+ root->PrintToJSONArray(&code_trie);
+ }
+ {
+ JSONArray code_trie(&obj, "inclusiveCodeTrie");
+ CodeRegionTrieNode* root = code_trie_builder.inclusive_root();
+ ASSERT(root != NULL);
+ root->PrintToJSONArray(&code_trie);
}
{
JSONArray function_trie(&obj, "exclusiveFunctionTrie");
- ProfileFunctionTrieNode* root = function_trie_builder.root();
+ ProfileFunctionTrieNode* root =
+ function_trie_builder.exclusive_root();
+ ASSERT(root != NULL);
+ root->PrintToJSONArray(&function_trie);
+ }
+ {
+ JSONArray function_trie(&obj, "inclusiveFunctionTrie");
+ ProfileFunctionTrieNode* root =
+ function_trie_builder.inclusive_root();
ASSERT(root != NULL);
root->PrintToJSONArray(&function_trie);
}
« no previous file with comments | « runtime/vm/profiler.cc ('k') | runtime/vm/scope_timer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698