Skip to content

Commit

Permalink
[vm, service] Allow choice of tags and code-verus-function when getti…
Browse files Browse the repository at this point in the history
…ng profile samples as timeline events.

Change-Id: Ie0cf3d43d5ccc748216ba2b45a9466ce60dcf239
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97176
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
  • Loading branch information
rmacnak-google authored and commit-bot@chromium.org committed Mar 26, 2019
1 parent 0e48504 commit b7a5e47
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 47 deletions.
3 changes: 2 additions & 1 deletion runtime/vm/profiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1635,7 +1635,8 @@ ProcessedSample::ProcessedSample()
user_tag_(0),
allocation_cid_(-1),
truncated_(false),
timeline_trie_(NULL) {}
timeline_code_trie_(nullptr),
timeline_function_trie_(nullptr) {}

void ProcessedSample::FixupCaller(const CodeLookupTable& clt,
uword pc_marker,
Expand Down
17 changes: 10 additions & 7 deletions runtime/vm/profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,17 +726,20 @@ class ProcessedSample : public ZoneAllocated {
first_frame_executing_ = first_frame_executing;
}

ProfileTrieNode* timeline_trie() const { return timeline_trie_; }
void set_timeline_trie(ProfileTrieNode* trie) {
ASSERT(timeline_trie_ == NULL);
timeline_trie_ = trie;
}

ProfileTrieNode* timeline_code_trie() const { return timeline_code_trie_; }
void set_timeline_code_trie(ProfileTrieNode* trie) {
ASSERT(timeline_code_trie_ == NULL);
timeline_code_trie_ = trie;
}

ProfileTrieNode* timeline_function_trie() const {
return timeline_function_trie_;
}
void set_timeline_function_trie(ProfileTrieNode* trie) {
ASSERT(timeline_function_trie_ == NULL);
timeline_function_trie_ = trie;
}

private:
void FixupCaller(const CodeLookupTable& clt,
uword pc_marker,
Expand All @@ -757,8 +760,8 @@ class ProcessedSample : public ZoneAllocated {
bool first_frame_executing_;
uword native_allocation_address_;
uintptr_t native_allocation_size_bytes_;
ProfileTrieNode* timeline_trie_;
ProfileTrieNode* timeline_code_trie_;
ProfileTrieNode* timeline_function_trie_;

friend class SampleBuffer;
DISALLOW_COPY_AND_ASSIGN(ProcessedSample);
Expand Down
92 changes: 62 additions & 30 deletions runtime/vm/profiler_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1501,8 +1501,6 @@ class ProfileBuilder : public ValueObject {
if (sample->truncated()) {
current = AppendTruncatedTag(current, sample);
}

sample->set_timeline_code_trie(current);
}
}

Expand Down Expand Up @@ -1553,7 +1551,7 @@ class ProfileBuilder : public ValueObject {
current = AppendExitFrame(sample->vm_tag(), current, sample);
}

sample->set_timeline_trie(current);
sample->set_timeline_function_trie(current);
}
}

