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

Unified Diff: tracing/tracing/extras/importer/trace_event_importer.html

Issue 1276003004: Process v8 sampling data into the trace model. (Closed) Base URL: git@github.com:catapult-project/catapult.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
Index: tracing/tracing/extras/importer/trace_event_importer.html
diff --git a/tracing/tracing/extras/importer/trace_event_importer.html b/tracing/tracing/extras/importer/trace_event_importer.html
index 6e24d4ac0866eb3fad6c2f5bbdfea7075e3e0f15..07acd2b894d5e2b7d19672b0168ec4c6d3ff8e49 100644
--- a/tracing/tracing/extras/importer/trace_event_importer.html
+++ b/tracing/tracing/extras/importer/trace_event_importer.html
@@ -5,11 +5,12 @@ Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
-<link rel="import" href="/tracing/ui/base/color_scheme.html">
<link rel="import" href="/tracing/base/quad.html">
<link rel="import" href="/tracing/base/range.html">
<link rel="import" href="/tracing/base/utils.html">
<link rel="import" href="/tracing/base/units/time.html">
+<link rel="import" href="/tracing/extras/importer/trace_code_entry.html">
+<link rel="import" href="/tracing/extras/importer/v8/codemap.html">
<link rel="import" href="/tracing/importer/importer.html">
<link rel="import" href="/tracing/model/attribute.html">
<link rel="import" href="/tracing/model/comment_box_annotation.html">
@@ -23,6 +24,7 @@ found in the LICENSE file.
<link rel="import" href="/tracing/model/rect_annotation.html">
<link rel="import" href="/tracing/model/x_marker_annotation.html">
<link rel="import" href="/tracing/model/model.html">
+<link rel="import" href="/tracing/ui/base/color_scheme.html">
<script>
'use strict';
@@ -32,9 +34,7 @@ found in the LICENSE file.
* into the provided model.
*/
tr.exportTo('tr.e.importer', function() {
-
var Importer = tr.importer.Importer;
-
var deepCopy = tr.b.deepCopy;
function getEventColor(event, opt_customName) {
@@ -59,11 +59,16 @@ tr.exportTo('tr.e.importer', function() {
this.battorData_ = undefined;
this.eventsWereFromString_ = false;
this.softwareMeasuredCpuCount_ = undefined;
+
this.allAsyncEvents_ = [];
this.allFlowEvents_ = [];
this.allObjectEvents_ = [];
+
this.traceEventSampleStackFramesByName_ = {};
+ this.v8ProcessCodeMaps_ = {};
+ this.v8ProcessRootStackFrame_ = {};
+
// Dump ID -> {global: (event | undefined), process: [events]}
this.allMemoryDumpEvents_ = {};
@@ -401,7 +406,37 @@ tr.exportTo('tr.e.importer', function() {
}
},
+ processJitCodeEvent: function(event) {
+ if (this.v8ProcessCodeMaps_[event.pid] === undefined)
+ this.v8ProcessCodeMaps_[event.pid] = new tr.e.importer.v8.CodeMap();
+ var map = this.v8ProcessCodeMaps_[event.pid];
+
+ var data = event.args.data;
+ var startAddr = parseInt(data.code_start, 16);
+ if (event.name === 'JitCodeMoved') {
+ try {
+ map.moveCode(startAddr, parseInt(data.new_code_start, 16));
+ } catch (err) {
+ // Ignore moved error. Means we didn't find the original block.
+ // We won't know the name if we try to insert the code here.
+ }
+ } else {
+ map.addCode(startAddr,
+ new tr.e.importer.TraceCodeEntry(data.code_len, data.name));
+ }
+ },
+
processInstantEvent: function(event) {
+ // V8 JIT events are logged as phase 'I' so we need to separate them out
+ // and handle specially.
+ //
+ // TODO(dsinclair): There are _a lot_ of JitCode events so I'm skipping
+ // the display for now. Can revisit later if we want to show them.
+ if (event.name === 'JitCodeAdded' || event.name === 'JitCodeMoved') {
+ this.processJitCodeEvent(event);
+ return;
+ }
+
// Thread-level instant events are treated as zero-duration slices.
if (event.s == 't' || event.s === undefined) {
this.processDurationEvent(event);
@@ -443,10 +478,95 @@ tr.exportTo('tr.e.importer', function() {
}
},
- processTraceSampleEvent: function(event) {
+ processV8Sample: function(event) {
+ var data = event.args.data;
+
+ var rootStackFrame = this.v8ProcessRootStackFrame_[event.pid];
+ if (!rootStackFrame) {
+ rootStackFrame = new tr.model.StackFrame(
+ undefined /* parent */, 'v8-root-stack-frame' /* id */,
+ 'v8' /* category */, 'v8-root-stack-frame' /* title */,
+ 0 /* colorId */);
+ this.v8ProcessRootStackFrame_[event.pid] = rootStackFrame;
+ }
+
+ function findChildWithEntryID(stackFrame, entryID) {
+ return tr.b.findFirstInArray(stackFrame.children, function(child) {
+ return child.entryID === entryID;
+ });
+ }
+
+ var model = this.model_;
+ function addStackFrame(lastStackFrame, entry) {
+ var childFrame = findChildWithEntryID(lastStackFrame, entry.id);
+ if (childFrame)
+ return childFrame;
+
+ var frame = new tr.model.StackFrame(
+ lastStackFrame, tr.b.GUID.allocate(),
+ 'v8', entry.name,
+ tr.ui.b.getColorIdForGeneralPurposeString(entry.name),
+ entry.sourceInfo);
+
+ frame.entryID = entry.id;
+ model.addStackFrame(frame);
+ return frame;
+ }
+
+ var lastStackFrame = rootStackFrame;
+
+ // There are several types of v8 sample events, gc, native, compiler, etc.
+ // Some of these types have stacks and some don't, we handle those two
+ // cases differently. For types that don't have any stack frames attached
+ // we synthesize one based on the type of thing that's happening so when
+ // we view all the samples we'll see something like 'external' or 'gc'
+ // as a fraction of the time spent.
+ if (data.stack.length > 0 && this.v8ProcessCodeMaps_[event.pid]) {
+ var map = this.v8ProcessCodeMaps_[event.pid];
+
+ // Stacks have the leaf node first, flip them around so the root
+ // comes first.
+ data.stack.reverse();
+
+ for (var i = 0; i < data.stack.length; i++) {
+ var addr = parseInt(data.stack[i], 16);
+ var entry = map.findEntry(addr);
+
+ if (entry === null) {
+ entry = {
+ id: 'unknown',
+ name: 'unknown',
+ sourceInfo: undefined
+ };
+ }
+
+ lastStackFrame = addStackFrame(lastStackFrame, entry);
+ }
+ } else {
+ var entry = {
+ id: data.vm_state,
+ name: data.vm_state,
+ sourceInfo: undefined
+ };
+ lastStackFrame = addStackFrame(lastStackFrame, entry);
+ }
+
var thread = this.model_.getOrCreateProcess(event.pid)
.getOrCreateThread(event.tid);
+ var sample = new tr.model.Sample(
+ undefined /* cpu */, thread, 'V8 Sample',
+ timestampFromUs(event.ts), lastStackFrame, 1 /* weight */,
+ this.deepCopyIfNeeded_(event.args));
+ this.model_.samples.push(sample);
+ },
+
+ processTraceSampleEvent: function(event) {
+ if (event.name === 'V8Sample') {
+ this.processV8Sample(event);
+ return;
+ }
+
var stackFrame = this.getStackFrameForEvent_(event);
if (stackFrame === undefined) {
stackFrame = this.traceEventSampleStackFramesByName_[
@@ -462,8 +582,11 @@ tr.exportTo('tr.e.importer', function() {
this.traceEventSampleStackFramesByName_[event.name] = stackFrame;
}
+ var thread = this.model_.getOrCreateProcess(event.pid)
+ .getOrCreateThread(event.tid);
+
var sample = new tr.model.Sample(
- undefined, thread, 'TRACE_EVENT_SAMPLE',
+ undefined, thread, 'Trace Event Sample',
timestampFromUs(event.ts), stackFrame, 1,
this.deepCopyIfNeeded_(event.args));
this.model_.samples.push(sample);
@@ -570,6 +693,12 @@ tr.exportTo('tr.e.importer', function() {
});
}
}
+
+ // Remove all the root stack frame children as they should
+ // already be added.
+ tr.b.iterItems(this.v8ProcessRootStackFrame_, function(name, frame) {
+ frame.removeAllChildren();
+ });
},
importStackFrames_: function() {
@@ -860,7 +989,7 @@ tr.exportTo('tr.e.importer', function() {
});
} else {
// Include args for both END and BEGIN for a matched pair.
- var concatenateArguments = function(args1, args2) {
+ function concatenateArguments(args1, args2) {
if (args1.params === undefined || args2.params === undefined)
return tr.b.concatenateObjects(args1, args2);
// Make an argument object to hold the combined params.

Powered by Google App Engine
This is Rietveld 408576698