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

Unified Diff: runtime/vm/profiler_service.cc

Issue 1268803006: Support profiler code transition tags (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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_service.h ('k') | runtime/vm/profiler_test.cc » ('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 997aab191597c6a6c17eed9a57fc02144318031b..872b6009c3329b0e13850929b30e17ba679c5159 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -581,11 +581,34 @@ ProfileFunction* ProfileCode::SetFunctionAndName(ProfileFunctionTable* table) {
ASSERT(tag_name != NULL);
SetName(tag_name);
} else {
- if (start() == VMTag::kRootTagId) {
- SetName("Root");
- } else {
- ASSERT(start() == VMTag::kTruncatedTagId);
- SetName("[Truncated]");
+ switch (start()) {
+ case VMTag::kRootTagId:
+ SetName("Root");
+ break;
+ case VMTag::kTruncatedTagId:
+ SetName("[Truncated]");
+ break;
+ case VMTag::kNoneCodeTagId:
+ SetName("[No Code]");
+ break;
+ case VMTag::kOptimizedCodeTagId:
+ SetName("[Optimized Code]");
+ break;
+ case VMTag::kUnoptimizedCodeTagId:
+ SetName("[Unoptimized Code]");
+ break;
+ case VMTag::kNativeCodeTagId:
+ SetName("[Native Code]");
+ break;
+ case VMTag::kInlineStartCodeTagId:
+ SetName("[Inline Start]");
+ break;
+ case VMTag::kInlineEndCodeTagId:
+ SetName("[Inline End]");
+ break;
+ default:
+ UNIMPLEMENTED();
+ break;
}
}
}
@@ -951,21 +974,34 @@ class ProfileFunctionTrieNode : public ProfileTrieNode {
class ProfileBuilder : public ValueObject {
public:
+ enum ProfileInfoKind {
+ kNone,
+ kOptimized,
+ kUnoptimized,
+ kNative,
+ kInlineStart,
+ kInlineFinish,
+ kNumProfileInfoKind,
+ };
+
ProfileBuilder(Isolate* isolate,
SampleFilter* filter,
Profile::TagOrder tag_order,
+ intptr_t extra_tags,
Profile* profile)
: isolate_(isolate),
vm_isolate_(Dart::vm_isolate()),
filter_(filter),
tag_order_(tag_order),
+ extra_tags_(extra_tags),
profile_(profile),
deoptimized_code_(new DeoptimizedCodeSet(isolate)),
null_code_(Code::ZoneHandle()),
null_function_(Function::ZoneHandle()),
tick_functions_(false),
inclusive_tree_(false),
- samples_(NULL) {
+ samples_(NULL),
+ info_kind_(kNone) {
ASSERT(profile_ != NULL);
}
@@ -1005,6 +1041,12 @@ class ProfileBuilder : public ValueObject {
// Register some synthetic tags.
RegisterProfileCodeTag(VMTag::kRootTagId);
RegisterProfileCodeTag(VMTag::kTruncatedTagId);
+ RegisterProfileCodeTag(VMTag::kNoneCodeTagId);
+ RegisterProfileCodeTag(VMTag::kOptimizedCodeTagId);
+ RegisterProfileCodeTag(VMTag::kUnoptimizedCodeTagId);
+ RegisterProfileCodeTag(VMTag::kNativeCodeTagId);
+ RegisterProfileCodeTag(VMTag::kInlineStartCodeTagId);
+ RegisterProfileCodeTag(VMTag::kInlineEndCodeTagId);
}
void FilterSamples() {
@@ -1152,12 +1194,15 @@ class ProfileBuilder : public ValueObject {
// VM & User tags.
current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+ ResetKind();
+
// Truncated tag.
if (sample->truncated()) {
current = AppendTruncatedTag(current);
}
// Walk the sampled PCs.
+ Code& code = Code::Handle();
for (intptr_t frame_index = sample->length() - 1;
frame_index >= 0;
frame_index--) {
@@ -1165,6 +1210,11 @@ class ProfileBuilder : public ValueObject {
intptr_t index =
GetProfileCodeIndex(sample->At(frame_index), sample->timestamp());
ASSERT(index >= 0);
+ ProfileCode* profile_code =
+ GetProfileCode(sample->At(frame_index), sample->timestamp());
+ ASSERT(profile_code->code_table_index() == index);
+ code ^= profile_code->code();
+ current = AppendKind(code, current);
current = current->GetChild(index);
current->Tick();
}
@@ -1186,7 +1236,10 @@ class ProfileBuilder : public ValueObject {
// VM & User tags.
current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+ ResetKind();
+
// Walk the sampled PCs.
+ Code& code = Code::Handle();
for (intptr_t frame_index = 0;
frame_index < sample->length();
frame_index++) {
@@ -1194,10 +1247,15 @@ class ProfileBuilder : public ValueObject {
intptr_t index =
GetProfileCodeIndex(sample->At(frame_index), sample->timestamp());
ASSERT(index >= 0);
+ ProfileCode* profile_code =
+ GetProfileCode(sample->At(frame_index), sample->timestamp());
+ ASSERT(profile_code->code_table_index() == index);
+ code ^= profile_code->code();
current = current->GetChild(index);
if (ShouldTickNode(sample, frame_index)) {
current->Tick();
}
+ current = AppendKind(code, current);
}
// Truncated tag.
if (sample->truncated()) {
@@ -1270,6 +1328,8 @@ class ProfileBuilder : public ValueObject {
// VM & User tags.
current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+ ResetKind();
+
// Walk the sampled PCs.
for (intptr_t frame_index = 0;
frame_index < sample->length();
@@ -1306,40 +1366,63 @@ class ProfileBuilder : public ValueObject {
}
if (code.IsNull() || (inlined_functions.length() == 0)) {
// No inlined functions.
+ if (inclusive_tree_) {
+ current = AppendKind(code, current);
+ }
current = ProcessFunction(current,
sample_index,
sample,
frame_index,
function,
code_index);
+ if (!inclusive_tree_) {
+ current = AppendKind(code, current);
+ }
return current;
}
+ ASSERT(code.is_optimized());
+
if (inclusive_tree_) {
- // Append the inlined children.
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());
+ const bool inliner = i == (inlined_functions.length() - 1);
+ if (inliner) {
+ current = AppendKind(code, current);
+ }
current = ProcessInlinedFunction(current,
sample_index,
sample,
frame_index,
inlined_function,
code_index);
+ if (inliner) {
+ current = AppendKind(kInlineStart, current);
+ }
}
+ current = AppendKind(kInlineFinish, current);
} else {
// Append the inlined children.
+ current = AppendKind(kInlineFinish, 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 bool inliner = i == (inlined_functions.length() - 1);
+ if (inliner) {
+ current = AppendKind(kInlineStart, current);
+ }
current = ProcessInlinedFunction(current,
sample_index,
sample,
frame_index + i,
inlined_function,
code_index);
+ if (inliner) {
+ current = AppendKind(code, current);
+ }
}
}
@@ -1464,6 +1547,53 @@ class ProfileBuilder : public ValueObject {
return current;
}
+ uword ProfileInfoKindToVMTag(ProfileInfoKind kind) {
+ switch (kind) {
+ case kNone:
+ return VMTag::kNoneCodeTagId;
+ case kOptimized:
+ return VMTag::kOptimizedCodeTagId;
+ case kUnoptimized:
+ return VMTag::kUnoptimizedCodeTagId;
+ case kNative:
+ return VMTag::kNativeCodeTagId;
+ case kInlineStart:
+ return VMTag::kInlineStartCodeTagId;
+ case kInlineFinish:
+ return VMTag::kInlineEndCodeTagId;
+ default:
+ UNIMPLEMENTED();
+ return VMTag::kInvalidTagId;
+ }
+ }
+
+ ProfileCodeTrieNode* AppendKind(ProfileInfoKind kind,
+ ProfileCodeTrieNode* current) {
+ if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) {
+ // Only emit if debug tags are requested.
+ return current;
+ }
+ if (kind != info_kind_) {
+ info_kind_ = kind;
+ intptr_t tag_index = GetProfileCodeTagIndex(ProfileInfoKindToVMTag(kind));
+ ASSERT(tag_index >= 0);
+ current = current->GetChild(tag_index);
+ current->Tick();
+ }
+ return current;
+ }
+
+ ProfileCodeTrieNode* AppendKind(const Code& code,
+ ProfileCodeTrieNode* current) {
+ if (code.IsNull()) {
+ return AppendKind(kNone, current);
+ } else if (code.is_optimized()) {
+ return AppendKind(kOptimized, current);
+ } else {
+ return AppendKind(kUnoptimized, current);
+ }
+ }
+
ProfileCodeTrieNode* AppendVMTags(uword vm_tag,
ProfileCodeTrieNode* current) {
current = AppendVMTag(vm_tag, current);
@@ -1500,6 +1630,38 @@ class ProfileBuilder : public ValueObject {
}
// ProfileFunctionTrieNode
+ void ResetKind() {
+ info_kind_ = kNone;
+ }
+
+ ProfileFunctionTrieNode* AppendKind(ProfileInfoKind kind,
+ ProfileFunctionTrieNode* current) {
+ if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) {
+ // Only emit if debug tags are requested.
+ return current;
+ }
+ if (kind != info_kind_) {
+ info_kind_ = kind;
+ intptr_t tag_index =
+ GetProfileFunctionTagIndex(ProfileInfoKindToVMTag(kind));
+ ASSERT(tag_index >= 0);
+ current = current->GetChild(tag_index);
+ current->Tick();
+ }
+ return current;
+ }
+
+ ProfileFunctionTrieNode* AppendKind(const Code& code,
+ ProfileFunctionTrieNode* current) {
+ if (code.IsNull()) {
+ return AppendKind(kNone, current);
+ } else if (code.is_optimized()) {
+ return AppendKind(kOptimized, current);
+ } else {
+ return AppendKind(kUnoptimized, current);
+ }
+ }
+
ProfileFunctionTrieNode* AppendUserTag(uword user_tag,
ProfileFunctionTrieNode* current) {
intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag);
@@ -1783,10 +1945,15 @@ class ProfileBuilder : public ValueObject {
(tag_order_ == Profile::kVM);
}
+ bool TagsEnabled(intptr_t extra_tags_bits) const {
+ return (extra_tags_ & extra_tags_bits) != 0;
+ }
+
Isolate* isolate_;
Isolate* vm_isolate_;
SampleFilter* filter_;
Profile::TagOrder tag_order_;
+ intptr_t extra_tags_;
Profile* profile_;
DeoptimizedCodeSet* deoptimized_code_;
const Code& null_code_;
@@ -1795,6 +1962,7 @@ class ProfileBuilder : public ValueObject {
bool inclusive_tree_;
ProcessedSampleBuffer* samples_;
+ ProfileInfoKind info_kind_;
};
@@ -1815,8 +1983,10 @@ Profile::Profile(Isolate* isolate)
}
-void Profile::Build(SampleFilter* filter, TagOrder tag_order) {
- ProfileBuilder builder(isolate_, filter, tag_order, this);
+void Profile::Build(SampleFilter* filter,
+ TagOrder tag_order,
+ intptr_t extra_tags) {
+ ProfileBuilder builder(isolate_, filter, tag_order, extra_tags, this);
builder.Build();
}
@@ -2019,6 +2189,7 @@ intptr_t ProfileTrieWalker::SiblingCount() {
void ProfilerService::PrintJSONImpl(Isolate* isolate,
JSONStream* stream,
Profile::TagOrder tag_order,
+ intptr_t extra_tags,
SampleFilter* filter) {
// Disable profile interrupts while processing the buffer.
Profiler::EndExecution(isolate);
@@ -2036,7 +2207,7 @@ void ProfilerService::PrintJSONImpl(Isolate* isolate,
StackZone zone(isolate);
HANDLESCOPE(isolate);
Profile profile(isolate);
- profile.Build(filter, tag_order);
+ profile.Build(filter, tag_order, extra_tags);
profile.PrintJSON(stream);
}
@@ -2058,10 +2229,11 @@ class NoAllocationSampleFilter : public SampleFilter {
void ProfilerService::PrintJSON(JSONStream* stream,
- Profile::TagOrder tag_order) {
+ Profile::TagOrder tag_order,
+ intptr_t extra_tags) {
Isolate* isolate = Isolate::Current();
NoAllocationSampleFilter filter(isolate);
- PrintJSONImpl(isolate, stream, tag_order, &filter);
+ PrintJSONImpl(isolate, stream, tag_order, extra_tags, &filter);
}
@@ -2088,7 +2260,7 @@ void ProfilerService::PrintAllocationJSON(JSONStream* stream,
const Class& cls) {
Isolate* isolate = Isolate::Current();
ClassAllocationSampleFilter filter(isolate, cls);
- PrintJSONImpl(isolate, stream, tag_order, &filter);
+ PrintJSONImpl(isolate, stream, tag_order, kNoExtraTags, &filter);
}
« no previous file with comments | « runtime/vm/profiler_service.h ('k') | runtime/vm/profiler_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698