Expand Down Expand Up @@ -2410,7 +2408,8 @@ static const intptr_t kRootFrameId = 0;
void Profile::PrintTimelineFrameJSON(JSONObject* frames,
ProfileTrieNode* current,
ProfileTrieNode* parent,
intptr_t* next_id) {
intptr_t* next_id,
bool code_trie) {
ASSERT(current->frame_id() == -1);
const intptr_t id = *next_id;
*next_id = id + 1;
Expand All @@ -2425,8 +2424,13 @@ void Profile::PrintTimelineFrameJSON(JSONObject* frames,
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 (code_trie) {
ProfileCode* code = GetCode(current->table_index());
frame.AddProperty("name", code->name());
} else {
ProfileFunction* func = GetFunction(current->table_index());
frame.AddProperty("name", func->Name());
}
if ((parent != NULL) && (parent->frame_id() != kRootFrameId)) {
ASSERT(parent->frame_id() != -1);
frame.AddPropertyF("parent", "%" Pd "-%" Pd, isolate_id,
Expand All @@ -2436,20 +2440,25 @@ void Profile::PrintTimelineFrameJSON(JSONObject* frames,

for (intptr_t i = 0; i < current->NumChildren(); i++) {
ProfileTrieNode* child = current->At(i);
PrintTimelineFrameJSON(frames, child, current, next_id);
PrintTimelineFrameJSON(frames, child, current, next_id, code_trie);
}
}

void Profile::PrintTimelineJSON(JSONStream* stream) {
void Profile::PrintTimelineJSON(JSONStream* stream, bool code_trie) {
ScopeTimer sw("Profile::PrintTimelineJSON", FLAG_trace_profiler);
JSONObject obj(stream);
obj.AddProperty("type", "_CpuProfileTimeline");
PrintHeaderJSON(&obj);
{
JSONObject frames(&obj, "stackFrames");
ProfileTrieNode* root = GetTrieRoot(kInclusiveFunction);
ProfileTrieNode* root;
if (code_trie) {
root = GetTrieRoot(kInclusiveCode);
} else {
root = GetTrieRoot(kInclusiveFunction);
}
intptr_t next_id = kRootFrameId;
PrintTimelineFrameJSON(&frames, root, NULL, &next_id);
PrintTimelineFrameJSON(&frames, root, NULL, &next_id, code_trie);
}
{
JSONArray events(&obj, "traceEvents");
Expand All @@ -2471,24 +2480,35 @@ void Profile::PrintTimelineJSON(JSONStream* stream) {
args.AddProperty("mode", "basic");
}

ProfileTrieNode* trie = sample->timeline_trie();
ProfileTrieNode* trie;
if (code_trie) {
trie = sample->timeline_code_trie();
} else {
trie = sample->timeline_function_trie();
}
ASSERT(trie->frame_id() != -1);
event.AddPropertyF("sf", "%" Pd "-%" Pd, isolate_id, trie->frame_id());
}
}
}

void Profile::AddParentTriePointers(ProfileTrieNode* current,
ProfileTrieNode* parent) {
ProfileTrieNode* parent,
bool code_trie) {
if (current == NULL) {
ProfileTrieNode* root = GetTrieRoot(kInclusiveCode);
AddParentTriePointers(root, NULL);
ProfileTrieNode* root;
if (code_trie) {
root = GetTrieRoot(kInclusiveCode);
} else {
root = GetTrieRoot(kInclusiveFunction);
}
AddParentTriePointers(root, NULL, code_trie);
return;
}

current->set_parent(parent);
for (int i = 0; i < current->NumChildren(); i++) {
AddParentTriePointers(current->At(i), current);
AddParentTriePointers(current->At(i), current, code_trie);
}
}

Expand All @@ -2501,17 +2521,21 @@ void Profile::PrintBacktrace(ProfileTrieNode* node, TextBuffer* buf) {
}
}

void Profile::AddToTimeline() {
void Profile::AddToTimeline(bool code_trie) {
TimelineStream* stream = Timeline::GetProfilerStream();
if (stream == NULL) {
return;
}
AddParentTriePointers(NULL, NULL);
AddParentTriePointers(NULL, NULL, code_trie);
for (intptr_t sample_index = 0; sample_index < samples_->length();
sample_index++) {
TextBuffer buf(256);
ProcessedSample* sample = samples_->At(sample_index);
PrintBacktrace(sample->timeline_code_trie(), &buf);
if (code_trie) {
PrintBacktrace(sample->timeline_code_trie(), &buf);
} else {
PrintBacktrace(sample->timeline_function_trie(), &buf);
}
TimelineEvent* event = stream->StartEvent();
event->Instant("Dart CPU sample", sample->timestamp());
event->set_owns_label(false);
Expand Down Expand Up @@ -2745,7 +2769,8 @@ void ProfilerService::PrintJSONImpl(Thread* thread,
intptr_t extra_tags,
SampleFilter* filter,
SampleBuffer* sample_buffer,
PrintKind kind) {
PrintKind kind,
bool code_trie) {
Isolate* isolate = thread->isolate();
// Disable thread interrupts while processing the buffer.
DisableThreadInterruptsScope dtis(thread);
Expand All @@ -2761,11 +2786,11 @@ void ProfilerService::PrintJSONImpl(Thread* thread,
Profile profile(isolate);
profile.Build(thread, filter, sample_buffer, tag_order, extra_tags);
if (kind == kAsTimeline) {
profile.PrintTimelineJSON(stream);
profile.PrintTimelineJSON(stream, code_trie);
} else if (kind == kAsProfile) {
profile.PrintProfileJSON(stream);
} else if (kind == kAsPlatformTimeline) {
profile.AddToTimeline();
profile.AddToTimeline(code_trie);
}
}
}
Expand Down Expand Up @@ -2793,8 +2818,9 @@ void ProfilerService::PrintJSON(JSONStream* stream,
Isolate* isolate = thread->isolate();
NoAllocationSampleFilter filter(isolate->main_port(), Thread::kMutatorTask,
time_origin_micros, time_extent_micros);
bool code_trie = false; // Doesn't matter for kAsProfile.
PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter,
Profiler::sample_buffer(), kAsProfile);
Profiler::sample_buffer(), kAsProfile, code_trie);
}

class ClassAllocationSampleFilter : public SampleFilter {
Expand Down Expand Up @@ -2831,8 +2857,9 @@ void ProfilerService::PrintAllocationJSON(JSONStream* stream,
ClassAllocationSampleFilter filter(isolate->main_port(), cls,
Thread::kMutatorTask, time_origin_micros,
time_extent_micros);
bool code_trie = false; // Doesn't matter for kAsProfile.
PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter,
Profiler::sample_buffer(), kAsProfile);
Profiler::sample_buffer(), kAsProfile, code_trie);
}

void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream,
Expand All @@ -2841,14 +2868,16 @@ void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream,
int64_t time_extent_micros) {
Thread* thread = Thread::Current();
NativeAllocationSampleFilter filter(time_origin_micros, time_extent_micros);
bool code_trie = false; // Doesn't matter for kAsProfile.
PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter,
Profiler::allocation_sample_buffer(), kAsProfile);
Profiler::allocation_sample_buffer(), kAsProfile, code_trie);
}

