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

Unified Diff: runtime/vm/profiler_service.cc

Issue 1525913002: Observatory: Include profiler samples in the timeline view. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years 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/service.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 a4e6b835ce7a6fdda2704a892a7588a8ff677145..9a0d5fc07a19f6d501db1a3d3a9008c122bfcccf 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -797,7 +797,8 @@ class ProfileCodeTable : public ZoneAllocated {
ProfileTrieNode::ProfileTrieNode(intptr_t table_index)
: table_index_(table_index),
count_(0),
- children_(0) {
+ children_(0),
+ frame_id_(-1) {
ASSERT(table_index_ >= 0);
}
@@ -1056,6 +1057,7 @@ class ProfileBuilder : public ValueObject {
return;
}
samples_ = sample_buffer->BuildProcessedSampleBuffer(filter_);
+ profile_->samples_ = samples_;
profile_->sample_count_ = samples_->length();
}
@@ -1333,6 +1335,8 @@ class ProfileBuilder : public ValueObject {
ASSERT(sample->At(frame_index) != 0);
current = ProcessFrame(current, sample_index, sample, frame_index);
}
+
+ sample->set_timeline_trie(current);
}
}
@@ -1973,6 +1977,8 @@ class ProfileBuilder : public ValueObject {
Profile::Profile(Isolate* isolate)
: isolate_(isolate),
+ zone_(Thread::Current()->zone()),
+ samples_(NULL),
live_code_(NULL),
dead_code_(NULL),
tag_code_(NULL),
@@ -2034,16 +2040,90 @@ ProfileTrieNode* Profile::GetTrieRoot(TrieKind trie_kind) {
}
-void Profile::PrintJSON(JSONStream* stream) {
- ScopeTimer sw("Profile::PrintJSON", FLAG_trace_profiler);
+void Profile::PrintHeaderJSON(JSONObject* obj) {
+ obj->AddProperty("samplePeriod",
+ static_cast<intptr_t>(FLAG_profile_period));
+ obj->AddProperty("stackDepth",
+ static_cast<intptr_t>(FLAG_max_profile_depth));
+ obj->AddProperty("sampleCount", sample_count());
+ obj->AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
+}
+
+
+void Profile::PrintTimelineFrameJSON(JSONObject* frames,
+ ProfileTrieNode* current,
+ ProfileTrieNode* parent,
+ intptr_t* next_id) {
+ ASSERT(current->frame_id() == -1);
+ const intptr_t id = *next_id;
+ *next_id = id + 1;
+ current->set_frame_id(id);
+ ASSERT(current->frame_id() != -1);
+
+ {
+ // The samples from many isolates may be merged into a single timeline,
+ // so prefix frames id with the isolate.
+ intptr_t isolate_id = reinterpret_cast<intptr_t>(isolate_);
+ const char* key = zone_->PrintToString("%" Pd "-%" Pd,
+ isolate_id, current->frame_id());
+ JSONObject frame(frames, key);
+ frame.AddProperty("category", "Dart");
+ ProfileFunction* func = GetFunction(current->table_index());
+ frame.AddProperty("name", func->Name());
+ if (parent != NULL) {
+ ASSERT(parent->frame_id() != -1);
+ frame.AddPropertyF("parent", "%" Pd "-%" Pd,
+ isolate_id, parent->frame_id());
+ }
+ }
+
+ for (intptr_t i = 0; i < current->NumChildren(); i++) {
+ ProfileTrieNode* child = current->At(i);
+ PrintTimelineFrameJSON(frames, child, current, next_id);
+ }
+}
+
+
+void Profile::PrintTimelineJSON(JSONStream* stream) {
+ ScopeTimer sw("Profile::PrintTimelineJSON", FLAG_trace_profiler);
+ JSONObject obj(stream);
+ obj.AddProperty("type", "_CpuProfileTimeline");
+ PrintHeaderJSON(&obj);
+ {
+ JSONObject frames(&obj, "stackFrames");
+ ProfileTrieNode* root = GetTrieRoot(kInclusiveFunction);
+ intptr_t next_id = 0;
+ PrintTimelineFrameJSON(&frames, root, NULL, &next_id);
+ }
+ {
+ JSONArray events(&obj, "traceEvents");
+ intptr_t pid = OS::ProcessId();
+ intptr_t isolate_id = reinterpret_cast<intptr_t>(isolate_);
+ for (intptr_t sample_index = 0;
+ sample_index < samples_->length();
+ sample_index++) {
+ ProcessedSample* sample = samples_->At(sample_index);
+ JSONObject event(&events);
+ event.AddProperty("ph", "P"); // kind = sample event
+ event.AddProperty64("pid", pid);
+ event.AddProperty64("tid", OSThread::ThreadIdToIntPtr(sample->tid()));
+ event.AddPropertyTimeMicros("ts", sample->timestamp());
+ event.AddProperty("cat", "Dart");
+
+ ProfileTrieNode* trie = sample->timeline_trie();
+ ASSERT(trie->frame_id() != -1);
+ event.AddPropertyF("sf", "%" Pd "-%" Pd,
+ isolate_id, trie->frame_id());
+ }
+ }
+}
+
+
+void Profile::PrintProfileJSON(JSONStream* stream) {
+ ScopeTimer sw("Profile::PrintProfileJSON", FLAG_trace_profiler);
JSONObject obj(stream);
obj.AddProperty("type", "_CpuProfile");
- obj.AddProperty("samplePeriod",
- static_cast<intptr_t>(FLAG_profile_period));
- obj.AddProperty("stackDepth",
- static_cast<intptr_t>(FLAG_max_profile_depth));
- obj.AddProperty("sampleCount", sample_count());
- obj.AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
+ PrintHeaderJSON(&obj);
{
JSONArray codes(&obj, "codes");
for (intptr_t i = 0; i < live_code_->length(); i++) {
@@ -2196,7 +2276,8 @@ void ProfilerService::PrintJSONImpl(Thread* thread,
JSONStream* stream,
Profile::TagOrder tag_order,
intptr_t extra_tags,
- SampleFilter* filter) {
+ SampleFilter* filter,
+ bool as_timeline) {
Isolate* isolate = thread->isolate();
// Disable thread interrupts while processing the buffer.
DisableThreadInterruptsScope dtis(thread);
@@ -2212,7 +2293,11 @@ void ProfilerService::PrintJSONImpl(Thread* thread,
HANDLESCOPE(thread);
Profile profile(isolate);
profile.Build(thread, filter, tag_order, extra_tags);
- profile.PrintJSON(stream);
+ if (as_timeline) {
+ profile.PrintTimelineJSON(stream);
+ } else {
+ profile.PrintProfileJSON(stream);
+ }
}
}
@@ -2235,7 +2320,8 @@ void ProfilerService::PrintJSON(JSONStream* stream,
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
NoAllocationSampleFilter filter(isolate);
- PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter);
+ const bool as_timeline = false;
+ PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter, as_timeline);
}
@@ -2263,7 +2349,18 @@ void ProfilerService::PrintAllocationJSON(JSONStream* stream,
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
ClassAllocationSampleFilter filter(isolate, cls);
- PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter);
+ const bool as_timeline = false;
+ PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
+}
+
+
+void ProfilerService::PrintTimelineJSON(JSONStream* stream,
+ Profile::TagOrder tag_order) {
+ Thread* thread = Thread::Current();
+ Isolate* isolate = thread->isolate();
+ NoAllocationSampleFilter filter(isolate);
+ const bool as_timeline = true;
+ PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
}
« no previous file with comments | « runtime/vm/profiler_service.h ('k') | runtime/vm/service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698