1010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis// Use of this source code is governed by a BSD-style license that can be 3010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis// found in the LICENSE file. 4010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 5010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis/** 6010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @fileoverview TraceEventImporter imports TraceEvent-formatted data 7010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * into the provided timeline model. 8010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 92da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('timeline_model'); 102da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('timeline_color_scheme'); 112da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.exportTo('tracing', function() { 12010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 13010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis function TraceEventImporter(model, eventData) { 142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.importPriority = 1; 15010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_ = model; 16010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 17010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (typeof(eventData) === 'string' || eventData instanceof String) { 18010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // If the event data begins with a [, then we know it should end with a ]. 19010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // The reason we check for this is because some tracing implementations 20010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // cannot guarantee that a ']' gets written to the trace file. So, we are 21010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // forgiving and if this is obviously the case, we fix it up before 22010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // throwing the string at JSON.parse. 23010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (eventData[0] == '[') { 24010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis n = eventData.length; 252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (eventData[n - 1] == '\n') { 262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis eventData = eventData.substring(0, n - 1); 272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis n--; 282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (eventData[n - 1] == '\r') { 302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis eventData = eventData.substring(0, n - 1); 312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis n--; 322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 33010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (eventData[n - 1] == ',') 362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis eventData = eventData.substring(0, n - 1); 372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (eventData[n - 1] != ']') 382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis eventData = eventData + ']'; 39010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 41010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.events_ = JSON.parse(eventData); 42010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 43010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else { 44010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.events_ = eventData; 45010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 46010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 47010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Some trace_event implementations put the actual trace events 48010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // inside a container. E.g { ... , traceEvents: [ ] } 49010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // If we see that, just pull out the trace events. 502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (this.events_.traceEvents) { 51010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.events_ = this.events_.traceEvents; 522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (fieldName in this.events_) { 532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (fieldName == 'traceEvents') 542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.model_.metadata.push({name: fieldName, 562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis value: this.events_[fieldName]}); 572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 59010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 60010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Async events need to be processed durign finalizeEvents 61010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.allAsyncEvents_ = []; 62010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 63010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 64010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 65010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @return {boolean} Whether obj is a TraceEvent array. 66010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 67010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis TraceEventImporter.canImport = function(eventData) { 68010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // May be encoded JSON. But we dont want to parse it fully yet. 69010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Use a simple heuristic: 70010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // - eventData that starts with [ are probably trace_event 71010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // - eventData that starts with { are probably trace_event 72010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // May be encoded JSON. Treat files that start with { as importable by us. 73010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (typeof(eventData) === 'string' || eventData instanceof String) { 74010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return eventData[0] == '{' || eventData[0] == '['; 75010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 76010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 77010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Might just be an array of events 78010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (eventData instanceof Array && eventData.length && eventData[0].ph) 79010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return true; 80010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 81010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Might be an object with a traceEvents field in it. 82010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (eventData.traceEvents) 83010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return eventData.traceEvents instanceof Array && 84010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis eventData.traceEvents[0].ph; 85010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 86010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return false; 87010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }; 88010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 89010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis TraceEventImporter.prototype = { 90010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 91010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis __proto__: Object.prototype, 92010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 93010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 94010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Helper to process an 'async finish' event, which will close an open slice 95010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * on a TimelineAsyncSliceGroup object. 962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis processAsyncEvent: function(index, event) { 98010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var thread = this.model_.getOrCreateProcess(event.pid). 99010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis getOrCreateThread(event.tid); 100010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.allAsyncEvents_.push({ 101010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis event: event, 102010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis thread: thread}); 103010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 104010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 105010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 106010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Helper that creates and adds samples to a TimelineCounter object based on 107010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * 'C' phase events. 108010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 109010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis processCounterEvent: function(event) { 110010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var ctr_name; 111010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (event.id !== undefined) 112010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ctr_name = event.name + '[' + event.id + ']'; 113010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis else 114010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ctr_name = event.name; 115010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 116010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var ctr = this.model_.getOrCreateProcess(event.pid) 117010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis .getOrCreateCounter(event.cat, ctr_name); 118010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Initialize the counter's series fields if needed. 119010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (ctr.numSeries == 0) { 120010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis for (var seriesName in event.args) { 121010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ctr.seriesNames.push(seriesName); 122010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ctr.seriesColors.push( 123010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis tracing.getStringColorId(ctr.name + '.' + seriesName)); 124010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 125010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (ctr.numSeries == 0) { 126010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_.importErrors.push('Expected counter ' + event.name + 127010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ' to have at least one argument to use as a value.'); 128010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Drop the counter. 129010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis delete ctr.parent.counters[ctr.name]; 130010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return; 131010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 132010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 133010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 134010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Add the sample values. 135010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ctr.timestamps.push(event.ts / 1000); 136010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis for (var i = 0; i < ctr.numSeries; i++) { 137010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var seriesName = ctr.seriesNames[i]; 138010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (event.args[seriesName] === undefined) { 139010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ctr.samples.push(0); 140010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis continue; 141010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 142010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ctr.samples.push(event.args[seriesName]); 143010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 144010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 145010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 146010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 147010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Walks through the events_ list and outputs the structures discovered to 148010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * model_. 149010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 150010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis importEvents: function() { 151010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Walk through events 152010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var events = this.events_; 153010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Some events cannot be handled until we have done a first pass over the 154010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // data set. So, accumulate them into a temporary data structure. 155010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var second_pass_events = []; 156010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis for (var eI = 0; eI < events.length; eI++) { 157010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var event = events[eI]; 158010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (event.ph == 'B') { 1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var thread = this.model_.getOrCreateProcess(event.pid) 1602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis .getOrCreateThread(event.tid); 1612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!thread.isTimestampValidForBeginOrEnd(event.ts / 1000)) { 1622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.model_.importErrors.push( 1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 'Timestamps are moving backward.'); 1642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 1652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis thread.beginSlice(event.cat, event.name, event.ts / 1000, event.args); 167010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else if (event.ph == 'E') { 1682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var thread = this.model_.getOrCreateProcess(event.pid) 1692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis .getOrCreateThread(event.tid); 1702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!thread.isTimestampValidForBeginOrEnd(event.ts / 1000)) { 1712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.model_.importErrors.push( 1722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 'Timestamps are moving backward.'); 1732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 1742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!thread.openSliceCount) { 1762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.model_.importErrors.push( 1772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 'E phase event without a matching B phase event.'); 1782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 1792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var slice = thread.endSlice(event.ts / 1000); 1822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var arg in event.args) { 1832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (slice.args[arg] !== undefined) { 1842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.model_.importErrors.push( 1852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 'Both the B and E phases of ' + slice.name + 1862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 'provided values for argument ' + arg + '. ' + 1872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 'The value of the E phase event will be used.'); 1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slice.args[arg] = event.args[arg]; 1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 192010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else if (event.ph == 'S') { 1932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.processAsyncEvent(eI, event); 194010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else if (event.ph == 'F') { 1952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.processAsyncEvent(eI, event); 196010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else if (event.ph == 'T') { 1972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.processAsyncEvent(eI, event); 198010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else if (event.ph == 'I') { 199010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Treat an Instant event as a duration 0 slice. 200010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // TimelineSliceTrack's redraw() knows how to handle this. 2012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var thread = this.model_.getOrCreateProcess(event.pid) 2022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis .getOrCreateThread(event.tid); 2032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis thread.beginSlice(event.cat, event.name, event.ts / 1000, event.args); 2042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis thread.endSlice(event.ts / 1000); 205010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else if (event.ph == 'C') { 206010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.processCounterEvent(event); 207010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else if (event.ph == 'M') { 208010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (event.name == 'thread_name') { 209010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var thread = this.model_.getOrCreateProcess(event.pid) 210010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis .getOrCreateThread(event.tid); 211010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis thread.name = event.args.name; 212010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else { 213010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_.importErrors.push( 214010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 'Unrecognized metadata name: ' + event.name); 215010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 21657a636a44b62b6d8aece3b27aee6ddac2c8c4d8bErik Gilling } else if (event.ph == 's') { 21757a636a44b62b6d8aece3b27aee6ddac2c8c4d8bErik Gilling // NB: toss until there's proper support 21857a636a44b62b6d8aece3b27aee6ddac2c8c4d8bErik Gilling } else if (event.ph == 't') { 21957a636a44b62b6d8aece3b27aee6ddac2c8c4d8bErik Gilling // NB: toss until there's proper support 22057a636a44b62b6d8aece3b27aee6ddac2c8c4d8bErik Gilling } else if (event.ph == 'f') { 22157a636a44b62b6d8aece3b27aee6ddac2c8c4d8bErik Gilling // NB: toss until there's proper support 222010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else { 223010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_.importErrors.push( 224010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 'Unrecognized event phase: ' + event.ph + 225010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis '(' + event.name + ')'); 226010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 227010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 228010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 229010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 230010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 231010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Called by the TimelineModel after all other importers have imported their 2322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * events. 233010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 234010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis finalizeImport: function() { 2352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.createAsyncSlices_(); 2362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 2372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis createAsyncSlices_: function() { 239010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (this.allAsyncEvents_.length == 0) 240010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return; 241010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 242010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.allAsyncEvents_.sort(function(x, y) { 243010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return x.event.ts - y.event.ts; 244010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }); 245010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 246010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var asyncEventStatesByNameThenID = {}; 247010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 248010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var allAsyncEvents = this.allAsyncEvents_; 249010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis for (var i = 0; i < allAsyncEvents.length; i++) { 250010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var asyncEventState = allAsyncEvents[i]; 251010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 252010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var event = asyncEventState.event; 253010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var name = event.name; 254010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (name === undefined) { 255010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_.importErrors.push( 256010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 'Async events (ph: S, T or F) require an name parameter.'); 257010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis continue; 258010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 259010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 260010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var id = event.id; 261010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (id === undefined) { 262010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_.importErrors.push( 263010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 'Async events (ph: S, T or F) require an id parameter.'); 264010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis continue; 265010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 266010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 267010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // TODO(simonjam): Add a synchronous tick on the appropriate thread. 268010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 269010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (event.ph == 'S') { 270010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (asyncEventStatesByNameThenID[name] === undefined) 271010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis asyncEventStatesByNameThenID[name] = {}; 272010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (asyncEventStatesByNameThenID[name][id]) { 273010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_.importErrors.push( 2742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 'At ' + event.ts + ', a slice of the same id ' + id + 275010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ' was alrady open.'); 276010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis continue; 277010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 278010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis asyncEventStatesByNameThenID[name][id] = []; 279010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis asyncEventStatesByNameThenID[name][id].push(asyncEventState); 280010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else { 281010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (asyncEventStatesByNameThenID[name] === undefined) { 282010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_.importErrors.push( 283010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 'At ' + event.ts + ', no slice named ' + name + 284010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ' was open.'); 285010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis continue; 286010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 287010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (asyncEventStatesByNameThenID[name][id] === undefined) { 288010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.model_.importErrors.push( 289010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 'At ' + event.ts + ', no slice named ' + name + 290010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis ' with id=' + id + ' was open.'); 291010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis continue; 292010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 293010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var events = asyncEventStatesByNameThenID[name][id]; 294010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis events.push(asyncEventState); 295010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 296010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (event.ph == 'F') { 297010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Create a slice from start to end. 298010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var slice = new tracing.TimelineAsyncSlice( 2992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis events[0].event.cat, 300010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis name, 301010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis tracing.getStringColorId(name), 302010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis events[0].event.ts / 1000); 303010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 304010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis slice.duration = (event.ts / 1000) - (events[0].event.ts / 1000); 305010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 306010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis slice.startThread = events[0].thread; 307010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis slice.endThread = asyncEventState.thread; 308010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis slice.id = id; 309010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis slice.args = events[0].event.args; 310010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis slice.subSlices = []; 311010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 312010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Create subSlices for each step. 313010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis for (var j = 1; j < events.length; ++j) { 314010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var subName = name; 315010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (events[j - 1].event.ph == 'T') 316010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis subName = name + ':' + events[j - 1].event.args.step; 317010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var subSlice = new tracing.TimelineAsyncSlice( 3182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis events[0].event.cat, 319010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis subName, 320010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis tracing.getStringColorId(name + j), 321010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis events[j - 1].event.ts / 1000); 322010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 323010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis subSlice.duration = 324010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis (events[j].event.ts / 1000) - (events[j - 1].event.ts / 1000); 325010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 326010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis subSlice.startThread = events[j - 1].thread; 327010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis subSlice.endThread = events[j].thread; 328010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis subSlice.id = id; 329010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis subSlice.args = events[j - 1].event.args; 330010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 331010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis slice.subSlices.push(subSlice); 332010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 333010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 334010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // The args for the finish event go in the last subSlice. 335010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var lastSlice = slice.subSlices[slice.subSlices.length - 1]; 336010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis for (var arg in event.args) 337010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis lastSlice.args[arg] = event.args[arg]; 338010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 339010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Add |slice| to the start-thread's asyncSlices. 340010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis slice.startThread.asyncSlices.push(slice); 341010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis delete asyncEventStatesByNameThenID[name][id]; 342010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 343010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 344010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 345010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 346010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }; 347010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 348010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis tracing.TimelineModel.registerImporter(TraceEventImporter); 349010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 350010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return { 351010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis TraceEventImporter: TraceEventImporter 352010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }; 353010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis}); 354