void ProfilerService::PrintTimelineJSON(JSONStream* stream,
Profile::TagOrder tag_order,
int64_t time_origin_micros,
int64_t time_extent_micros) {
int64_t time_extent_micros,
bool code_trie) {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
const intptr_t thread_task_mask = Thread::kMutatorTask |
Expand All @@ -2857,20 +2886,23 @@ void ProfilerService::PrintTimelineJSON(JSONStream* stream,
NoAllocationSampleFilter filter(isolate->main_port(), thread_task_mask,
time_origin_micros, time_extent_micros);
PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter,
Profiler::sample_buffer(), kAsTimeline);
Profiler::sample_buffer(), kAsTimeline, code_trie);
}

void ProfilerService::AddToTimeline() {
void ProfilerService::AddToTimeline(Profile::TagOrder tag_order,
int64_t time_origin_micros,
int64_t time_extent_micros,
bool code_trie) {
JSONStream stream;
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
const intptr_t thread_task_mask = Thread::kMutatorTask |
Thread::kCompilerTask |
Thread::kSweeperTask | Thread::kMarkerTask;
NoAllocationSampleFilter filter(isolate->main_port(), thread_task_mask, -1,
-1);
NoAllocationSampleFilter filter(isolate->main_port(), thread_task_mask,
time_origin_micros, time_extent_micros);
PrintJSONImpl(thread, &stream, Profile::kNoTags, kNoExtraTags, &filter,
Profiler::sample_buffer(), kAsPlatformTimeline);
Profiler::sample_buffer(), kAsPlatformTimeline, code_trie);
}

void ProfilerService::ClearSamples() {
Expand Down
22 changes: 15 additions & 7 deletions runtime/vm/profiler_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,22 +394,25 @@ class Profile : public ValueObject {
ProfileTrieNode* GetTrieRoot(TrieKind trie_kind);

void PrintProfileJSON(JSONStream* stream);
void PrintTimelineJSON(JSONStream* stream);
void PrintTimelineJSON(JSONStream* stream, bool code_trie);

// Serializes sample backtraces into arguments on Instant events and adds them
// directly to the timeline.
void AddToTimeline();
void AddToTimeline(bool code_trie);

ProfileFunction* FindFunction(const Function& function);

private:
void AddParentTriePointers(ProfileTrieNode* current, ProfileTrieNode* parent);
void AddParentTriePointers(ProfileTrieNode* current,
ProfileTrieNode* parent,
bool code_trie);
void PrintBacktrace(ProfileTrieNode* node, TextBuffer* buf);
void PrintHeaderJSON(JSONObject* obj);
void PrintTimelineFrameJSON(JSONObject* frames,
ProfileTrieNode* current,
ProfileTrieNode* parent,
intptr_t* next_id);
intptr_t* next_id,
bool code_trie);

Isolate* isolate_;
Zone* zone_;
Expand Down Expand Up @@ -497,9 +500,13 @@ class ProfilerService : public AllStatic {
static void PrintTimelineJSON(JSONStream* stream,
Profile::TagOrder tag_order,
int64_t time_origin_micros,
int64_t time_extent_micros);
int64_t time_extent_micros,
bool code_trie);

static void AddToTimeline();
static void AddToTimeline(Profile::TagOrder tag_order,
int64_t time_origin_micros,
int64_t time_extent_micros,
bool code_trie);

static void ClearSamples();

Expand All @@ -516,7 +523,8 @@ class ProfilerService : public AllStatic {
intptr_t extra_tags,
SampleFilter* filter,
SampleBuffer* sample_buffer,
PrintKind kind);
PrintKind kind,
bool code_trie);
};

} // namespace dart
Expand Down
13 changes: 11 additions & 2 deletions runtime/vm/service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3866,13 +3866,22 @@ static bool GetCpuProfileTimeline(Thread* thread, JSONStream* js) {
UIntParameter::Parse(js->LookupParam("timeOriginMicros"));
int64_t time_extent_micros =
UIntParameter::Parse(js->LookupParam("timeExtentMicros"));
bool code_trie = BoolParameter::Parse(js->LookupParam("code"), false);
ProfilerService::PrintTimelineJSON(js, tag_order, time_origin_micros,
time_extent_micros);
time_extent_micros, code_trie);
return true;
}

static bool WriteCpuProfileTimeline(Thread* thread, JSONStream* js) {
ProfilerService::AddToTimeline();
Profile::TagOrder tag_order =
EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
int64_t time_origin_micros =
UIntParameter::Parse(js->LookupParam("timeOriginMicros"));
int64_t time_extent_micros =
UIntParameter::Parse(js->LookupParam("timeExtentMicros"));
bool code_trie = BoolParameter::Parse(js->LookupParam("code"), true);
ProfilerService::AddToTimeline(tag_order, time_origin_micros,
time_extent_micros, code_trie);
return true;
}

Expand Down

0 comments on commit b7a5e47

Please sign in to comment.