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

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

Issue 2755943002: tracing: Stream processing for some importers (Closed)
Patch Set: review / sync Created 3 years, 8 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 ab0f98bef184c363213019d9f28fed7297ad83fe..16c5e15ac9e75443da37cdae013385cf00b3ec2b 100644
--- a/tracing/tracing/extras/importer/trace_event_importer.html
+++ b/tracing/tracing/extras/importer/trace_event_importer.html
@@ -9,9 +9,11 @@ found in the LICENSE file.
<link rel="import" href="/tracing/base/color_scheme.html">
<link rel="import" href="/tracing/base/math/range.html">
<link rel="import" href="/tracing/base/scalar.html">
+<link rel="import" href="/tracing/base/trace_stream.html">
<link rel="import" href="/tracing/base/unit.html">
<link rel="import" href="/tracing/base/utils.html">
<link rel="import" href="/tracing/extras/importer/heap_dump_trace_event_importer.html">
+<link rel="import" href="/tracing/extras/importer/oboe.html">
<link rel="import" href="/tracing/extras/importer/trace_code_entry.html">
<link rel="import" href="/tracing/extras/importer/trace_code_map.html">
<link rel="import" href="/tracing/extras/importer/v8/codemap.html">
@@ -121,6 +123,7 @@ tr.exportTo('tr.e.importer', function() {
// The complete list of fields on the trace that should not be treated as
// trace metadata.
var NON_METADATA_FIELDS = new Set([
+ 'displayTimeUnit',
'samples',
'stackFrames',
'traceAnnotations',
@@ -129,6 +132,7 @@ tr.exportTo('tr.e.importer', function() {
]);
function TraceEventImporter(model, eventData) {
+ this.hasEvents_ = undefined; // Set properly when importEvents is called.
this.importPriority = 1;
this.model_ = model;
this.events_ = undefined;
@@ -196,53 +200,38 @@ tr.exportTo('tr.e.importer', function() {
this.events_ = eventData;
}
- this.traceAnnotations_ = this.events_.traceAnnotations;
-
// Some trace_event implementations put the actual trace events
// inside a container. E.g { ... , traceEvents: [ ] }
// If we see that, just pull out the trace events.
if (this.events_.traceEvents) {
- var container = this.events_;
+ const container = this.events_;
this.events_ = this.events_.traceEvents;
- // Some trace authors store subtraces as specific properties of the trace.
- for (var subtraceField of SUBTRACE_FIELDS) {
+ for (const subtraceField of SUBTRACE_FIELDS) {
if (container[subtraceField]) {
- this.subtraces_.push(container[subtraceField]);
- }
- }
-
- // Sampling data.
- this.sampleEvents_ = container.samples;
- this.stackFrameEvents_ = container.stackFrames;
-
- // Some implementations specify displayTimeUnit
- if (container.displayTimeUnit) {
- var unitName = container.displayTimeUnit;
- var unit = tr.b.TimeDisplayModes[unitName];
- if (unit === undefined) {
- throw new Error('Unit ' + unitName + ' is not supported.');
- }
- this.model_.intrinsicTimeUnit = unit;
- }
-
- // Any other fields in the container should be treated as metadata.
- for (var fieldName in container) {
- if (NON_METADATA_FIELDS.has(fieldName)) continue;
-
- this.model_.metadata.push(
- { name: fieldName, value: container[fieldName] });
-
- if (fieldName === 'metadata') {
- var metadata = container[fieldName];
- if (metadata['highres-ticks']) {
- this.model_.isTimeHighResolution = metadata['highres-ticks'];
- }
- if (metadata['clock-domain']) {
- this.clockDomainId_ = metadata['clock-domain'];
- }
- }
- }
+ this.storeSubtrace_(container[subtraceField]);
+ }
+ }
+ this.storeSamples_(container.samples);
+ this.storeStackFrames_(container.stackFrames);
+ this.storeDisplayTimeUnit_(container.displayTimeUnit);
+ this.storeTraceAnnotations_(container.traceAnnotations);
+ this.storeMetadata_(container);
+ } else if (this.events_ instanceof tr.b.TraceStream) {
+ const parser = oboe()
+ .node('{cat ph}', function(e) { return oboe.drop; })
+ .node('!.powerTraceAsString', this.storeSubtrace_.bind(this))
+ .node('!.systemTraceEvents', this.storeSubtrace_.bind(this))
+ .node('!.samples', this.storeSamples_.bind(this))
+ .node('!.stackFrames', this.storeStackFrames_.bind(this))
+ .node('!.displayTimeUnit', this.storeDisplayTimeUnit_.bind(this))
+ .node('!.traceAnnotations', this.storeTraceAnnotations_.bind(this))
+ .done(this.storeMetadata_.bind(this));
+ this.events_.rewind();
+ while (this.events_.hasData) {
+ parser.write(this.events_.readNumBytes());
+ }
+ parser.finish();
}
}
@@ -255,6 +244,11 @@ tr.exportTo('tr.e.importer', function() {
// - eventData that starts with [ are probably trace_event
// - eventData that starts with { are probably trace_event
// May be encoded JSON. Treat files that start with { as importable by us.
+ if (eventData instanceof tr.b.TraceStream) {
+ if (eventData.isBinary) return false;
+ eventData = eventData.header;
+ }
+
if (typeof(eventData) === 'string' || eventData instanceof String) {
eventData = eventData.trim();
return eventData[0] === '{' || eventData[0] === '[';
@@ -271,7 +265,8 @@ tr.exportTo('tr.e.importer', function() {
if (eventData.traceEvents.length && eventData.traceEvents[0].ph) {
return true;
}
- if (eventData.samples.length && eventData.stackFrames !== undefined) {
+ if (eventData.samples && eventData.samples.length &&
+ eventData.stackFrames !== undefined) {
return true;
}
}
@@ -1079,24 +1074,36 @@ tr.exportTo('tr.e.importer', function() {
},
importClockSyncMarkers: function() {
- for (var i = 0; i < this.events_.length; i++) {
- var event = this.events_[i];
+ if (this.events_ instanceof tr.b.TraceStream) {
+ const parser = oboe().node(
+ '{cat ph}', this.importClockSyncMarker_.bind(this));
+ this.events_.rewind();
+ while (this.events_.hasData) {
+ parser.write(this.events_.readNumBytes());
+ }
+ parser.finish();
+ } else {
+ for (let i = 0; i < this.events_.length; i++) {
+ this.importClockSyncMarker_(this.events_[i]);
+ }
+ }
+ },
- var isLegacyChromeClockSync = isLegacyChromeClockSyncEvent(event);
- if (event.ph !== 'c' && !isLegacyChromeClockSync) continue;
+ importClockSyncMarker_: function(event) {
+ const isLegacyChromeClockSync = isLegacyChromeClockSyncEvent(event);
+ if (event.ph !== 'c' && !isLegacyChromeClockSync) return;
- var eventSizeInBytes =
- this.model_.importOptions.trackDetailedModelStats ?
- JSON.stringify(event).length : undefined;
+ const eventSizeInBytes =
+ this.model_.importOptions.trackDetailedModelStats ?
+ JSON.stringify(event).length : undefined;
- this.model_.stats.willProcessBasicTraceEvent(
- 'clock_sync', event.cat, event.name, event.ts, eventSizeInBytes);
+ this.model_.stats.willProcessBasicTraceEvent(
+ 'clock_sync', event.cat, event.name, event.ts, eventSizeInBytes);
- if (isLegacyChromeClockSync) {
- this.processLegacyChromeClockSyncEvent(event);
- } else {
- this.processClockSyncEvent(event);
- }
+ if (isLegacyChromeClockSync) {
+ this.processLegacyChromeClockSyncEvent(event);
+ } else {
+ this.processClockSyncEvent(event);
}
},
@@ -1105,95 +1112,199 @@ tr.exportTo('tr.e.importer', function() {
* model_.
*/
importEvents: function() {
+ this.hasEvents_ = false;
if (this.stackFrameEvents_) {
this.importStackFrames_(this.stackFrameEvents_, 'g');
}
- if (this.traceAnnotations_) {
- this.importAnnotations_();
+ if (this.traceAnnotations_) this.importAnnotations_();
+
+ if (this.events_ instanceof tr.b.TraceStream) {
+ const parser = oboe().node('{cat ph}', this.processEvent_.bind(this));
+ this.events_.rewind();
+ while (this.events_.hasData) {
+ parser.write(this.events_.readNumBytes());
+ }
+ parser.finish();
+ } else {
+ for (let eI = 0; eI < this.events_.length; eI++) {
+ this.processEvent_(this.events_[eI]);
+ }
}
- var importOptions = this.model_.importOptions;
- var trackDetailedModelStats = importOptions.trackDetailedModelStats;
+ this.processV8Events();
- var modelStats = this.model_.stats;
+ // Remove all the root stack frame children as they should
+ // already be added.
+ for (const frame of Object.values(this.v8ProcessRootStackFrame_)) {
+ frame.removeAllChildren();
+ }
+ },
- var events = this.events_;
- for (var eI = 0; eI < events.length; eI++) {
- var event = events[eI];
+ // Some trace authors store subtraces as specific properties of the trace.
+ storeSubtrace_: function(subtrace) {
+ this.subtraces_.push(subtrace);
+ return oboe.drop;
+ },
- if (event.args === '__stripped__') {
- event.argsStripped = true;
- event.args = undefined;
- }
+ storeSamples_: function(samples) {
+ this.sampleEvents_ = samples;
+ return oboe.drop;
+ },
- var eventSizeInBytes;
- if (trackDetailedModelStats) {
- eventSizeInBytes = JSON.stringify(event).length;
- } else {
- eventSizeInBytes = undefined;
+ storeStackFrames_: function(stackFrames) {
+ this.stackFrameEvents_ = stackFrames;
+ return oboe.drop;
+ },
+
+ // Some implementations specify displayTimeUnit
+ storeDisplayTimeUnit_: function(unitName) {
+ if (!unitName) return;
+ const unit = tr.b.TimeDisplayModes[unitName];
+ if (unit === undefined) {
+ throw new Error('Unit ' + unitName + ' is not supported.');
+ }
+ this.model_.intrinsicTimeUnit = unit;
+ return oboe.drop;
+ },
+
+ storeTraceAnnotations_: function(traceAnnotations) {
+ this.traceAnnotations_ = traceAnnotations;
+ return oboe.drop;
+ },
+
+ // Any fields in the container that is not in NON_METADATA_FIELDS should be
+ // treated as metadata.
+ storeMetadata_: function(container) {
+ for (const fieldName of Object.keys(container)) {
+ if (NON_METADATA_FIELDS.has(fieldName)) continue;
+ this.model_.metadata.push(
+ { name: fieldName, value: container[fieldName] });
+ if (fieldName !== 'metadata') continue;
+ const metadata = container[fieldName];
+ if (metadata['highres-ticks']) {
+ this.model_.isTimeHighResolution = metadata['highres-ticks'];
}
+ if (metadata['clock-domain']) {
+ this.clockDomainId_ = metadata['clock-domain'];
+ }
+ }
+ return oboe.drop;
+ },
- if (event.ph === 'B' || event.ph === 'E') {
+ processEvent_: function(event) {
+ this.hasEvents_ = true;
+ const importOptions = this.model_.importOptions;
+ const trackDetailedModelStats = importOptions.trackDetailedModelStats;
+ const modelStats = this.model_.stats;
+
+ if (event.args === '__stripped__') {
+ event.argsStripped = true;
+ event.args = undefined;
+ }
+
+ let eventSizeInBytes = undefined;
+ if (trackDetailedModelStats) {
+ eventSizeInBytes = JSON.stringify(event).length;
+ }
+
+ switch (event.ph) {
+ case 'B':
+ case 'E':
modelStats.willProcessBasicTraceEvent(
'begin_end (non-compact)', event.cat, event.name, event.ts,
eventSizeInBytes);
this.processDurationEvent(event);
- } else if (event.ph === 'X') {
+ break;
+
+ case 'X': {
modelStats.willProcessBasicTraceEvent(
'begin_end (compact)', event.cat, event.name, event.ts,
eventSizeInBytes);
- var slice = this.processCompleteEvent(event);
+ const slice = this.processCompleteEvent(event);
// TODO(yuhaoz): If Chrome supports creating other events with flow,
// we will need to call processFlowEvent for them also.
// https://github.com/catapult-project/catapult/issues/1259
if (slice !== undefined && event.bind_id !== undefined) {
this.processFlowEvent(event, slice);
}
- } else if (event.ph === 'b' || event.ph === 'e' || event.ph === 'n' ||
- event.ph === 'S' || event.ph === 'F' || event.ph === 'T' ||
- event.ph === 'p') {
+ break;
+ }
+
+ case 'b':
+ case 'e':
+ case 'n':
+ case 'S':
+ case 'F':
+ case 'T':
+ case 'p':
modelStats.willProcessBasicTraceEvent(
'async', event.cat, event.name, event.ts, eventSizeInBytes);
this.processAsyncEvent(event);
+ break;
// Note, I is historic. The instant event marker got changed, but we
// want to support loading old trace files so we have both I and i.
- } else if (event.ph === 'I' || event.ph === 'i' || event.ph === 'R') {
+ case 'I':
+ case 'i':
+ case 'R':
modelStats.willProcessBasicTraceEvent(
'instant', event.cat, event.name, event.ts, eventSizeInBytes);
this.processInstantEvent(event);
- } else if (event.ph === 'P') {
+ break;
+
+ case 'P':
modelStats.willProcessBasicTraceEvent(
'samples', event.cat, event.name, event.ts, eventSizeInBytes);
this.processTraceSampleEvent(event);
- } else if (event.ph === 'C') {
+ break;
+
+ case 'C':
modelStats.willProcessBasicTraceEvent(
'counters', event.cat, event.name, event.ts, eventSizeInBytes);
this.processCounterEvent(event);
- } else if (event.ph === 'M') {
+ break;
+
+ case 'M':
modelStats.willProcessBasicTraceEvent(
'metadata', event.cat, event.name, event.ts, eventSizeInBytes);
this.processMetadataEvent(event);
- } else if (event.ph === 'N' || event.ph === 'D' || event.ph === 'O') {
+ break;
+
+ case 'N':
+ case 'D':
+ case 'O':
modelStats.willProcessBasicTraceEvent(
'objects', event.cat, event.name, event.ts, eventSizeInBytes);
this.processObjectEvent(event);
- } else if (event.ph === 's' || event.ph === 't' || event.ph === 'f') {
+ break;
+
+ case 's':
+ case 't':
+ case 'f':
modelStats.willProcessBasicTraceEvent(
'flows', event.cat, event.name, event.ts, eventSizeInBytes);
this.processFlowEvent(event);
- } else if (event.ph === 'v') {
+ break;
+
+ case 'v':
modelStats.willProcessBasicTraceEvent(
'memory_dumps', event.cat, event.name, event.ts,
eventSizeInBytes);
this.processMemoryDumpEvent(event);
- } else if (event.ph === '(' || event.ph === ')') {
+ break;
+
+ case '(':
+ case ')':
this.processContextEvent(event);
- } else if (event.ph === 'c') {
- // No-op. Clock sync events have already been processed in
- // importClockSyncMarkers().
- } else {
+ break;
+
+ // No-op. Clock sync events have already been processed in
+ // importClockSyncMarkers().
+ case 'c':
+ break;
+
+ default:
modelStats.willProcessBasicTraceEvent(
'unknown', event.cat, event.name, event.ts, eventSizeInBytes);
this.model_.importWarning({
@@ -1201,15 +1312,8 @@ tr.exportTo('tr.e.importer', function() {
message: 'Unrecognized event phase: ' +
event.ph + ' (' + event.name + ')'
});
- }
- }
- this.processV8Events();
-
- // Remove all the root stack frame children as they should
- // already be added.
- for (var frame of Object.values(this.v8ProcessRootStackFrame_)) {
- frame.removeAllChildren();
}
+ return oboe.drop;
},
importStackFrames_: function(rawStackFrames, idPrefix) {
@@ -1424,7 +1528,9 @@ tr.exportTo('tr.e.importer', function() {
// If this is the only importer, then fake-create the threads.
var events = this.sampleEvents_;
- if (this.events_.length === 0) {
+ if (this.hasEvents_ === undefined) {
+ throw new Error('importEvents is not run before importSampleData');
+ } else if (!this.hasEvents_) {
for (var i = 0; i < events.length; i++) {
var event = events[i];
m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);

Powered by Google App Engine
This is Rietveld 408576698