diff options
Diffstat (limited to 'chromium/third_party/catapult/tracing/tracing/extras/importer')
74 files changed, 0 insertions, 22409 deletions
diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/android/event_log_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/android/event_log_importer.html deleted file mode 100644 index ff2e22e16a2..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/android/event_log_importer.html +++ /dev/null @@ -1,321 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/importer/importer.html"> -<link rel="import" href="/tracing/importer/simple_line_reader.html"> -<link rel="import" href="/tracing/model/activity.html"> -<link rel="import" href="/tracing/model/model.html"> - - -<script> -/** - * @fileoverview Imports android event log data into the trace model. - * Android event log data contains information about activities that - * are launched/paused, processes that are started, memory usage, etc. - * - * The current implementation only parses activity events, with the goal of - * determining which Activity is running in the foreground for a process. - * - * This importer assumes the events arrive as a string. The unit tests provide - * examples of the trace format. - */ -'use strict'; - -tr.exportTo('tr.e.importer.android', function() { - var Importer = tr.importer.Importer; - - var ACTIVITY_STATE = { - NONE: 'none', - CREATED: 'created', - STARTED: 'started', - RESUMED: 'resumed', - PAUSED: 'paused', - STOPPED: 'stopped', - DESTROYED: 'destroyed' - }; - - var activityMap = {}; - - /** - * Imports android event log data (adb logcat -b events) - * @constructor - */ - function EventLogImporter(model, events) { - this.model_ = model; - this.events_ = events; - this.importPriority = 3; - } - - // Generic format of event log entries. - // Sample event log entry that this matches (split over 2 lines): - // 08-11 13:12:31.405 880 2645 I am_focused_activity: [0,com.google.android.googlequicksearchbox/com.google.android.launcher.GEL] // @suppress longLineCheck - var eventLogActivityRE = new RegExp( - '(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)' + - '\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*' + - '(am_\\w+)\\s*:(.*)'); - - // 08-28 03:58:21.834 888 3177 I am_create_activity: [0,5972200,30,com.nxp.taginfolite/.activities.MainView,android.intent.action.MAIN,NULL,NULL,270532608] // @suppress longLineCheck - // Store the name of the created activity only - var amCreateRE = new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]'); - - // 07-22 12:22:19.504 920 2504 I am_focused_activity: [0,com.android.systemui/.recents.RecentsActivity] // @suppress longLineCheck - //Store the name of the focused activity only - var amFocusedRE = new RegExp('\s*\\[\\d+,(.*)\\]'); - - // 07-21 19:56:12.315 920 2261 I am_proc_start: [0,19942,10062,com.google.android.talk,broadcast,com.google.android.talk/com.google.android.apps.hangouts.realtimechat.RealTimeChatService$AlarmReceiver] // @suppress longLineCheck - // We care about proc starts on behalf of activities, and store the activity - var amProcStartRE = new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]'); - - // 07-22 12:21:43.490 2893 2893 I am_on_resume_called: [0,com.google.android.launcher.GEL] // @suppress longLineCheck - // Store the activity name only - var amOnResumeRE = new RegExp('\s*\\[\\d+,(.*)\\]'); - - // 07-22 12:22:19.545 2893 2893 I am_on_paused_called: [0,com.google.android.launcher.GEL] // @suppress longLineCheck - // Store the activity name only - var amOnPauseRE = new RegExp('\s*\\[\\d+,(.*)\\]'); - - // 08-28 03:51:54.456 888 907 I am_activity_launch_time: [0,185307115,com.google.android.googlequicksearchbox/com.google.android.launcher.GEL,1174,1174] // @suppress longLineCheck - // Store the activity name and launch times - var amLaunchTimeRE = new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)'); - - // 08-28 03:58:15.854 888 902 I am_destroy_activity: [0,203516597,29,com.android.chrome/com.google.android.apps.chrome.Main,finish-idle] // @suppress longLineCheck - // Store the activity name only - var amDestroyRE = new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]'); - - /** - * @return {boolean} True when events is an android event log array. - */ - EventLogImporter.canImport = function(events) { - if (!(typeof(events) === 'string' || events instanceof String)) - return false; - - // Prevent the importer from matching this file in vulcanized traces. - if (/^<!DOCTYPE html>/.test(events)) - return false; - - return eventLogActivityRE.test(events); - }; - - EventLogImporter.prototype = { - __proto__: Importer.prototype, - - get importerName() { - return 'EventLogImporter'; - }, - - get model() { - return this.model_; - }, - - /** - * @return {string} the full activity name (including package) from - * a component - */ - getFullActivityName: function(component) { - var componentSplit = component.split('/'); - if (componentSplit[1].startsWith('.')) - return componentSplit[0] + componentSplit[1]; - - return componentSplit[1]; - }, - - /** - * @return {string} the process name of a component - */ - getProcName: function(component) { - var componentSplit = component.split('/'); - return componentSplit[0]; - }, - - findOrCreateActivity: function(activityName) { - if (activityName in activityMap) - return activityMap[activityName]; - var activity = { - state: ACTIVITY_STATE.NONE, - name: activityName - }; - activityMap[activityName] = activity; - return activity; - }, - - deleteActivity: function(activityName) { - delete activityMap[activityName]; - }, - - handleCreateActivity: function(ts, activityName) { - var activity = this.findOrCreateActivity(activityName); - activity.state = ACTIVITY_STATE.CREATED; - activity.createdTs = ts; - }, - - handleFocusActivity: function(ts, procName, activityName) { - var activity = this.findOrCreateActivity(activityName); - activity.lastFocusedTs = ts; - }, - - handleProcStartForActivity: function(ts, activityName) { - var activity = this.findOrCreateActivity(activityName); - activity.procStartTs = ts; - }, - - handleOnResumeCalled: function(ts, pid, activityName) { - var activity = this.findOrCreateActivity(activityName); - activity.state = ACTIVITY_STATE.RESUMED; - activity.lastResumeTs = ts; - // on_resume_called shows the actual PID; use this - // to link the activity up with a process later - activity.pid = pid; - }, - - handleOnPauseCalled: function(ts, activityName) { - var activity = this.findOrCreateActivity(activityName); - activity.state = ACTIVITY_STATE.PAUSED; - activity.lastPauseTs = ts; - // Create a new AndroidActivity representing the foreground state, - // but only if the pause happened within the model bounds - if (ts > this.model_.bounds.min && ts < this.model_.bounds.max) - this.addActivityToProcess(activity); - }, - - handleLaunchTime: function(ts, activityName, launchTime) { - var activity = this.findOrCreateActivity(activityName); - activity.launchTime = launchTime; - }, - - handleDestroyActivity: function(ts, activityName) { - this.deleteActivity(activityName); - }, - - addActivityToProcess: function(activity) { - if (activity.pid === undefined) - return; - var process = this.model_.getOrCreateProcess(activity.pid); - // The range of the activity is the time from resume to time - // of pause; limit the start time to the beginning of the model - var range = tr.b.Range.fromExplicitRange( - Math.max(this.model_.bounds.min, activity.lastResumeTs), - activity.lastPauseTs); - var newActivity = new tr.model.Activity(activity.name, - 'Android Activity', range, - {created: activity.createdTs, - procstart: activity.procStartTs, - lastfocus: activity.lastFocusedTs}); - process.activities.push(newActivity); - }, - - parseAmLine_: function(line) { - var match = eventLogActivityRE.exec(line); - if (!match) - return; - - // Possible activity life-cycles: - // 1) Launch from scratch: - // - am_create_activity - // - am_focused_activity - // - am_proc_start - // - am_proc_bound - // - am_restart_activity - // - am_on_resume_called - // 2) Re-open existing activity - // - am_focused_activity - // - am_on_resume_called - - // HACK: event log date format is "MM-DD" and doesn't contain the year; - // to figure out the year, take the min bound of the model, convert - // to real-time and use that as the year. - // The Android event log will eventually contain the year once this - // CL is in a release: - // https://android-review.googlesource.com/#/c/168900 - var first_realtime_ts = this.model_.bounds.min - - this.model_.realtime_to_monotonic_offset_ms; - var year = new Date(first_realtime_ts).getFullYear(); - var ts = match[1].substring(0, 5) + '-' + year + ' ' + - match[1].substring(5, match[1].length); - - var monotonic_ts = Date.parse(ts) + - this.model_.realtime_to_monotonic_offset_ms; - - var pid = match[2]; - var action = match[5]; - var data = match[6]; - - if (action === 'am_create_activity') { - match = amCreateRE.exec(data); - if (match && match.length >= 2) { - this.handleCreateActivity(monotonic_ts, - this.getFullActivityName(match[1])); - } - } else if (action === 'am_focused_activity') { - match = amFocusedRE.exec(data); - if (match && match.length >= 2) { - this.handleFocusActivity(monotonic_ts, - this.getProcName(match[1]), this.getFullActivityName(match[1])); - } - } else if (action === 'am_proc_start') { - match = amProcStartRE.exec(data); - if (match && match.length >= 2) { - this.handleProcStartForActivity(monotonic_ts, - this.getFullActivityName(match[1])); - } - } else if (action === 'am_on_resume_called') { - match = amOnResumeRE.exec(data); - if (match && match.length >= 2) - this.handleOnResumeCalled(monotonic_ts, pid, match[1]); - } else if (action === 'am_on_paused_called') { - match = amOnPauseRE.exec(data); - if (match && match.length >= 2) - this.handleOnPauseCalled(monotonic_ts, match[1]); - } else if (action === 'am_activity_launch_time') { - match = amLaunchTimeRE.exec(data); - this.handleLaunchTime(monotonic_ts, - this.getFullActivityName(match[1]), match[2]); - } else if (action === 'am_destroy_activity') { - match = amDestroyRE.exec(data); - if (match && match.length == 2) { - this.handleDestroyActivity(monotonic_ts, - this.getFullActivityName(match[1])); - } - } - }, - - importEvents: function() { - // Check if we have a mapping from real-time to CLOCK_MONOTONIC - if (isNaN(this.model_.realtime_to_monotonic_offset_ms)) { - this.model_.importWarning({ - type: 'eveng_log_clock_sync', - message: 'Need a trace_event_clock_sync to map realtime to import.' - }); - return; - } - // Since the event log typically spans a much larger timeframe - // than the ftrace data, we want to calculate the bounds of the existing - // model, and dump all event log data outside of those bounds - this.model_.updateBounds(); - - var lines = this.events_.split('\n'); - lines.forEach(this.parseAmLine_, this); - - // Iterate over all created activities that are not destroyed yet - for (var activityName in activityMap) { - var activity = activityMap[activityName]; - // If we're still in the foreground, store the activity anyway - if (activity.state == ACTIVITY_STATE.RESUMED) { - // Set the pause timestamp to the end of the model bounds - activity.lastPauseTs = this.model_.bounds.max; - this.addActivityToProcess(activity); - } - } - } - }; - - Importer.register(EventLogImporter); - - return { - EventLogImporter: EventLogImporter - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/battor_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/battor_importer.html deleted file mode 100644 index 381bf0f8687..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/battor_importer.html +++ /dev/null @@ -1,181 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/importer/importer.html"> -<link rel="import" href="/tracing/model/model.html"> -<link rel="import" href="/tracing/model/power_series.html"> - -<script> -/** - * @fileoverview Imports text files in the BattOr format into the - * Model. This format is output by the battor_agent executable and library. - * - * This importer assumes the events arrive as a string. The unit tests provide - * examples of the trace format. - */ -'use strict'; - -tr.exportTo('tr.e.importer.battor', function() { - /** - * Imports a BattOr power trace into a specified model. - * @constructor - */ - function BattorImporter(model, events) { - this.importPriority = 3; // runs after the linux_perf importer - this.model_ = model; - this.samples_ = this.linesToSamples_(events.split('\n')); - } - - var battorDataLineRE = new RegExp( - '^(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)' + - '(?:\\s+<(\\S+)>)?$' - ); - var battorHeaderLineRE = /^# BattOr/; - - /** - * Guesses whether the provided events is a BattOr string. - * Looks for the magic string "# BattOr" at the start of the file, - * - * @return {boolean} True when events is a BattOr array. - */ - BattorImporter.canImport = function(events) { - if (!(typeof(events) === 'string' || events instanceof String)) - return false; - - return battorHeaderLineRE.test(events); - }; - - BattorImporter.prototype = { - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'BattorImporter'; - }, - - get model() { - return this.model_; - }, - - /** - * Imports clock sync markers in this.events_ into model_. - */ - importClockSyncMarkers: function() { - for (var i = 0; i < this.samples_.length; i++) { - var sample = this.samples_[i]; - if (sample.syncId) { - this.model_.clockSyncManager.addClockSyncMarker( - tr.model.ClockDomainId.BATTOR, sample.syncId, sample.ts); - } - } - }, - - /** - * Imports the data in this.events_ into model_. - */ - importEvents: function() { - if (this.model_.device.powerSeries) { - this.model_.importWarning({ - type: 'import_error', - message: 'Power counter exists, can not import BattOr power trace.' - }); - return; - } - - var modelTimeTransformer = - this.model_.clockSyncManager.getModelTimeTransformer( - tr.model.ClockDomainId.BATTOR); - - var powerSeries = this.model_.device.powerSeries = - new tr.model.PowerSeries(this.model_.device); - for (var i = 0; i < this.samples_.length; i++) { - var sample = this.samples_[i]; - powerSeries.addPowerSample( - modelTimeTransformer(sample.ts), sample.power); - } - }, - - /** - * Given an array of strings that make up the lines of a BattOr trace, - * returns an array of samples contained within those lines. - */ - linesToSamples_: function(lines) { - var samples = []; - - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - line = line.trim(); - - if (line.length === 0) - continue; - - if (line.startsWith('#')) - continue; - - // Parse power sample. - var groups = battorDataLineRE.exec(line); - if (!groups) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Unrecognized line in BattOr trace: ' + line - }); - continue; - } - - var ts = parseFloat(groups[1]); - var voltage = parseFloat(groups[2]) / 1000; - var current = parseFloat(groups[3]) / 1000; - var syncId = groups[4]; - - if (voltage < 0 || current < 0) { - this.model_.importWarning({ - type: 'parse_error', - message: 'The following line in the BattOr trace has a negative ' + - 'voltage or current, neither of which are allowed: ' + line + - '. A common cause of this is that the device is charging ' + - 'while the trace is being recorded.' - }); - continue; - } - - samples.push(new Sample(ts, voltage, current, syncId)); - } - - return samples; - } - }; - - /** - * A sample recorded by a BattOr. - * - * @param {number} ts The timestamp (in milliseconds) of the sample. - * @param {number} voltage The voltage (in volts) at the specified time. - * @param {number} current The current (in amps) at the specified time. - * @param {string=} opt_syncId The sync ID of the sync that happened at this - * sample. - * - * @constructor - */ - function Sample(ts, voltage, current, opt_syncId) { - this.ts = ts; - this.voltage = voltage; - this.current = current; - this.syncId = opt_syncId; - } - - Sample.prototype = { - /** Returns the instantaneous power consumption (in Watts). */ - get power() { return this.voltage * this.current; } - }; - - tr.importer.Importer.register(BattorImporter); - - return { - BattorImporter: BattorImporter, - }; -}); - -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/battor_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/battor_importer_test.html deleted file mode 100644 index ac8c125dbc6..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/battor_importer_test.html +++ /dev/null @@ -1,85 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/battor_importer.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> -<link rel="import" href="/tracing/extras/importer/trace_event_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - - var CHROMIUM_EVENTS = [ - { - name: 'a', args: {}, pid: 52, ts: 0, - cat: 'foo', tid: 53, ph: 'B' - }, - { - pid: 94936, tid: 5643, ts: 15000, - ph: 'c', cat: '__metadata', name: 'clock_sync', - args: {sync_id: 'ABCDEF-01234-5678-0A1B2C3D', issue_ts: 10000}, - tts: 16496444 - } - ]; - - var BATTOR_LINES = [ - '# BattOr', - '# voltage_range [0.0, 6144.0] mV', - '# current_range [0.0, 2275.5] mA', - '# sample_rate 2000 Hz, gain 5.0x', - '0.000000 0.000000 4000.000000', - '0.500000 0.000000 4000.000000', - '1.000000 0.000000 4000.000000', - '1.500000 0.000000 4000.000000', - '2.000000 1.000000 4000.000000' - ]; - - test('canImport', function() { - assert.isFalse(tr.e.importer.battor.BattorImporter.canImport('string')); - assert.isFalse(tr.e.importer.battor.BattorImporter.canImport([])); - assert.isTrue(tr.e.importer.battor.BattorImporter.canImport( - BATTOR_LINES.join('\n'))); - }); - - test('importExplicitClockSync', function() { - // Add a BattOr sample with an explicit clock sync. - var battorLinesWithExplicitSync = BATTOR_LINES.slice(); - battorLinesWithExplicitSync.push( - '2.500000 1.000000 4000.000000 <ABCDEF-01234-5678-0A1B2C3D>'); - - var m = tr.c.TestUtils.newModelWithEvents( - [CHROMIUM_EVENTS, battorLinesWithExplicitSync.join('\n')]); - - // Check to see if power samples were imported successfully. - assert.isDefined(m.device.powerSeries); - - assert.strictEqual(m.device.powerSeries.samples[0].start, 7.5); - assert.strictEqual(m.device.powerSeries.samples[5].start, 10.0); - }); - - test('explicitClockSyncWithoutSyncMarkers', function() { - // Create an empty model. - var m = new tr.Model(); - var io = new tr.importer.ImportOptions(); - io.showImportWarnings = false; - m.importOptions = io; - - // Add a BattOr sample with an explicit clock sync. - var battorLinesWithExplicitSync = BATTOR_LINES.slice(); - battorLinesWithExplicitSync.push( - '2.500000 1.000000 4000.000000 <ABCDEF-01234-5678-0A1B2C3D>'); - - var m = tr.c.TestUtils.newModelWithEvents( - [battorLinesWithExplicitSync.join('\n')]); - - assert.strictEqual(m.device.powerSeries.samples[0].start, 0); - assert.strictEqual(m.device.powerSeries.samples[5].start, 2.5); - }); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/ddms_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/ddms_importer.html deleted file mode 100644 index fd760c7c7f4..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/ddms_importer.html +++ /dev/null @@ -1,221 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/extras/importer/jszip.html"> -<link rel="import" href="/tracing/importer/importer.html"> -<link rel="import" href="/tracing/model/model.html"> - -<script> -/** - * @fileoverview Blah. - */ -'use strict'; - -tr.exportTo('tr.e.importer.ddms', function() { - var kPid = 0; - var kCategory = 'java'; - var kMethodLutEndMarker = '\n*end\n'; - var kThreadsStart = '\n*threads\n'; - var kMethodsStart = '\n*methods\n'; - - var kTraceMethodEnter = 0x00; // method entry - var kTraceMethodExit = 0x01; // method exit - var kTraceUnroll = 0x02; // method exited by exception unrolling - // 0x03 currently unused - var kTraceMethodActionMask = 0x03; // two bits - - var kTraceHeaderLength = 32; - var kTraceMagicValue = 0x574f4c53; - var kTraceVersionSingleClock = 2; - var kTraceVersionDualClock = 3; - var kTraceRecordSizeSingleClock = 10; // using v2 - var kTraceRecordSizeDualClock = 14; // using v3 with two timestamps - - function Reader(string_payload) { - this.position_ = 0; - this.data_ = JSZip.utils.transformTo('uint8array', string_payload); - } - - Reader.prototype = { - __proto__: Object.prototype, - - uint8: function() { - var result = this.data_[this.position_]; - this.position_ += 1; - return result; - }, - - uint16: function() { - var result = 0; - result += this.uint8(); - result += this.uint8() << 8; - return result; - }, - - uint32: function() { - var result = 0; - result += this.uint8(); - result += this.uint8() << 8; - result += this.uint8() << 16; - result += this.uint8() << 24; - return result; - }, - - uint64: function() { - // Javascript isn't able to manage 64-bit numeric values. - var low = this.uint32(); - var high = this.uint32(); - var low_str = ('0000000' + low.toString(16)).substr(-8); - var high_str = ('0000000' + high.toString(16)).substr(-8); - var result = high_str + low_str; - return result; - }, - - seekTo: function(position) { - this.position_ = position; - }, - - hasMore: function() { - return this.position_ < this.data_.length; - } - }; - - /** - * Imports DDMS method tracing events into a specified model. - * @constructor - */ - function DdmsImporter(model, data) { - this.importPriority = 3; - this.model_ = model; - this.data_ = data; - } - - /** - * Guesses whether the provided events is from a DDMS method trace. - * @return {boolean} True when events is a DDMS method trace. - */ - DdmsImporter.canImport = function(data) { - if (typeof(data) === 'string' || data instanceof String) { - var header = data.slice(0, 1000); - return header.startsWith('*version\n') && - header.indexOf('\nvm=') >= 0 && - header.indexOf(kThreadsStart) >= 0; - } - /* key bit */ - return false; - }; - - DdmsImporter.prototype = { - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'DdmsImporter'; - }, - - get model() { - return this.model_; - }, - - /** - * Imports the data in this.data_ into this.model_. - */ - importEvents: function() { - var divider = this.data_.indexOf(kMethodLutEndMarker) + - kMethodLutEndMarker.length; - this.metadata_ = this.data_.slice(0, divider); - this.methods_ = {}; - this.parseThreads(); - this.parseMethods(); - - var traceReader = new Reader(this.data_.slice(divider)); - var magic = traceReader.uint32(); - if (magic != kTraceMagicValue) { - throw Error('Failed to match magic value'); - } - this.version_ = traceReader.uint16(); - if (this.version_ != kTraceVersionDualClock) { - throw Error('Unknown version'); - } - var dataOffest = traceReader.uint16(); - var startDateTime = traceReader.uint64(); - var recordSize = traceReader.uint16(); - - traceReader.seekTo(dataOffest); - - while (traceReader.hasMore()) { - this.parseTraceEntry(traceReader); - } - }, - - parseTraceEntry: function(reader) { - var tid = reader.uint16(); - var methodPacked = reader.uint32(); - var cpuSinceStart = reader.uint32(); - var wallClockSinceStart = reader.uint32(); - var method = methodPacked & ~kTraceMethodActionMask; - var action = methodPacked & kTraceMethodActionMask; - var thread = this.getTid(tid); - method = this.getMethodName(method); - if (action == kTraceMethodEnter) { - thread.sliceGroup.beginSlice(kCategory, method, wallClockSinceStart, - undefined, cpuSinceStart); - } else if (thread.sliceGroup.openSliceCount) { - thread.sliceGroup.endSlice(wallClockSinceStart, cpuSinceStart); - } - }, - - parseThreads: function() { - var threads = this.metadata_.slice(this.metadata_.indexOf(kThreadsStart) + - kThreadsStart.length); - threads = threads.slice(0, threads.indexOf('\n*')); - threads = threads.split('\n'); - threads.forEach(this.parseThread.bind(this)); - }, - - parseThread: function(thread_line) { - var tid = thread_line.slice(0, thread_line.indexOf('\t')); - var thread = this.getTid(parseInt(tid)); - thread.name = thread_line.slice(thread_line.indexOf('\t') + 1); - }, - - getTid: function(tid) { - return this.model_.getOrCreateProcess(kPid) - .getOrCreateThread(tid); - }, - - parseMethods: function() { - var methods = this.metadata_.slice(this.metadata_.indexOf(kMethodsStart) + - kMethodsStart.length); - methods = methods.slice(0, methods.indexOf('\n*')); - methods = methods.split('\n'); - methods.forEach(this.parseMethod.bind(this)); - }, - - parseMethod: function(method_line) { - var data = method_line.split('\t'); - var methodId = parseInt(data[0]); - var methodName = data[1] + '.' + data[2] + data[3]; - this.addMethod(methodId, methodName); - }, - - addMethod: function(methodId, methodName) { - this.methods_[methodId] = methodName; - }, - - getMethodName: function(methodId) { - return this.methods_[methodId]; - } - }; - - // Register the DdmsImporter to the Importer. - tr.importer.Importer.register(DdmsImporter); - - return { - DdmsImporter: DdmsImporter - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/ddms_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/ddms_importer_test.html deleted file mode 100644 index 997556b7273..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/ddms_importer_test.html +++ /dev/null @@ -1,188 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/base/base64.html"> -<link rel="import" href="/tracing/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/ddms_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - var Base64 = tr.b.Base64; - - test('canImport', function() { - assert.isFalse(tr.e.importer.ddms.DdmsImporter.canImport('string')); - assert.isFalse(tr.e.importer.ddms.DdmsImporter.canImport([])); - assert.isTrue(tr.e.importer.ddms.DdmsImporter.canImport(TEST_DATA)); - }); - - test('parseThreads', function() { - var m = tr.c.TestUtils.newModelWithEvents(TEST_DATA, { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 2); - threads = m.findAllThreadsNamed('main'); - assert.equal(threads.length, 1); - var thread = threads[0]; - assert.equal(thread.tid, 2703); - }); - - test('parseMethods', function() { - var m = tr.c.TestUtils.newModelWithEvents(TEST_DATA, { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var threads = m.findAllThreadsNamed('Binder_1'); - assert.equal(threads.length, 1); - var thread = threads[0]; - assert.equal(thread.sliceGroup.length, 22); - assert.equal('android.os.Binder.execTransact(IJJI)Z', - thread.sliceGroup.slices[0].title); - }); - - var TEST_DATA = Base64.atob( - 'KnZlcnNpb24KMwpkYXRhLWZpbGUtb3ZlcmZsb3c9ZmFsc2UKY2' + - 'xvY2s9ZHVhbAplbGFwc2VkLXRpbWUtdXNlYz02MzMwNzc5Cm51' + - 'bS1tZXRob2QtY2FsbHM9NzYKY2xvY2stY2FsbC1vdmVyaGVhZC' + - '1uc2VjPTMzNDMKdm09YXJ0Cip0aHJlYWRzCjI3MDMJbWFpbgoy' + - 'NzEwCUhlYXAgdGhyZWFkIHBvb2wgd29ya2VyIHRocmVhZCAxCj' + - 'I3MDkJSGVhcCB0aHJlYWQgcG9vbCB3b3JrZXIgdGhyZWFkIDAK' + - 'MjcxMQlIZWFwIHRocmVhZCBwb29sIHdvcmtlciB0aHJlYWQgMg' + - 'oyNzEyCVNpZ25hbCBDYXRjaGVyCjI3MTMJSkRXUAoyNzE0CVJl' + - 'ZmVyZW5jZVF1ZXVlRGFlbW9uCjI3MTUJRmluYWxpemVyRGFlbW' + - '9uCjI3MTYJRmluYWxpemVyV2F0Y2hkb2dEYWVtb24KMjcxNwlI' + - 'ZWFwVHJpbW1lckRhZW1vbgoyNzE4CUdDRGFlbW9uCjI3MTkJQm' + - 'luZGVyXzEKMjcyMAlCaW5kZXJfMgoyNzI3CVJlbmRlclRocmVh' + - 'ZAoyNzI4CUFzeW5jVGFzayAjMQoyNzI5CUFzeW5jVGFzayAjMg' + - 'oyNzMwCUJpbmRlcl8zCjExNTk4CWh3dWlUYXNrMQoxMTU5OQlo' + - 'd3VpVGFzazIKMTE2MDAJQXN5bmNUYXNrICMzCjExNjAxCUFzeW' + - '5jVGFzayAjNAoxMTY3MwlBc3luY1Rhc2sgIzUKKm1ldGhvZHMK' + - 'MHg3MGZiNzc1OAlkYWx2aWsuc3lzdGVtLkNsb3NlR3VhcmQJY2' + - 'xvc2UJKClWCUNsb3NlR3VhcmQuamF2YQoweDcwZmI4NDE4CWRh' + - 'bHZpay5zeXN0ZW0uVk1EZWJ1ZwlzdGFydE1ldGhvZFRyYWNpbm' + - 'cJKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2lvL0ZpbGVEZXNj' + - 'cmlwdG9yO0lJWkkpVglWTURlYnVnLmphdmEKMHg3MGZlYTcyOA' + - 'lqYXZhLnV0aWwuQXJyYXlMaXN0CXNpemUJKClJCUFycmF5TGlz' + - 'dC5qYXZhCjB4NzEwMTNmYTgJbGliY29yZS5pby5CbG9ja0d1YX' + - 'JkT3MJY2xvc2UJKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yOylW' + - 'CUJsb2NrR3VhcmRPcy5qYXZhCjB4NzEwNTc3NDgJYW5kcm9pZC' + - '5vcy5CaW5kZXIJZXhlY1RyYW5zYWN0CShJSkpJKVoJQmluZGVy' + - 'LmphdmEKMHg3MTA3MTdlOAlhbmRyb2lkLmFwcC5BY3Rpdml0eV' + - 'RocmVhZCRBcHBsaWNhdGlvblRocmVhZAlwcm9maWxlckNvbnRy' + - 'b2wJKFpMYW5kcm9pZC9hcHAvUHJvZmlsZXJJbmZvO0kpVglBY3' + - 'Rpdml0eVRocmVhZC5qYXZhCjB4NzEwNzJhNDgJYW5kcm9pZC5h' + - 'cHAuQXBwbGljYXRpb25UaHJlYWROYXRpdmUJb25UcmFuc2FjdA' + - 'koSUxhbmRyb2lkL29zL1BhcmNlbDtMYW5kcm9pZC9vcy9QYXJj' + - 'ZWw7SSlaCUFwcGxpY2F0aW9uVGhyZWFkTmF0aXZlLmphdmEKMH' + - 'g3MTA3MmYyOAlhbmRyb2lkLm9zLkhhbmRsZXIJZW5xdWV1ZU1l' + - 'c3NhZ2UJKExhbmRyb2lkL29zL01lc3NhZ2VRdWV1ZTtMYW5kcm' + - '9pZC9vcy9NZXNzYWdlO0opWglIYW5kbGVyLmphdmEKMHg3MTA3' + - 'MmZlOAlhbmRyb2lkLm9zLkhhbmRsZXIJZGlzcGF0Y2hNZXNzYW' + - 'dlCShMYW5kcm9pZC9vcy9NZXNzYWdlOylWCUhhbmRsZXIuamF2' + - 'YQoweDcxMDczNTI4CWFuZHJvaWQub3MuSGFuZGxlcglzZW5kTW' + - 'Vzc2FnZQkoTGFuZHJvaWQvb3MvTWVzc2FnZTspWglIYW5kbGVy' + - 'LmphdmEKMHg3MTA3MzU4OAlhbmRyb2lkLm9zLkhhbmRsZXIJc2' + - 'VuZE1lc3NhZ2VBdFRpbWUJKExhbmRyb2lkL29zL01lc3NhZ2U7' + - 'SilaCUhhbmRsZXIuamF2YQoweDcxMDczNWI4CWFuZHJvaWQub3' + - 'MuSGFuZGxlcglzZW5kTWVzc2FnZURlbGF5ZWQJKExhbmRyb2lk' + - 'L29zL01lc3NhZ2U7SilaCUhhbmRsZXIuamF2YQoweDcxMDczNj' + - 'Q4CWFuZHJvaWQuYXBwLkFjdGl2aXR5VGhyZWFkJEgJaGFuZGxl' + - 'TWVzc2FnZQkoTGFuZHJvaWQvb3MvTWVzc2FnZTspVglBY3Rpdm' + - 'l0eVRocmVhZC5qYXZhCjB4NzEwNzM3NjgJYW5kcm9pZC5hcHAu' + - 'QWN0aXZpdHlUaHJlYWQkUHJvZmlsZXIJc3RhcnRQcm9maWxpbm' + - 'cJKClWCUFjdGl2aXR5VGhyZWFkLmphdmEKMHg3MTA3Mzc5OAlh' + - 'bmRyb2lkLmFwcC5BY3Rpdml0eVRocmVhZCRQcm9maWxlcglzdG' + - '9wUHJvZmlsaW5nCSgpVglBY3Rpdml0eVRocmVhZC5qYXZhCjB4' + - 'NzEwYzQ2ZDgJYW5kcm9pZC5vcy5NZXNzYWdlCW9idGFpbgkoKU' + - 'xhbmRyb2lkL29zL01lc3NhZ2U7CU1lc3NhZ2UuamF2YQoweDcx' + - 'MGM0YTM4CWFuZHJvaWQub3MuTWVzc2FnZQlpc0luVXNlCSgpWg' + - 'lNZXNzYWdlLmphdmEKMHg3MTBjNGE2OAlhbmRyb2lkLm9zLk1l' + - 'c3NhZ2UJbWFya0luVXNlCSgpVglNZXNzYWdlLmphdmEKMHg3MT' + - 'BjNGFmOAlhbmRyb2lkLm9zLk1lc3NhZ2UJcmVjeWNsZVVuY2hl' + - 'Y2tlZAkoKVYJTWVzc2FnZS5qYXZhCjB4NzEwYzRmMTgJYW5kcm' + - '9pZC5vcy5QYXJjZWwJaW5pdAkoSilWCVBhcmNlbC5qYXZhCjB4' + - 'NzEwYzRmYTgJYW5kcm9pZC5vcy5QYXJjZWwJb2J0YWluCShKKU' + - 'xhbmRyb2lkL29zL1BhcmNlbDsJUGFyY2VsLmphdmEKMHg3MTBj' + - 'NTQyOAlhbmRyb2lkLm9zLlBhcmNlbAllbmZvcmNlSW50ZXJmYW' + - 'NlCShMamF2YS9sYW5nL1N0cmluZzspVglQYXJjZWwuamF2YQow' + - 'eDcxMGM1OWY4CWFuZHJvaWQub3MuUGFyY2VsCXJlYWRJbnQJKC' + - 'lJCVBhcmNlbC5qYXZhCjB4NzEwYzZhNDgJYW5kcm9pZC5vcy5Q' + - 'YXJjZWxGaWxlRGVzY3JpcHRvcgljbG9zZVdpdGhTdGF0dXMJKE' + - 'lMamF2YS9sYW5nL1N0cmluZzspVglQYXJjZWxGaWxlRGVzY3Jp' + - 'cHRvci5qYXZhCjB4NzEwYzZkNzgJYW5kcm9pZC5vcy5QYXJjZW' + - 'xGaWxlRGVzY3JpcHRvcgl3cml0ZUNvbW1TdGF0dXNBbmRDbG9z' + - 'ZQkoSUxqYXZhL2xhbmcvU3RyaW5nOylWCVBhcmNlbEZpbGVEZX' + - 'NjcmlwdG9yLmphdmEKMHg3MTBjNmUwOAlhbmRyb2lkLm9zLlBh' + - 'cmNlbEZpbGVEZXNjcmlwdG9yCWNsb3NlCSgpVglQYXJjZWxGaW' + - 'xlRGVzY3JpcHRvci5qYXZhCjB4NzEwYzZmZTgJYW5kcm9pZC5v' + - 'cy5QYXJjZWxGaWxlRGVzY3JpcHRvcglyZWxlYXNlUmVzb3VyY2' + - 'VzCSgpVglQYXJjZWxGaWxlRGVzY3JpcHRvci5qYXZhCjB4NzEx' + - 'NWIwZjgJYW5kcm9pZC5vcy5NZXNzYWdlUXVldWUJZW5xdWV1ZU' + - '1lc3NhZ2UJKExhbmRyb2lkL29zL01lc3NhZ2U7SilaCU1lc3Nh' + - 'Z2VRdWV1ZS5qYXZhCjB4NzExNWIyMTgJYW5kcm9pZC5vcy5NZX' + - 'NzYWdlUXVldWUJbmV4dAkoKUxhbmRyb2lkL29zL01lc3NhZ2U7' + - 'CU1lc3NhZ2VRdWV1ZS5qYXZhCjB4NzE3ZTM2MzAJZGFsdmlrLn' + - 'N5c3RlbS5WTURlYnVnCXN0YXJ0TWV0aG9kVHJhY2luZ0ZkCShM' + - 'amF2YS9sYW5nL1N0cmluZztMamF2YS9pby9GaWxlRGVzY3JpcH' + - 'RvcjtJSVpJKVYJVk1EZWJ1Zy5qYXZhCjB4NzE4MTBhMjAJamF2' + - 'YS5pby5GaWxlRGVzY3JpcHRvcglpc1NvY2tldAkoKVoJRmlsZU' + - 'Rlc2NyaXB0b3IuamF2YQoweDcxODEwYWUwCWphdmEuaW8uRmls' + - 'ZURlc2NyaXB0b3IJdmFsaWQJKClaCUZpbGVEZXNjcmlwdG9yLm' + - 'phdmEKMHg3MTgxYmI4MAlsaWJjb3JlLmlvLklvVXRpbHMJY2xv' + - 'c2UJKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yOylWCUlvVXRpbH' + - 'MuamF2YQoweDcxODFiYmIwCWxpYmNvcmUuaW8uSW9VdGlscwlj' + - 'bG9zZVF1aWV0bHkJKExqYXZhL2lvL0ZpbGVEZXNjcmlwdG9yOy' + - 'lWCUlvVXRpbHMuamF2YQoweDcxODIxZWUwCWFuZHJvaWQuYXBw' + - 'LkFjdGl2aXR5VGhyZWFkCWFjY2VzcyQzMDAJKExhbmRyb2lkL2' + - 'FwcC9BY3Rpdml0eVRocmVhZDtJTGphdmEvbGFuZy9PYmplY3Q7' + - 'SUkpVglBY3Rpdml0eVRocmVhZC5qYXZhCjB4NzE4MjJhZTAJYW' + - '5kcm9pZC5hcHAuQWN0aXZpdHlUaHJlYWQJc2VuZE1lc3NhZ2UJ' + - 'KElMamF2YS9sYW5nL09iamVjdDtJSSlWCUFjdGl2aXR5VGhyZW' + - 'FkLmphdmEKMHg3MTgyMmIxMAlhbmRyb2lkLmFwcC5BY3Rpdml0' + - 'eVRocmVhZAlzZW5kTWVzc2FnZQkoSUxqYXZhL2xhbmcvT2JqZW' + - 'N0O0lJWilWCUFjdGl2aXR5VGhyZWFkLmphdmEKMHg3MTgyMzIz' + - 'MAlhbmRyb2lkLmFwcC5BY3Rpdml0eVRocmVhZAloYW5kbGVQcm' + - '9maWxlckNvbnRyb2wJKFpMYW5kcm9pZC9hcHAvUHJvZmlsZXJJ' + - 'bmZvO0kpVglBY3Rpdml0eVRocmVhZC5qYXZhCjB4NzE4MzY3MD' + - 'AJYW5kcm9pZC5vcy5EZWJ1ZwlzdG9wTWV0aG9kVHJhY2luZwko' + - 'KVYJRGVidWcuamF2YQoqZW5kClNMT1cDACAASxycoWkAAAAOAA' + - 'AAAAAAAAAAAAAAAAAAjwoxNn5xxtotAKISAgCPChmE+3CT4y0A' + - '/hsCAI8KaTcHcbbkLQAtNQIAjwoIbgxx0eQtAEc1AgCPCkhqDH' + - 'Hk5C0AWjUCAI8KWHf7cPLkLQBoNQIAjwpZd/tw/eQtAHM1AgCP' + - 'CnhtDHED5S0AeTUCAI8KeW0McQjlLQB+NQIAjwqwu4FxFOUtAI' + - 'o1AgCPCoC7gXEa5S0AkDUCAI8K4AqBcSPlLQCaNQIAjwrhCoFx' + - 'KuUtAKE1AgCPCqg/AXE65S0AsTUCAI8KIAqBcUDlLQC2NQIAjw' + - 'ohCoFxTuUtAMU1AgCPCqk/AXFn5S0A3jUCAI8KgbuBcWzlLQDi' + - 'NQIAjwqxu4Fxb+UtAOU1AgCPCuhvDHF15S0A6zUCAI8K6W8McX' + - 'nlLQDvNQIAjwpJagxxfOUtAPI1AgCPCgluDHGB5S0A9zUCAI8K' + - 'MTKCcYXlLQD6NQIAjwpJNgdxjOUtAAM2AgCPCukvB3GS5S0ACT' + - 'YCAI8K+EoMcaTlLQAbNgIAjwr5SgxxwOUtADY2AgCPChiyFXHH' + - '5S0APTYCAI8KKKf+cPHlLQBnNgIAjwopp/5w++UtAHE2AgCfCk' + - 'h3BXHy2wAAu5RgAJ8KqE8McSvcAADwlGAAnwoYTwxxaNwAACyV' + - 'YACfChlPDHGD3AAARpVgAJ8KqU8McZbcAABZlWAAnwqoTwxxrN' + - 'wAAG6VYACfChhPDHHL3AAAjpVgAJ8KGU8MceDcAACjlWAAnwqp' + - 'Twxx8twAALSVYACfCkgqB3Ea3QAA3ZVgAJ8KKFQMcUHdAAAFlm' + - 'AAnwopVAxxjN0AAFGWYACfCvhZDHHD3QAAiJZgAJ8K+VkMcejd' + - 'AACslmAAnwr4WQxxAN4AAMOWYACfCvlZDHEa3gAA3ZZgAJ8K+F' + - 'kMcS/eAADylmAAnwr5WQxxR94AAAqXYACfCugXB3Fv3gAAM5dg' + - 'AJ8K4B6CcYveAABPl2AAnwrgKoJxrN4AAHCXYACfChArgnHQ3g' + - 'AAkpdgAJ8K2EYMceTeAACml2AAnwrZRgxxDd8AANCXYACfCig1' + - 'B3Er3wAA7pdgAJ8KuDUHcT7fAAAAmGAAnwqINQdxa98AAC+YYA' + - 'CfCigvB3GD3wAASJhgAJ8K+LAVcaDfAABjmGAAnwo4Sgxxtt8A' + - 'AHiYYACfCjlKDHHL3wAAkJhgAJ8KaEoMce3fAACxmGAAnwppSg' + - 'xxAuAAAMWYYACfCvmwFXFz4AAAOJlgAI8KGbIVcU3mLQBAmWAA' + - 'jwroLwdxVuYtAEmZYACfCikvB3GG4AAASZlgAI8KSDYHcVzmLQ' + - 'BPmWAAjwowMoJxZuYtAFmZYACfCok1B3GW4AAAWJlgAI8KmDcH' + - 'cXTmLQBnmWAAnwq5NQdxr+AAAHGZYACPCgBng3GC5i0AdplgAJ' + - '8KKTUHcb3gAAB/mWAAnwoRK4JxzOAAAI6ZYAA='); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/etw_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/etw_importer.html deleted file mode 100644 index 799e2a13b95..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/etw_importer.html +++ /dev/null @@ -1,477 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/base/base64.html"> -<link rel="import" href="/tracing/extras/importer/etw/eventtrace_parser.html"> -<link rel="import" href="/tracing/extras/importer/etw/process_parser.html"> -<link rel="import" href="/tracing/extras/importer/etw/thread_parser.html"> -<link rel="import" href="/tracing/importer/importer.html"> -<link rel="import" href="/tracing/model/model.html"> - -<script> -/** - * @fileoverview Imports JSON file with the raw payloads from a Windows event - * trace into the Model. This format is outputted by Chrome running - * on a Windows system. - * - * This importer assumes the events arrived as a JSON file and the payloads are - * undecoded sequence of bytes in hex format string. The unit tests provide - * examples of the trace format. - * - * The format of the system trace is - * { - * name: 'ETW', - * content: [ <events> ] - * } - * - * where the <events> are dictionary values with fields. - * - * { - * guid: "1234-...", // The unique GUID for the event. - * op: 12, // The opcode of the event. - * ver: 1, // The encoding version of the event. - * cpu: 0, // The cpu id on which the event was captured. - * ts: 1092, // The thread id on which the event was captured. - * payload: "aaaa" // A base64 encoded string of the raw payload. - * } - * - * The payload is an undecoded version of the raw event sent by ETW. - * This importer uses specific parsers to decode recognized events. - * A parser need to register the recognized event by calling - * registerEventHandler(guid, opcode, handler). The parser is responsible to - * decode the payload and update the Model. - * - * The payload formats are described there: - * http://msdn.microsoft.com/en-us/library/windows/desktop/aa364085(v=vs.85).aspx - * - */ -'use strict'; - -tr.exportTo('tr.e.importer.etw', function() { - // GUID and opcode of a Thread DCStart event, as defined at the link above. - var kThreadGuid = '3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C'; - var kThreadDCStartOpcode = 3; - - /** - * Represents the raw bytes payload decoder. - * @constructor - */ - function Decoder() { - this.payload_ = new DataView(new ArrayBuffer(256)); - }; - - Decoder.prototype = { - __proto__: Object.prototype, - - reset: function(base64_payload) { - var decoded_size = tr.b.Base64.getDecodedBufferLength(base64_payload); - if (decoded_size > this.payload_.byteLength) - this.payload_ = new DataView(new ArrayBuffer(decoded_size)); - - tr.b.Base64.DecodeToTypedArray(base64_payload, this.payload_); - this.position_ = 0; - }, - - skip: function(length) { - this.position_ += length; - }, - - decodeUInt8: function() { - var result = this.payload_.getUint8(this.position_, true); - this.position_ += 1; - return result; - }, - - decodeUInt16: function() { - var result = this.payload_.getUint16(this.position_, true); - this.position_ += 2; - return result; - }, - - decodeUInt32: function() { - var result = this.payload_.getUint32(this.position_, true); - this.position_ += 4; - return result; - }, - - decodeUInt64ToString: function() { - // Javascript isn't able to manage 64-bit numeric values. - var low = this.decodeUInt32(); - var high = this.decodeUInt32(); - var low_str = ('0000000' + low.toString(16)).substr(-8); - var high_str = ('0000000' + high.toString(16)).substr(-8); - var result = high_str + low_str; - return result; - }, - - decodeInt8: function() { - var result = this.payload_.getInt8(this.position_, true); - this.position_ += 1; - return result; - }, - - decodeInt16: function() { - var result = this.payload_.getInt16(this.position_, true); - this.position_ += 2; - return result; - }, - - decodeInt32: function() { - var result = this.payload_.getInt32(this.position_, true); - this.position_ += 4; - return result; - }, - - decodeInt64ToString: function() { - // Javascript isn't able to manage 64-bit numeric values. - // Fallback to unsigned 64-bit hexa value. - return this.decodeUInt64ToString(); - }, - - decodeUInteger: function(is64) { - if (is64) - return this.decodeUInt64ToString(); - return this.decodeUInt32(); - }, - - decodeString: function() { - var str = ''; - while (true) { - var c = this.decodeUInt8(); - if (!c) - return str; - str = str + String.fromCharCode(c); - } - }, - - decodeW16String: function() { - var str = ''; - while (true) { - var c = this.decodeUInt16(); - if (!c) - return str; - str = str + String.fromCharCode(c); - } - }, - - decodeFixedW16String: function(length) { - var old_position = this.position_; - var str = ''; - for (var i = 0; i < length; i++) { - var c = this.decodeUInt16(); - if (!c) - break; - str = str + String.fromCharCode(c); - } - - // Move the position after the fixed buffer (i.e. wchar[length]). - this.position_ = old_position + 2 * length; - return str; - }, - - decodeBytes: function(length) { - var bytes = []; - for (var i = 0; i < length; ++i) { - var c = this.decodeUInt8(); - bytes.push(c); - } - return bytes; - }, - - decodeSID: function(is64) { - // Decode the TOKEN_USER structure. - var pSid = this.decodeUInteger(is64); - var attributes = this.decodeUInt32(); - - // Skip padding. - if (is64) - this.decodeUInt32(); - - // Decode the SID structure. - var revision = this.decodeUInt8(); - var subAuthorityCount = this.decodeUInt8(); - this.decodeUInt16(); - this.decodeUInt32(); - - if (revision != 1) - throw 'Invalid SID revision: could not decode the SID structure.'; - - var sid = this.decodeBytes(4 * subAuthorityCount); - - return { - pSid: pSid, - attributes: attributes, - sid: sid - }; - }, - - decodeSystemTime: function() { - // Decode the SystemTime structure. - var wYear = this.decodeInt16(); - var wMonth = this.decodeInt16(); - var wDayOfWeek = this.decodeInt16(); - var wDay = this.decodeInt16(); - var wHour = this.decodeInt16(); - var wMinute = this.decodeInt16(); - var wSecond = this.decodeInt16(); - var wMilliseconds = this.decodeInt16(); - return { - wYear: wYear, - wMonth: wMonth, - wDayOfWeek: wDayOfWeek, - wDay: wDay, - wHour: wHour, - wMinute: wMinute, - wSecond: wSecond, - wMilliseconds: wMilliseconds - }; - }, - - decodeTimeZoneInformation: function() { - // Decode the TimeZoneInformation structure. - var bias = this.decodeUInt32(); - var standardName = this.decodeFixedW16String(32); - var standardDate = this.decodeSystemTime(); - var standardBias = this.decodeUInt32(); - var daylightName = this.decodeFixedW16String(32); - var daylightDate = this.decodeSystemTime(); - var daylightBias = this.decodeUInt32(); - return { - bias: bias, - standardName: standardName, - standardDate: standardDate, - standardBias: standardBias, - daylightName: daylightName, - daylightDate: daylightDate, - daylightBias: daylightBias - }; - } - - }; - - /** - * Imports Windows ETW kernel events into a specified model. - * @constructor - */ - function EtwImporter(model, events) { - this.importPriority = 3; - this.model_ = model; - this.events_ = events; - this.handlers_ = {}; - this.decoder_ = new Decoder(); - this.walltime_ = undefined; - this.ticks_ = undefined; - this.is64bit_ = undefined; - - // A map of tids to their process pid. On Windows, the tid is global to - // the system and doesn't need to belong to a process. As many events - // only provide tid, this map allows to retrieve the parent process. - this.tidsToPid_ = {}; - - // Instantiate the parsers; this will register handlers for known events. - var allTypeInfos = tr.e.importer.etw.Parser.getAllRegisteredTypeInfos(); - this.parsers_ = allTypeInfos.map( - function(typeInfo) { - return new typeInfo.constructor(this); - }, this); - } - - /** - * Guesses whether the provided events is from a Windows ETW trace. - * The object must has a property named 'name' with the value 'ETW' and - * a property 'content' with all the undecoded events. - * - * @return {boolean} True when events is a Windows ETW array. - */ - EtwImporter.canImport = function(events) { - if (!events.hasOwnProperty('name') || - !events.hasOwnProperty('content') || - events.name !== 'ETW') { - return false; - } - - return true; - }; - - EtwImporter.prototype = { - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'EtwImporter'; - }, - - get model() { - return this.model_; - }, - - createThreadIfNeeded: function(pid, tid) { - this.tidsToPid_[tid] = pid; - }, - - removeThreadIfPresent: function(tid) { - this.tidsToPid_[tid] = undefined; - }, - - getPidFromWindowsTid: function(tid) { - if (tid == 0) - return 0; - var pid = this.tidsToPid_[tid]; - if (pid == undefined) { - // Kernel threads are not defined. - return 0; - } - return pid; - }, - - getThreadFromWindowsTid: function(tid) { - var pid = this.getPidFromWindowsTid(tid); - var process = this.model_.getProcess(pid); - if (!process) - return undefined; - return process.getThread(tid); - }, - - /* - * Retrieve the Cpu for a given cpuNumber. - * @return {Cpu} A Cpu corresponding to the given cpuNumber. - */ - getOrCreateCpu: function(cpuNumber) { - var cpu = this.model_.kernel.getOrCreateCpu(cpuNumber); - return cpu; - }, - - /** - * Imports the data in this.events_ into this.model_. - */ - importEvents: function() { - this.events_.content.forEach(this.parseInfo.bind(this)); - - if (this.walltime_ == undefined || this.ticks_ == undefined) - throw Error('Cannot find clock sync information in the system trace.'); - - if (this.is64bit_ == undefined) - throw Error('Cannot determine pointer size of the system trace.'); - - this.events_.content.forEach(this.parseEvent.bind(this)); - }, - - importTimestamp: function(timestamp) { - var ts = parseInt(timestamp, 16); - return (ts - this.walltime_ + this.ticks_) / 1000.; - }, - - parseInfo: function(event) { - // Retrieve clock sync information. - if (event.hasOwnProperty('guid') && - event.hasOwnProperty('walltime') && - event.hasOwnProperty('tick') && - event.guid === 'ClockSync') { - this.walltime_ = parseInt(event.walltime, 16); - this.ticks_ = parseInt(event.tick, 16); - } - - // Retrieve pointer size information from a Thread.DCStart event. - if (this.is64bit_ == undefined && - event.hasOwnProperty('guid') && - event.hasOwnProperty('op') && - event.hasOwnProperty('ver') && - event.hasOwnProperty('payload') && - event.guid === kThreadGuid && - event.op == kThreadDCStartOpcode) { - var decoded_size = tr.b.Base64.getDecodedBufferLength(event.payload); - - if (event.ver == 1) { - if (decoded_size >= 52) - this.is64bit_ = true; - else - this.is64bit_ = false; - } else if (event.ver == 2) { - if (decoded_size >= 64) - this.is64bit_ = true; - else - this.is64bit_ = false; - } else if (event.ver == 3) { - if (decoded_size >= 60) - this.is64bit_ = true; - else - this.is64bit_ = false; - } - } - - return true; - }, - - parseEvent: function(event) { - if (!event.hasOwnProperty('guid') || - !event.hasOwnProperty('op') || - !event.hasOwnProperty('ver') || - !event.hasOwnProperty('cpu') || - !event.hasOwnProperty('ts') || - !event.hasOwnProperty('payload')) { - return false; - } - - var timestamp = this.importTimestamp(event.ts); - - // Create the event header. - var header = { - guid: event.guid, - opcode: event.op, - version: event.ver, - cpu: event.cpu, - timestamp: timestamp, - is64: this.is64bit_ - }; - - // Set the payload to decode. - var decoder = this.decoder_; - decoder.reset(event.payload); - - // Retrieve the handler to decode the payload. - var handler = this.getEventHandler(header.guid, header.opcode); - if (!handler) - return false; - - if (!handler(header, decoder)) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Malformed ' + header.guid + ' event (' + event.payload + ')' - }); - return false; - } - - return true; - }, - - /** - * Registers a windows ETW event handler used by parseEvent(). - */ - registerEventHandler: function(guid, opcode, handler) { - if (this.handlers_[guid] == undefined) - this.handlers_[guid] = []; - this.handlers_[guid][opcode] = handler; - }, - - /** - * Retrieves a registered event handler. - */ - getEventHandler: function(guid, opcode) { - if (this.handlers_[guid] == undefined) - return undefined; - return this.handlers_[guid][opcode]; - } - - }; - - // Register the EtwImporter to the Importer. - tr.importer.Importer.register(EtwImporter); - - return { - EtwImporter: EtwImporter - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/etw_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/etw_importer_test.html deleted file mode 100644 index 91a94d6c015..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/etw_importer_test.html +++ /dev/null @@ -1,291 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/base/base64.html"> -<link rel="import" href="/tracing/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/etw/etw_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - var Base64 = tr.b.Base64; - - test('canImport', function() { - assert.isFalse(tr.e.importer.etw.EtwImporter.canImport('string')); - assert.isFalse(tr.e.importer.etw.EtwImporter.canImport([])); - - // Must not parse an invalid name. - var dummy = { name: 'dummy', content: [] }; - assert.isFalse(tr.e.importer.etw.EtwImporter.canImport(dummy)); - - // Must parse an empty valid trace. - var valid = { name: 'ETW', content: [] }; - assert.isTrue(tr.e.importer.etw.EtwImporter.canImport(valid)); - }); - - test('getModel', function() { - var model = 'dummy'; - var events = []; - var importer = new tr.e.importer.etw.EtwImporter(model, events); - assert.strictEqual(importer.model, model); - }); - - test('registerEventHandler', function() { - // Create a dummy EtwImporter. - var model = 'dummy'; - var events = ['events']; - var importer = new tr.e.importer.etw.EtwImporter(model, events); - var dummy_handler = function() {}; - - // The handler must not exists. - assert.isUndefined(importer.getEventHandler('ABCDEF', 2)); - - // Register an event handler for guid: ABCDEF and opcode: 2. - importer.registerEventHandler('ABCDEF', 2, dummy_handler); - - // The handler exists now, must find it. - assert.isDefined(importer.getEventHandler('ABCDEF', 2)); - - // Must be able to manage an invalid handler. - assert.isUndefined(importer.getEventHandler('zzzzzz', 2)); - }); - - test('parseEvent', function() { - var model = 'dummy'; - var events = []; - var importer = new tr.e.importer.etw.EtwImporter(model, events); - var handler_called = false; - var dummy_handler = function() { handler_called = true; return true; }; - - // Register a valid handler. - importer.registerEventHandler('aaaa', 42, dummy_handler); - - // Try to parse an invalid event with missing fields. - var incomplet_event = { guid: 'aaaa', 'op': 42, 'ver': 0 }; - assert.isFalse(importer.parseEvent(incomplet_event)); - assert.isFalse(handler_called); - - // Try to parse a valid event. - var valid_event = { - guid: 'aaaa', 'op': 42, 'ver': 0, 'cpu': 0, 'ts': 0, - 'payload': Base64.btoa('0') - }; - assert.isTrue(importer.parseEvent(valid_event)); - assert.isTrue(handler_called); - }); - - test('resetTooSmall', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - - var oldByteLength = decoder.payload_.byteLength; - // Decode a payload too big for the actual buffer. - decoder.reset('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='); - var newByteLength = decoder.payload_.byteLength; - - // Validate the buffer has been resized. - assert.isBelow(oldByteLength, newByteLength); - }); - - test('decode', function() { - var model = 'dummy'; - var events = []; - var importer = new tr.e.importer.etw.EtwImporter(model, events); - - var decoder = importer.decoder_; - - decoder.reset('YQBiYw=='); - assert.equal(decoder.decodeInt32(), 0x63620061); - - // Decode unsigned numbers. - decoder.reset('AQ=='); - assert.equal(decoder.decodeUInt8(), 0x01); - - decoder.reset('AQI='); - assert.equal(decoder.decodeUInt16(), 0x0201); - - decoder.reset('AQIDBA=='); - assert.equal(decoder.decodeUInt32(), 0x04030201); - - decoder.reset('AQIDBAUGBwg='); - assert.strictEqual(decoder.decodeUInt64ToString(), '0807060504030201'); - - // Decode signed numbers. - decoder.reset('AQ=='); - assert.equal(decoder.decodeInt8(), 0x01); - - decoder.reset('AQI='); - assert.equal(decoder.decodeInt16(), 0x0201); - - decoder.reset('AQIDBA=='); - assert.equal(decoder.decodeInt32(), 0x04030201); - - decoder.reset('AQIDBAUGBwg='); - assert.strictEqual(decoder.decodeInt64ToString(), '0807060504030201'); - - // Last value before being a signed number. - decoder.reset('fw=='); - assert.equal(decoder.decodeInt8(), 127); - - // Decode negative numbers. - decoder.reset('1g=='); - assert.equal(decoder.decodeInt8(), -42); - - decoder.reset('gA=='); - assert.equal(decoder.decodeInt8(), -128); - - decoder.reset('hYI='); - assert.equal(decoder.decodeInt16(), -32123); - - decoder.reset('hYL//w=='); - assert.equal(decoder.decodeInt32(), -32123); - - decoder.reset('Lv1ptv////8='); - assert.equal(decoder.decodeInt32(), -1234567890); - - // Decode number with zero (nul) in the middle of the string. - decoder.reset('YQBiYw=='); - assert.equal(decoder.decodeInt32(), 0x63620061); - }); - - test('decodeUInteger', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - - decoder.reset('AQIDBAUGBwg='); - assert.equal(decoder.decodeUInteger(false), 0x04030201); - - decoder.reset('AQIDBAUGBwg='); - assert.strictEqual(decoder.decodeUInteger(true), '0807060504030201'); - }); - - test('decodeString', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - - decoder.reset('dGVzdAA='); - assert.strictEqual(decoder.decodeString(), 'test'); - - decoder.reset('VGhpcyBpcyBhIHRlc3Qu'); - assert.strictEqual(decoder.decodeString(), 'This is a test.'); - }); - - test('decodeW16String', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - decoder.reset('dABlAHMAdAAAAA=='); - assert.strictEqual(decoder.decodeW16String(), 'test'); - }); - - test('decodeFixedW16String', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - decoder.reset('dABlAHMAdAAAAA=='); - assert.strictEqual(decoder.decodeFixedW16String(32), 'test'); - assert.equal(decoder.position_, 64); - - decoder.reset('dABlAHMAdAAAAA=='); - assert.strictEqual(decoder.decodeFixedW16String(1), 't'); - assert.equal(decoder.position_, 2); - }); - - test('decodeBytes', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - decoder.reset('AAECAwQFBgc='); - var bytes = decoder.decodeBytes(8); - for (var i = 0; i < bytes.length; ++i) - assert.equal(bytes[i], i); - }); - - test('decodeSID', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - - // Decode a SID structure with 64-bit pointer. - decoder.reset( - 'AQIDBAECAwQFBAMCAAAAAAEFAAAAAAAFFQAAAAECAwQFBgcICQoLDA0DAAA='); - var sid = decoder.decodeSID(true); - - assert.strictEqual(sid.pSid, '0403020104030201'); - assert.equal(sid.attributes, 0x02030405); - assert.equal(sid.sid.length, 20); - }); - - test('decodeSystemTime', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - - // Decode a SystemTime structure. - decoder.reset('AQACAAMABAAFAAYABwAIAA=='); - var time = decoder.decodeSystemTime(); - assert.equal(time.wYear, 1); - assert.equal(time.wMonth, 2); - assert.equal(time.wDayOfWeek, 3); - assert.equal(time.wDay, 4); - assert.equal(time.wHour, 5); - assert.equal(time.wMinute, 6); - assert.equal(time.wSecond, 7); - assert.equal(time.wMilliseconds, 8); - }); - - test('decodeTimeZoneInformation', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - - // Decode a TimeZoneInformation structure. - decoder.reset('AQIDBGEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAwAEAAUABgAHAAgABA' + - 'MCAWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAAwAEAAUABgAHAAgACAgI' + - 'CA=='); - var time = decoder.decodeTimeZoneInformation(); - - assert.equal(time.bias, 0x04030201); - assert.equal(time.standardBias, 0x01020304); - assert.equal(time.daylightBias, 0x08080808); - assert.strictEqual(time.standardName, 'a'); - assert.strictEqual(time.daylightName, 'b'); - }); - - test('manageThreads', function() { - var events = []; - var model = 'dummy'; - var importer = new tr.e.importer.etw.EtwImporter(model, events); - - // After initialisation, no threads must exists. - assert.equal(Object.getOwnPropertyNames(importer.tidsToPid_).length, 0); - - // Add some threads. - var thread10 = importer.createThreadIfNeeded(1, 10); - var thread11 = importer.createThreadIfNeeded(1, 11); - var thread20 = importer.createThreadIfNeeded(2, 20); - - assert.equal(Object.getOwnPropertyNames(importer.tidsToPid_).length, 3); - assert.isTrue(importer.tidsToPid_.hasOwnProperty(10)); - assert.isTrue(importer.tidsToPid_.hasOwnProperty(11)); - assert.isTrue(importer.tidsToPid_.hasOwnProperty(20)); - - // Retrieve existing threads and processes. - var pid10 = importer.getPidFromWindowsTid(10); - var pid11 = importer.getPidFromWindowsTid(11); - var pid20 = importer.getPidFromWindowsTid(20); - - assert.equal(pid10, 1); - assert.equal(pid11, 1); - assert.equal(pid20, 2); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/eventtrace_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/eventtrace_parser.html deleted file mode 100644 index 14c1dcf5c1b..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/eventtrace_parser.html +++ /dev/null @@ -1,110 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/extras/importer/etw/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses EventTrace events in the Windows event trace format. - */ - -tr.exportTo('tr.e.importer.etw', function() { - var Parser = tr.e.importer.etw.Parser; - - // Constants for EventTrace events. - var guid = '68FDD900-4A3E-11D1-84F4-0000F80464E3'; - var kEventTraceHeaderOpcode = 0; - - /** - * Parses Windows EventTrace trace events. - * @constructor - */ - function EventTraceParser(importer) { - Parser.call(this, importer); - - // Register handlers. - importer.registerEventHandler(guid, kEventTraceHeaderOpcode, - EventTraceParser.prototype.decodeHeader.bind(this)); - } - - EventTraceParser.prototype = { - __proto__: Parser.prototype, - - decodeFields: function(header, decoder) { - if (header.version != 2) - throw new Error('Incompatible EventTrace event version.'); - - var bufferSize = decoder.decodeUInt32(); - var version = decoder.decodeUInt32(); - var providerVersion = decoder.decodeUInt32(); - var numberOfProcessors = decoder.decodeUInt32(); - var endTime = decoder.decodeUInt64ToString(); - var timerResolution = decoder.decodeUInt32(); - var maxFileSize = decoder.decodeUInt32(); - var logFileMode = decoder.decodeUInt32(); - var buffersWritten = decoder.decodeUInt32(); - var startBuffers = decoder.decodeUInt32(); - var pointerSize = decoder.decodeUInt32(); - var eventsLost = decoder.decodeUInt32(); - var cpuSpeed = decoder.decodeUInt32(); - var loggerName = decoder.decodeUInteger(header.is64); - var logFileName = decoder.decodeUInteger(header.is64); - var timeZoneInformation = decoder.decodeTimeZoneInformation(); - var padding = decoder.decodeUInt32(); - var bootTime = decoder.decodeUInt64ToString(); - var perfFreq = decoder.decodeUInt64ToString(); - var startTime = decoder.decodeUInt64ToString(); - var reservedFlags = decoder.decodeUInt32(); - var buffersLost = decoder.decodeUInt32(); - var sessionNameString = decoder.decodeW16String(); - var logFileNameString = decoder.decodeW16String(); - - return { - bufferSize: bufferSize, - version: version, - providerVersion: providerVersion, - numberOfProcessors: numberOfProcessors, - endTime: endTime, - timerResolution: timerResolution, - maxFileSize: maxFileSize, - logFileMode: logFileMode, - buffersWritten: buffersWritten, - startBuffers: startBuffers, - pointerSize: pointerSize, - eventsLost: eventsLost, - cpuSpeed: cpuSpeed, - loggerName: loggerName, - logFileName: logFileName, - timeZoneInformation: timeZoneInformation, - bootTime: bootTime, - perfFreq: perfFreq, - startTime: startTime, - reservedFlags: reservedFlags, - buffersLost: buffersLost, - sessionNameString: sessionNameString, - logFileNameString: logFileNameString - }; - }, - - decodeHeader: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - // TODO(etienneb): Update the Model with |fields|. - return true; - } - - }; - - Parser.register(EventTraceParser); - - return { - EventTraceParser: EventTraceParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/eventtrace_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/eventtrace_parser_test.html deleted file mode 100644 index 840eb5ef06a..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/eventtrace_parser_test.html +++ /dev/null @@ -1,120 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/etw/etw_importer.html"> -<link rel="import" href="/tracing/extras/importer/etw/eventtrace_parser.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - // Constants for EventTrace events. - var guid = '68FDD900-4A3E-11D1-84F4-0000F80464E3'; - var kEventTraceHeaderOpcode = 0; - - var kEventTraceHeaderPayload32bitV2 = - 'AAABAAYBAQWwHQAAEAAAABEs1WHICMwBYWECAGQAAAABAAAAAwAAAAEAAAAEAAAAAAAAA' + - 'FoJAAAFAAAABgAAACwBAABAAHQAegByAGUAcwAuAGQAbABsACwALQAxADEAMgAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAQACAAAAAAAAAAAAAABAAHQ' + - 'AegByAGUAcwAuAGQAbABsACwALQAxADEAMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAADAAAAAgACAAAAAAAAAMT///8AAAAAf0Ob368FzAGdrCMAAAAAACw0o' + - '2DICMwBAQAAAAAAAABNAGEAawBlACAAVABlAHMAdAAgAEQAYQB0AGEAIABTAGUAcwBzAG' + - 'kAbwBuAAAAYwA6AFwAcwByAGMAXABzAGEAdwBiAHUAYwBrAFwAdAByAHUAbgBrAFwAcwB' + - 'yAGMAXABzAGEAdwBiAHUAYwBrAFwAbABvAGcAXwBsAGkAYgBcAHQAZQBzAHQAXwBkAGEA' + - 'dABhAFwAaQBtAGEAZwBlAF8AZABhAHQAYQBfADMAMgBfAHYAMAAuAGUAdABsAAAA'; - - var kEventTraceHeaderPayload64bitV2 = - 'AAABAAYBAQWxHQAABAAAADsuzRRYLM8BYWECAAAAAAABAAEAtgEAAAEAAAAIAAAAHwAAA' + - 'KAGAAAAAAAAAAAAAAAAAAAAAAAALAEAAEAAdAB6AHIAZQBzAC4AZABsAGwALAAtADEAMQ' + - 'AyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAABAAIAAAAAAAA' + - 'AAAAAAEAAdAB6AHIAZQBzAC4AZABsAGwALAAtADEAMQAxAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAMAAAACAAIAAAAAAAAAxP///wAAAABZQyWiwCvPAX1GG' + - 'QAAAAAALWSZBFgszwEBAAAAAAAAAFIAZQBsAG8AZwBnAGUAcgAAAEMAOgBcAGsAZQByAG' + - '4AZQBsAC4AZQB0AGwAAAA='; - - test('DecodeFields', function() { - - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - var parser = new tr.e.importer.etw.EventTraceParser(importer); - var header; - var fields; - - // Validate a version 2 32-bit payload. - header = { - guid: guid, opcode: kEventTraceHeaderOpcode, version: 2, is64: 0 - }; - decoder.reset(kEventTraceHeaderPayload32bitV2); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.bufferSize, 65536); - assert.equal(fields.version, 83951878); - assert.equal(fields.providerVersion, 7600); - assert.equal(fields.numberOfProcessors, 16); - assert.strictEqual(fields.endTime, '01cc08c861d52c11'); - assert.equal(fields.timerResolution, 156001); - assert.equal(fields.maxFileSize, 100); - assert.equal(fields.logFileMode, 1); - assert.equal(fields.buffersWritten, 3); - assert.equal(fields.startBuffers, 1); - assert.equal(fields.pointerSize, 4); - assert.equal(fields.eventsLost, 0); - assert.equal(fields.cpuSpeed, 2394); - assert.equal(fields.loggerName, 5); - assert.equal(fields.logFileName, 6); - assert.strictEqual(fields.timeZoneInformation.standardName, - '@tzres.dll,-112'); - assert.strictEqual(fields.timeZoneInformation.daylightName, - '@tzres.dll,-111'); - assert.strictEqual(fields.bootTime, '01cc05afdf9b437f'); - assert.strictEqual(fields.perfFreq, '000000000023ac9d'); - assert.strictEqual(fields.startTime, '01cc08c860a3342c'); - assert.equal(fields.reservedFlags, 1); - assert.equal(fields.buffersLost, 0); - assert.strictEqual(fields.sessionNameString, 'Make Test Data Session'); - assert.strictEqual(fields.logFileNameString, - 'c:\\src\\sawbuck\\trunk\\src\\sawbuck\\log_lib\\' + - 'test_data\\image_data_32_v0.etl'); - - // Validate a version 2 64-bit payload. - header = { - guid: guid, opcode: kEventTraceHeaderOpcode, version: 2, is64: 1 - }; - decoder.reset(kEventTraceHeaderPayload64bitV2); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.bufferSize, 65536); - assert.equal(fields.version, 83951878); - assert.equal(fields.providerVersion, 7601); - assert.equal(fields.numberOfProcessors, 4); - assert.strictEqual(fields.endTime, '01cf2c5814cd2e3b'); - assert.equal(fields.timerResolution, 156001); - assert.equal(fields.maxFileSize, 0); - assert.equal(fields.logFileMode, 0x10001); - assert.equal(fields.buffersWritten, 438); - assert.equal(fields.startBuffers, 1); - assert.equal(fields.pointerSize, 8); - assert.equal(fields.eventsLost, 31); - assert.equal(fields.cpuSpeed, 1696); - assert.equal(fields.loggerName, 0); - assert.equal(fields.logFileName, 0); - assert.strictEqual(fields.timeZoneInformation.standardName, - '@tzres.dll,-112'); - assert.strictEqual(fields.timeZoneInformation.daylightName, - '@tzres.dll,-111'); - assert.strictEqual(fields.bootTime, '01cf2bc0a2254359'); - assert.strictEqual(fields.perfFreq, '000000000019467d'); - assert.strictEqual(fields.startTime, '01cf2c580499642d'); - assert.equal(fields.reservedFlags, 1); - assert.equal(fields.buffersLost, 0); - assert.strictEqual(fields.sessionNameString, 'Relogger'); - assert.strictEqual(fields.logFileNameString, 'C:\\kernel.etl'); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/parser.html deleted file mode 100644 index 414defe510b..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/parser.html +++ /dev/null @@ -1,73 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/base/base.html"> -<link rel="import" href="/tracing/base/extension_registry.html"> -<script> -'use strict'; - -/** - * @fileoverview Base class for Windows ETW event parsers. - * - * The ETW trace event importer depends on subclasses of - * Parser to parse event data. Each subclass corresponds - * to a group of trace events; e.g. Thread and Process implements - * decoding of scheduling events. Parser subclasses must - * call Parser.register to arrange to be instantiated - * and their constructor must register their event handlers with the - * importer. For example, - * - * var Parser = tr.e.importer.etw.Parser; - * - * function ThreadParser(importer) { - * Parser.call(this, importer); - * - * importer.registerEventHandler(guid, kThreadStartOpcode, - * ThreadParser.prototype.decodeStart.bind(this)); - * importer.registerEventHandler(guid, kThreadEndOpcode, - * ThreadParser.prototype.decodeEnd.bind(this)); - * } - * - * Parser.register(ThreadParser); - * - * When a registered event is found, the associated event handler is invoked: - * - * decodeStart: function(header, decoder) { - * [...] - * return true; - * }, - * - * If the routine returns false the caller will generate an import error - * saying there was a problem parsing it. Handlers can also emit import - * messages using this.importer.model.importWarning. If this is done in lieu of - * the generic import error it may be desirable for the handler to return - * true. - * - */ -tr.exportTo('tr.e.importer.etw', function() { - /** - * Parses Windows ETW events. - * @constructor - */ - function Parser(importer) { - this.importer = importer; - this.model = importer.model; - } - - Parser.prototype = { - __proto__: Object.prototype - }; - - var options = new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE); - options.mandatoryBaseClass = Parser; - tr.b.decorateExtensionRegistry(Parser, options); - - - return { - Parser: Parser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/process_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/process_parser.html deleted file mode 100644 index 51f1e9b51aa..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/process_parser.html +++ /dev/null @@ -1,181 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/extras/importer/etw/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses processes events in the Windows event trace format. - * - * The Windows process events are: - * - * - DCStart: Describes a process that was already running when the trace - * started. ETW automatically generates these events for all running - * processes at the beginning of the trace. - * - Start: Describes a process launched during the tracing session. - * - End: Describes a process that ended during the tracing session. - * - DCEnd: Describes a process that was still running when the trace ended. - * - * See http://msdn.microsoft.com/library/windows/desktop/aa364092.aspx - */ -tr.exportTo('tr.e.importer.etw', function() { - var Parser = tr.e.importer.etw.Parser; - - // Constants for Process events. - var guid = '3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C'; - var kProcessStartOpcode = 1; - var kProcessEndOpcode = 2; - var kProcessDCStartOpcode = 3; - var kProcessDCEndOpcode = 4; - var kProcessDefunctOpcode = 39; - - /** - * Parses Windows process trace events. - * @constructor - */ - function ProcessParser(importer) { - Parser.call(this, importer); - - // Register handlers. - importer.registerEventHandler(guid, kProcessStartOpcode, - ProcessParser.prototype.decodeStart.bind(this)); - importer.registerEventHandler(guid, kProcessEndOpcode, - ProcessParser.prototype.decodeEnd.bind(this)); - importer.registerEventHandler(guid, kProcessDCStartOpcode, - ProcessParser.prototype.decodeDCStart.bind(this)); - importer.registerEventHandler(guid, kProcessDCEndOpcode, - ProcessParser.prototype.decodeDCEnd.bind(this)); - importer.registerEventHandler(guid, kProcessDefunctOpcode, - ProcessParser.prototype.decodeDefunct.bind(this)); - } - - ProcessParser.prototype = { - __proto__: Parser.prototype, - - decodeFields: function(header, decoder) { - if (header.version > 5) - throw new Error('Incompatible Process event version.'); - - var pageDirectoryBase; - if (header.version == 1) - pageDirectoryBase = decoder.decodeUInteger(header.is64); - - var uniqueProcessKey; - if (header.version >= 2) - uniqueProcessKey = decoder.decodeUInteger(header.is64); - - var processId = decoder.decodeUInt32(); - var parentId = decoder.decodeUInt32(); - - var sessionId; - var exitStatus; - if (header.version >= 1) { - sessionId = decoder.decodeUInt32(); - exitStatus = decoder.decodeInt32(); - } - - var directoryTableBase; - if (header.version >= 3) - directoryTableBase = decoder.decodeUInteger(header.is64); - - var flags; - if (header.version >= 4) - flags = decoder.decodeUInt32(); - - var userSID = decoder.decodeSID(header.is64); - - var imageFileName; - if (header.version >= 1) - imageFileName = decoder.decodeString(); - - var commandLine; - if (header.version >= 2) - commandLine = decoder.decodeW16String(); - - var packageFullName; - var applicationId; - if (header.version >= 4) { - packageFullName = decoder.decodeW16String(); - applicationId = decoder.decodeW16String(); - } - - var exitTime; - if (header.version == 5 && header.opcode == kProcessDefunctOpcode) - exitTime = decoder.decodeUInt64ToString(); - - return { - pageDirectoryBase: pageDirectoryBase, - uniqueProcessKey: uniqueProcessKey, - processId: processId, - parentId: parentId, - sessionId: sessionId, - exitStatus: exitStatus, - directoryTableBase: directoryTableBase, - flags: flags, - userSID: userSID, - imageFileName: imageFileName, - commandLine: commandLine, - packageFullName: packageFullName, - applicationId: applicationId, - exitTime: exitTime - }; - }, - - decodeStart: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - var process = this.model.getOrCreateProcess(fields.processId); - if (process.hasOwnProperty('has_ended')) { - // On Windows, a process ID used by a process could be reused as soon as - // the process ends (there is no pid cycling like on Linux). However, in - // a short trace, this is unlikely to happen. - throw new Error('Process clash detected.'); - } - process.name = fields.imageFileName; - return true; - }, - - decodeEnd: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - var process = this.model.getOrCreateProcess(fields.processId); - process.has_ended = true; - return true; - }, - - decodeDCStart: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - var process = this.model.getOrCreateProcess(fields.processId); - if (process.hasOwnProperty('has_ended')) - throw new Error('Process clash detected.'); - process.name = fields.imageFileName; - return true; - }, - - decodeDCEnd: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - var process = this.model.getOrCreateProcess(fields.processId); - process.has_ended = true; - return true; - }, - - decodeDefunct: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - // TODO(etienneb): Update the Model with |fields|. - return true; - } - - }; - - Parser.register(ProcessParser); - - return { - ProcessParser: ProcessParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/process_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/process_parser_test.html deleted file mode 100644 index 3f98e83c08a..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/process_parser_test.html +++ /dev/null @@ -1,150 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/etw/etw_importer.html"> -<link rel="import" href="/tracing/extras/importer/etw/process_parser.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - // Constants for Process events. - var guid = '3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C'; - var kProcessStartOpcode = 1; - var kProcessDefunctOpcode = 39; - - var kProcessStartPayload32bitV1 = - 'AAAAAPAGAADcAwAAAQAAAAMBAAAAAAAAAAAAAAEFAAAAAAAFFQAAAJYs7Cxo/TEG8dyk0' + - '+gDAABub3RlcGFkLmV4ZQA='; - - var kProcessStartPayload32bitV2 = - 'AAAAAPAGAADcAwAAAQAAAAMBAAAAAAAAAAAAAAEFAAAAAAAFFQAAAJYs7Cxo/TEG8dyk0' + - '+gDAABub3RlcGFkLmV4ZQAiAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABzAHkAcwB0AGUAbQ' + - 'AzADIAXABuAG8AdABlAHAAYQBkAC4AZQB4AGUAIgAgAAAA'; - - var kProcessStartPayload32bitV3 = - 'AAAAAPAGAADcAwAAAQAAAAMBAAAAAAAAAAAAAAAAAAABBQAAAAAABRUAAACWLOwsaP0xB' + - 'vHcpNPoAwAAbm90ZXBhZC5leGUAIgBDADoAXABXAGkAbgBkAG8AdwBzAFwAcwB5AHMAdA' + - 'BlAG0AMwAyAFwAbgBvAHQAZQBwAGEAZAAuAGUAeABlACIAIAAAAA=='; - - var kProcessStartPayload64bitV3 = - 'YIBiD4D6//8AGgAAoBwAAAEAAAADAQAAAPBDHQEAAAAwVlMVoPj//wAAAACg+P//AQUAA' + - 'AAAAAUVAAAAAgMBAgMEBQYHCAkKCwwAAHhwZXJmLmV4ZQB4AHAAZQByAGYAIAAgAC0AZA' + - 'AgAG8AdQB0AC4AZQB0AGwAAAA='; - - var kProcessStartPayload64bitV4 = - 'gED8GgDg//+MCgAACBcAAAUAAAADAQAAALCiowAAAAAAAAAAkPBXBADA//8AAAAAAAAAA' + - 'AEFAAAAAAAFFQAAAAECAwQFBgcICQoLBukDAAB4cGVyZi5leGUAeABwAGUAcgBmACAAIA' + - 'AtAHMAdABvAHAAAAAAAAAA'; - - var kProcessDefunctPayload64bitV5 = - 'wMXyBgDg//9IGQAAEAgAAAEAAAAAAAAAAGDLTwAAAAAAAAAA8OU7AwDA//8AAAAAAAAMA' + - 'AEFAAAAAAAFFQAAAMDBwsPExcbH0NHS09QDAABjaHJvbWUuZXhlAAAAAAAAAI1Jovns+s' + - '4B'; - - test('DecodeFields', function() { - - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - var parser = new tr.e.importer.etw.ProcessParser(importer); - var header; - var fields; - - // Validate a version 1 32-bit payload. - header = { guid: guid, opcode: kProcessStartOpcode, version: 1, is64: 0 }; - decoder.reset(kProcessStartPayload32bitV1); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.pageDirectoryBase, 0); - assert.equal(fields.processId, 1776); - assert.equal(fields.parentId, 988); - assert.equal(fields.sessionId, 1); - assert.equal(fields.exitStatus, 259); - assert.strictEqual(fields.imageFileName, 'notepad.exe'); - - // Validate a version 2 32-bit payload. - header = { guid: guid, opcode: kProcessStartOpcode, version: 2, is64: 0 }; - decoder.reset(kProcessStartPayload32bitV2); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.uniqueProcessKey, 0); - assert.equal(fields.processId, 1776); - assert.equal(fields.parentId, 988); - assert.equal(fields.sessionId, 1); - assert.equal(fields.exitStatus, 259); - assert.strictEqual(fields.imageFileName, 'notepad.exe'); - assert.strictEqual(fields.commandLine, - '\"C:\\Windows\\system32\\notepad.exe\" '); - - // Validate a version 3 32-bit payload. - header = { guid: guid, opcode: kProcessStartOpcode, version: 3, is64: 0 }; - decoder.reset(kProcessStartPayload32bitV3); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.uniqueProcessKey, 0); - assert.equal(fields.processId, 1776); - assert.equal(fields.parentId, 988); - assert.equal(fields.sessionId, 1); - assert.equal(fields.exitStatus, 259); - assert.equal(fields.directoryTableBase, 0); - assert.strictEqual(fields.imageFileName, 'notepad.exe'); - assert.strictEqual(fields.commandLine, - '\"C:\\Windows\\system32\\notepad.exe\" '); - - // Validate a version 3 64-bit payload. - header = { guid: guid, opcode: kProcessStartOpcode, version: 3, is64: 1 }; - decoder.reset(kProcessStartPayload64bitV3); - fields = parser.decodeFields(header, decoder); - - assert.strictEqual(fields.uniqueProcessKey, 'fffffa800f628060'); - assert.equal(fields.processId, 6656); - assert.equal(fields.parentId, 7328); - assert.equal(fields.sessionId, 1); - assert.equal(fields.exitStatus, 259); - assert.strictEqual(fields.directoryTableBase, '000000011d43f000'); - assert.strictEqual(fields.imageFileName, 'xperf.exe'); - assert.strictEqual(fields.commandLine, 'xperf -d out.etl'); - - // Validate a version 4 64-bit payload. - header = { guid: guid, opcode: kProcessStartOpcode, version: 4, is64: 1 }; - decoder.reset(kProcessStartPayload64bitV4); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.uniqueProcessKey, 'ffffe0001afc4080'); - assert.equal(fields.processId, 2700); - assert.equal(fields.parentId, 5896); - assert.equal(fields.sessionId, 5); - assert.equal(fields.exitStatus, 259); - assert.equal(fields.directoryTableBase, '00000000a3a2b000'); - assert.equal(fields.flags, 0); - assert.strictEqual(fields.imageFileName, 'xperf.exe'); - assert.strictEqual(fields.commandLine, 'xperf -stop'); - assert.strictEqual(fields.packageFullName, ''); - assert.strictEqual(fields.applicationId, ''); - - // Validate a version 5 64-bit payload. - header = { guid: guid, opcode: kProcessDefunctOpcode, version: 5, is64: 1 }; - decoder.reset(kProcessDefunctPayload64bitV5); - fields = parser.decodeFields(header, decoder); - - assert.strictEqual(fields.uniqueProcessKey, 'ffffe00006f2c5c0'); - assert.equal(fields.processId, 6472); - assert.equal(fields.parentId, 2064); - assert.equal(fields.sessionId, 1); - assert.equal(fields.exitStatus, 0); - assert.strictEqual(fields.directoryTableBase, '000000004fcb6000'); - assert.equal(fields.flags, 0); - assert.strictEqual(fields.imageFileName, 'chrome.exe'); - assert.strictEqual(fields.commandLine, ''); - assert.strictEqual(fields.packageFullName, ''); - assert.strictEqual(fields.applicationId, ''); - assert.strictEqual(fields.exitTime, '01cefaecf9a2498d'); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/thread_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/thread_parser.html deleted file mode 100644 index d4f75d1e4e5..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/thread_parser.html +++ /dev/null @@ -1,243 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/extras/importer/etw/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses threads events in the Windows event trace format. - * - * The Windows thread events are: - * - * - DCStart: Describes a thread that was already running when the trace - * started. ETW automatically generates these events for all running - * threads at the beginning of the trace. - * - Start: Describes a thread that started during the tracing session. - * - End: Describes a thread that ended during the tracing session. - * - DCEnd: Describes a thread that was still alive when the trace ended. - * - * See http://msdn.microsoft.com/library/windows/desktop/aa364132.aspx - */ -tr.exportTo('tr.e.importer.etw', function() { - var Parser = tr.e.importer.etw.Parser; - - // Constants for Thread events. - var guid = '3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C'; - var kThreadStartOpcode = 1; - var kThreadEndOpcode = 2; - var kThreadDCStartOpcode = 3; - var kThreadDCEndOpcode = 4; - var kThreadCSwitchOpcode = 36; - - /** - * Parses Windows threads trace events. - * @constructor - */ - function ThreadParser(importer) { - Parser.call(this, importer); - - // Register handlers. - importer.registerEventHandler(guid, kThreadStartOpcode, - ThreadParser.prototype.decodeStart.bind(this)); - importer.registerEventHandler(guid, kThreadEndOpcode, - ThreadParser.prototype.decodeEnd.bind(this)); - importer.registerEventHandler(guid, kThreadDCStartOpcode, - ThreadParser.prototype.decodeDCStart.bind(this)); - importer.registerEventHandler(guid, kThreadDCEndOpcode, - ThreadParser.prototype.decodeDCEnd.bind(this)); - importer.registerEventHandler(guid, kThreadCSwitchOpcode, - ThreadParser.prototype.decodeCSwitch.bind(this)); - } - - ThreadParser.prototype = { - __proto__: Parser.prototype, - - decodeFields: function(header, decoder) { - if (header.version > 3) - throw new Error('Incompatible Thread event version.'); - - // Common fields to all Thread events. - var processId = decoder.decodeUInt32(); - var threadId = decoder.decodeUInt32(); - - // Extended fields. - var stackBase; - var stackLimit; - var userStackBase; - var userStackLimit; - var affinity; - var startAddr; - var win32StartAddr; - var tebBase; - var subProcessTag; - var basePriority; - var pagePriority; - var ioPriority; - var threadFlags; - var waitMode; - - if (header.version == 1) { - // On version 1, only start events have extended information. - if (header.opcode == kThreadStartOpcode || - header.opcode == kThreadDCStartOpcode) { - stackBase = decoder.decodeUInteger(header.is64); - stackLimit = decoder.decodeUInteger(header.is64); - userStackBase = decoder.decodeUInteger(header.is64); - userStackLimit = decoder.decodeUInteger(header.is64); - startAddr = decoder.decodeUInteger(header.is64); - win32StartAddr = decoder.decodeUInteger(header.is64); - waitMode = decoder.decodeInt8(); - decoder.skip(3); - } - } else { - stackBase = decoder.decodeUInteger(header.is64); - stackLimit = decoder.decodeUInteger(header.is64); - userStackBase = decoder.decodeUInteger(header.is64); - userStackLimit = decoder.decodeUInteger(header.is64); - - // Version 2 produces a field named 'startAddr'. - if (header.version == 2) - startAddr = decoder.decodeUInteger(header.is64); - else - affinity = decoder.decodeUInteger(header.is64); - - win32StartAddr = decoder.decodeUInteger(header.is64); - tebBase = decoder.decodeUInteger(header.is64); - subProcessTag = decoder.decodeUInt32(); - - if (header.version == 3) { - basePriority = decoder.decodeUInt8(); - pagePriority = decoder.decodeUInt8(); - ioPriority = decoder.decodeUInt8(); - threadFlags = decoder.decodeUInt8(); - } - } - - return { - processId: processId, - threadId: threadId, - stackBase: stackBase, - stackLimit: stackLimit, - userStackBase: userStackBase, - userStackLimit: userStackLimit, - affinity: affinity, - startAddr: startAddr, - win32StartAddr: win32StartAddr, - tebBase: tebBase, - subProcessTag: subProcessTag, - waitMode: waitMode, - basePriority: basePriority, - pagePriority: pagePriority, - ioPriority: ioPriority, - threadFlags: threadFlags - }; - }, - - decodeCSwitchFields: function(header, decoder) { - if (header.version != 2) - throw new Error('Incompatible Thread event version.'); - - // Decode CSwitch payload. - var newThreadId = decoder.decodeUInt32(); - var oldThreadId = decoder.decodeUInt32(); - var newThreadPriority = decoder.decodeInt8(); - var oldThreadPriority = decoder.decodeInt8(); - var previousCState = decoder.decodeUInt8(); - var spareByte = decoder.decodeInt8(); - var oldThreadWaitReason = decoder.decodeInt8(); - var oldThreadWaitMode = decoder.decodeInt8(); - var oldThreadState = decoder.decodeInt8(); - var oldThreadWaitIdealProcessor = decoder.decodeInt8(); - var newThreadWaitTime = decoder.decodeUInt32(); - var reserved = decoder.decodeUInt32(); - - return { - newThreadId: newThreadId, - oldThreadId: oldThreadId, - newThreadPriority: newThreadPriority, - oldThreadPriority: oldThreadPriority, - previousCState: previousCState, - spareByte: spareByte, - oldThreadWaitReason: oldThreadWaitReason, - oldThreadWaitMode: oldThreadWaitMode, - oldThreadState: oldThreadState, - oldThreadWaitIdealProcessor: oldThreadWaitIdealProcessor, - newThreadWaitTime: newThreadWaitTime, - reserved: reserved - }; - }, - - decodeStart: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - this.importer.createThreadIfNeeded(fields.processId, fields.threadId); - return true; - }, - - decodeEnd: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - this.importer.removeThreadIfPresent(fields.threadId); - return true; - }, - - decodeDCStart: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - this.importer.createThreadIfNeeded(fields.processId, fields.threadId); - return true; - }, - - decodeDCEnd: function(header, decoder) { - var fields = this.decodeFields(header, decoder); - this.importer.removeThreadIfPresent(fields.threadId); - return true; - }, - - decodeCSwitch: function(header, decoder) { - var fields = this.decodeCSwitchFields(header, decoder); - var cpu = this.importer.getOrCreateCpu(header.cpu); - var new_thread = - this.importer.getThreadFromWindowsTid(fields.newThreadId); - - // Generate the new thread name. If some events were lost, it's possible - // that information about the new thread or process is not available. - var new_thread_name; - if (new_thread && new_thread.userFriendlyName) { - new_thread_name = new_thread.userFriendlyName; - } else { - var new_process_id = this.importer.getPidFromWindowsTid( - fields.newThreadId); - var new_process = this.model.getProcess(new_process_id); - var new_process_name; - if (new_process) - new_process_name = new_process.name; - else - new_process_name = 'Unknown process'; - - new_thread_name = - new_process_name + ' (tid ' + fields.newThreadId + ')'; - } - - cpu.switchActiveThread( - header.timestamp, - {}, - fields.newThreadId, - new_thread_name, - fields); - return true; - } - - }; - - Parser.register(ThreadParser); - - return { - ThreadParser: ThreadParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/thread_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/thread_parser_test.html deleted file mode 100644 index 56031c6381f..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/etw/thread_parser_test.html +++ /dev/null @@ -1,179 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/etw/etw_importer.html"> -<link rel="import" href="/tracing/extras/importer/etw/thread_parser.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - - // Constants for Thread events. - var guid = '3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C'; - var kThreadStartOpcode = 1; - var kThreadEndOpcode = 2; - var kThreadDCStartOpcode = 3; - var kThreadCSwitchOpcode = 36; - - var kThreadStartPayload32bitV1 = - 'BAAAAEwHAAAAYLfzADC38wAAAAAAAAAAhdse9wAAAAD/AAAA'; - - var kThreadEndPayload32bitV1 = 'BAAAALQAAAA='; - - - var kThreadDCStartPayload64bitV2 = - 'AAAAAAAAAAAAYPUCAPj//wAA9QIA+P//AAAAAAAAAAAAAAAAAAAAAIAlxwEA+P//gCXHA' + - 'QD4//8AAAAAAAAAAAAAAAA='; - - var kThreadStartPayload32bitV3 = - 'LAIAACwTAAAAUJixACCYsQAA1QAAwNQAAwAAAOkDq3cA4P1/AAAAAAkFAgA='; - - var kThreadStartPayload64bitV3 = - 'eCEAAJQUAAAAMA4nAND//wDQDScA0P//MP0LBgAAAAAAgAsGAAAAAP8AAAAAAAAALP1YX' + - 'AAAAAAAwBL/AAAAAAAAAAAIBQIA'; - - var kThreadCSwitchPayload32bitV2 = 'AAAAACwRAAAACQAAFwABABIAAAAmSAAA'; - var kThreadCSwitchPayload64bitV2 = 'zAgAAAAAAAAIAAEAAAACBAEAAACHbYg0'; - - test('DecodeFields', function() { - - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - var parser = new tr.e.importer.etw.ThreadParser(importer); - var header; - var fields; - - // Validate a version 1 32-bit payload. - header = { guid: guid, opcode: kThreadStartOpcode, version: 1, is64: 0 }; - decoder.reset(kThreadStartPayload32bitV1); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.processId, 4); - assert.equal(fields.threadId, 1868); - assert.equal(fields.stackBase, 4088881152); - assert.equal(fields.stackLimit, 4088868864); - assert.equal(fields.userStackBase, 0); - assert.equal(fields.userStackLimit, 0); - assert.equal(fields.startAddr, 4145994629); - assert.equal(fields.win32StartAddr, 0); - assert.equal(fields.waitMode, -1); - - // Validate an End version 1 32-bit payload. - header = { guid: guid, opcode: kThreadEndOpcode, version: 1, is64: 0 }; - decoder.reset(kThreadStartPayload32bitV1); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.processId, 4); - assert.equal(fields.threadId, 1868); - - // Validate a version 2 64-bit payload. - header = { guid: guid, opcode: kThreadDCStartOpcode, version: 2, is64: 1 }; - decoder.reset(kThreadDCStartPayload64bitV2); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.processId, 0); - assert.equal(fields.threadId, 0); - assert.strictEqual(fields.stackBase, 'fffff80002f56000'); - assert.equal(fields.stackLimit, 'fffff80002f50000'); - assert.strictEqual(fields.userStackBase, '0000000000000000'); - assert.strictEqual(fields.userStackLimit, '0000000000000000'); - assert.strictEqual(fields.startAddr, 'fffff80001c72580'); - assert.strictEqual(fields.win32StartAddr, 'fffff80001c72580'); - assert.strictEqual(fields.tebBase, '0000000000000000'); - assert.equal(fields.subProcessTag, 0); - - // Validate a version 3 32-bit payload. - header = { guid: guid, opcode: kThreadStartOpcode, version: 3, is64: 0 }; - decoder.reset(kThreadStartPayload32bitV3); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.processId, 556); - assert.equal(fields.threadId, 4908); - assert.equal(fields.stackBase, 2979549184); - assert.equal(fields.stackLimit, 2979536896); - assert.equal(fields.userStackBase, 13959168); - assert.equal(fields.userStackLimit, 13942784); - assert.equal(fields.affinity, 3); - assert.equal(fields.win32StartAddr, 2007696361); - assert.equal(fields.tebBase, 2147344384); - assert.equal(fields.subProcessTag, 0); - assert.equal(fields.basePriority, 9); - assert.equal(fields.pagePriority, 5); - assert.equal(fields.ioPriority, 2); - assert.equal(fields.threadFlags, 0); - - // Validate a version 3 64-bit payload. - header = { guid: guid, opcode: kThreadStartOpcode, version: 3, is64: 1 }; - decoder.reset(kThreadStartPayload64bitV3); - fields = parser.decodeFields(header, decoder); - - assert.equal(fields.processId, 8568); - assert.equal(fields.threadId, 5268); - assert.strictEqual(fields.stackBase, 'ffffd000270e3000'); - assert.strictEqual(fields.stackLimit, 'ffffd000270dd000'); - assert.strictEqual(fields.userStackBase, '00000000060bfd30'); - assert.strictEqual(fields.userStackLimit, '00000000060b8000'); - assert.strictEqual(fields.affinity, '00000000000000ff'); - assert.strictEqual(fields.win32StartAddr, '000000005c58fd2c'); - assert.strictEqual(fields.tebBase, '00000000ff12c000'); - assert.equal(fields.subProcessTag, 0); - assert.equal(fields.basePriority, 8); - assert.equal(fields.pagePriority, 5); - assert.equal(fields.ioPriority, 2); - assert.equal(fields.threadFlags, 0); - }); - - test('DecodeCSwitchFields', function() { - var importer = new tr.e.importer.etw.EtwImporter('dummy', []); - var decoder = importer.decoder_; - var parser = new tr.e.importer.etw.ThreadParser(importer); - var header; - var fields; - - - // Validate a version 2 CSwitch 32-bit payload. - header = { guid: guid, opcode: kThreadCSwitchOpcode, version: 2, is64: 0 }; - decoder.reset(kThreadCSwitchPayload32bitV2); - fields = parser.decodeCSwitchFields(header, decoder); - - assert.equal(fields.newThreadId, 0); - assert.equal(fields.oldThreadId, 4396); - assert.equal(fields.newThreadPriority, 0); - assert.equal(fields.oldThreadPriority, 9); - assert.equal(fields.previousCState, 0); - assert.equal(fields.spareByte, 0); - assert.equal(fields.oldThreadWaitReason, 23); - assert.equal(fields.oldThreadWaitMode, 0); - assert.equal(fields.oldThreadState, 1); - assert.equal(fields.oldThreadWaitIdealProcessor, 0); - assert.equal(fields.newThreadWaitTime, 18); - assert.equal(fields.reserved, 18470); - - // Validate a version 2 CSwitch 64-bit payload. - header = { guid: guid, opcode: kThreadCSwitchOpcode, version: 2, is64: 1 }; - decoder.reset(kThreadCSwitchPayload64bitV2); - fields = parser.decodeCSwitchFields(header, decoder); - - assert.equal(fields.newThreadId, 2252); - assert.equal(fields.oldThreadId, 0); - assert.equal(fields.newThreadPriority, 8); - assert.equal(fields.oldThreadPriority, 0); - assert.equal(fields.previousCState, 1); - assert.equal(fields.spareByte, 0); - assert.equal(fields.oldThreadWaitReason, 0); - assert.equal(fields.oldThreadWaitMode, 0); - assert.equal(fields.oldThreadState, 2); - assert.equal(fields.oldThreadWaitIdealProcessor, 4); - assert.equal(fields.newThreadWaitTime, 1); - assert.equal(fields.reserved, 881356167); - - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/gcloud_trace/gcloud_trace_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/gcloud_trace/gcloud_trace_importer.html deleted file mode 100644 index b110a7e6c82..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/gcloud_trace/gcloud_trace_importer.html +++ /dev/null @@ -1,99 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/importer/importer.html"> - -<script> - -'use strict'; - -/** - * @fileoverview GcloudTraceImporter imports JSON data from Google Cloud Trace. - */ -tr.exportTo('tr.e.importer.gcloud_trace', function() { - function GcloudTraceImporter(model, eventData) { - this.importPriority = 2; - this.eventData_ = eventData; - } - - /** - * @return {boolean} Whether obj looks like the JSON output from Cloud Trace. - */ - GcloudTraceImporter.canImport = function(eventData) { - if (typeof(eventData) !== 'string' && !(eventData instanceof String)) - return false; - - // Slice the data so we don't potentially do a replace on a gigantic string. - var normalizedEventData = eventData.slice(0, 20).replace(/\s/g, ''); - if (normalizedEventData.length < 14) - return false; - - return normalizedEventData.slice(0, 14) == '{"projectId":"'; - }; - - GcloudTraceImporter.prototype = { - - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'GcloudTraceImporter'; - }, - - /** - * Called by the Model to extract subtraces from the event data. The - * subtraces are passed on to other importers that can recognize them. - */ - extractSubtraces: function() { - var traceEvents = this.createEventsForTrace(); - return traceEvents ? [traceEvents] : []; - }, - - createEventsForTrace: function() { - var events = []; - var trace = JSON.parse(this.eventData_); - var spanLength = trace.spans.length; - for (var i = 0; i < spanLength; i++) { - events.push(this.createEventForSpan(trace.traceId, trace.spans[i])); - } - return { - 'traceEvents': events - }; - }, - - createEventForSpan: function(traceId, span) { - var newArgs = {}; - if (span.labels) { - newArgs = JSON.parse(JSON.stringify(span.labels)); - } - newArgs['Span ID'] = span.spanId; - newArgs['Start Time'] = span.startTime; - newArgs['End Time'] = span.endTime; - if (span.parentSpanId) { - newArgs['Parent Span ID'] = span.parentSpanId; - } - // The timestamps are ISO-standard strings, which are parsed to millis, - // then converted to the micros that the trace viewer expects. - return { - name: span.name, - args: newArgs, - pid: traceId, - ts: Date.parse(span.startTime) * 1000, - dur: (Date.parse(span.endTime) - Date.parse(span.startTime)) * 1000, - cat: 'tracespan', - tid: traceId, - ph: 'X' - }; - } - }; - - tr.importer.Importer.register(GcloudTraceImporter); - - return { - GcloudTraceImporter: GcloudTraceImporter - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/gcloud_trace/gcloud_trace_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/gcloud_trace/gcloud_trace_importer_test.html deleted file mode 100644 index 2c229ffc31c..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/gcloud_trace/gcloud_trace_importer_test.html +++ /dev/null @@ -1,99 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/model/model.html"> -<link rel="import" href="/tracing/extras/importer/trace_event_importer.html"> -<link rel="import" href="/tracing/extras/importer/gcloud_trace/gcloud_trace_importer.html"> - -<script> - -'use strict'; - -tr.b.unittest.testSuite(function() { - var GcloudTraceImporter = tr.e.importer.gcloud_trace.GcloudTraceImporter; - - test('noSpans', function() { - var trace = {projectId: 'My Project', traceId: '123', spans: []}; - - var model = new tr.Model(); - var importer = new tr.e.importer.gcloud_trace.GcloudTraceImporter(model, - JSON.stringify(trace)); - var subtraces = importer.extractSubtraces(); - assert.equal(1, subtraces.length); - // Note there are, in fact, use cases for traces with no events (spans). - assert.deepEqual([], subtraces[0].traceEvents); - }); - - test('typicalTrace', function() { - var span1 = { - 'spanId': '1', - 'kind': 'RPC_CLIENT', - 'name': '/first', - 'startTime': '2015-09-03T16:40:00.841654024Z', - 'endTime': '2015-09-03T16:40:00.856599389Z', - 'labels': { - 'key1': 'value1', - 'key2': 'value2' - } - }; - var span2 = { - 'spanId': '2', - 'kind': 'RPC_SERVER', - 'name': '/second', - 'startTime': '2015-09-03T16:40:00.842880028Z', - 'endTime': '2015-09-03T16:40:00.851729538Z', - 'parentSpanId': '1', - 'labels': { - 'key1': 'value3', - 'key2': 'value4' - } - }; - var trace = {projectId: 'My Project', traceId: '123', - spans: [span1, span2]}; - - var model = new tr.Model(); - var importer = new tr.e.importer.gcloud_trace.GcloudTraceImporter(model, - JSON.stringify(trace)); - var subtraces = importer.extractSubtraces(); - assert.equal(1, subtraces.length); - assert.equal(2, subtraces[0].traceEvents.length); - - var span1Event = subtraces[0].traceEvents[0]; - assert.equal('tracespan', span1Event.cat); - assert.equal('/first', span1Event.name); - assert.equal(1441298400841000, span1Event.ts); - assert.equal(15000, span1Event.dur); - assert.equal('123', span1Event.pid); - assert.equal('123', span1Event.tid); - assert.equal('2015-09-03T16:40:00.856599389Z', span1Event.args['End Time']); - assert.equal('1', span1Event.args['Span ID']); - assert.equal('value1', span1Event.args['key1']); - assert.equal('value2', span1Event.args['key2']); - assert.equal('2015-09-03T16:40:00.856599389Z', span1Event.args['End Time']); - - var span2Event = subtraces[0].traceEvents[1]; - assert.equal('tracespan', span2Event.cat); - assert.equal('/second', span2Event.name); - assert.equal(1441298400842000, span2Event.ts); - assert.equal(9000, span2Event.dur); - assert.equal('123', span2Event.pid); - assert.equal('123', span2Event.tid); - }); - - test('canImport', function() { - assert.isTrue(GcloudTraceImporter.canImport( - JSON.stringify({projectId: 'My Project'}))); - assert.isTrue(GcloudTraceImporter.canImport( - JSON.stringify({projectId: '56', traceId: '34'}))); - assert.isFalse(GcloudTraceImporter.canImport( - JSON.stringify({wrongjson: '33'}))); - assert.isFalse(GcloudTraceImporter.canImport('')); - assert.isFalse(GcloudTraceImporter.canImport([])); - }); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/gzip_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/gzip_importer.html deleted file mode 100644 index 8dfd2f199d2..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/gzip_importer.html +++ /dev/null @@ -1,188 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/extras/importer/jszip.html"> -<link rel="import" href="/tracing/importer/importer.html"> -<link rel="import" href="/tracing/model/model.html"> - -<script> -'use strict'; - -/** - * @fileoverview GzipImporter inflates gzip compressed data and passes it along - * to an actual importer. - */ -tr.exportTo('tr.e.importer', function() { - var GZIP_MEMBER_HEADER_ID_SIZE = 3; - - var GZIP_HEADER_ID1 = 0x1f; - var GZIP_HEADER_ID2 = 0x8b; - var GZIP_DEFLATE_COMPRESSION = 8; - - function GzipImporter(model, eventData) { - // Normalize the data into an Uint8Array. - if (typeof(eventData) === 'string' || eventData instanceof String) { - eventData = JSZip.utils.transformTo('uint8array', eventData); - } else if (eventData instanceof ArrayBuffer) { - eventData = new Uint8Array(eventData); - } else - throw new Error('Unknown gzip data format'); - this.model_ = model; - this.gzipData_ = eventData; - } - - /** - * @param {eventData} Possibly gzip compressed data as a string or an - * ArrayBuffer. - * @return {boolean} Whether obj looks like gzip compressed data. - */ - GzipImporter.canImport = function(eventData) { - var header; - if (eventData instanceof ArrayBuffer) - header = new Uint8Array(eventData.slice(0, GZIP_MEMBER_HEADER_ID_SIZE)); - else if (typeof(eventData) === 'string' || eventData instanceof String) { - header = eventData.substring(0, GZIP_MEMBER_HEADER_ID_SIZE); - // Convert the string to a byteArray for correct value comparison. - header = JSZip.utils.transformTo('uint8array', header); - } else - return false; - return header[0] == GZIP_HEADER_ID1 && - header[1] == GZIP_HEADER_ID2 && - header[2] == GZIP_DEFLATE_COMPRESSION; - }; - - /** - * Inflates (decompresses) the data stored in the given gzip bitstream. - * @return {string} Inflated data. - */ - GzipImporter.inflateGzipData_ = function(data) { - var position = 0; - - function getByte() { - if (position >= data.length) - throw new Error('Unexpected end of gzip data'); - return data[position++]; - } - - function getWord() { - var low = getByte(); - var high = getByte(); - return (high << 8) + low; - } - - function skipBytes(amount) { - position += amount; - } - - function skipZeroTerminatedString() { - while (getByte() != 0) {} - } - - var id1 = getByte(); - var id2 = getByte(); - if (id1 !== GZIP_HEADER_ID1 || id2 !== GZIP_HEADER_ID2) - throw new Error('Not gzip data'); - var compression_method = getByte(); - if (compression_method !== GZIP_DEFLATE_COMPRESSION) - throw new Error('Unsupported compression method: ' + compression_method); - var flags = getByte(); - var have_header_crc = flags & (1 << 1); - var have_extra_fields = flags & (1 << 2); - var have_file_name = flags & (1 << 3); - var have_comment = flags & (1 << 4); - - // Skip modification time, extra flags and OS. - skipBytes(4 + 1 + 1); - - // Skip remaining fields before compressed data. - if (have_extra_fields) { - var bytes_to_skip = getWord(); - skipBytes(bytes_to_skip); - } - if (have_file_name) - skipZeroTerminatedString(); - if (have_comment) - skipZeroTerminatedString(); - if (have_header_crc) - getWord(); - - // Inflate the data using jszip. - var inflated_data = - JSZip.compressions['DEFLATE'].uncompress(data.subarray(position)); - var string = GzipImporter.transformToString(inflated_data); - - if (inflated_data.length > 0 && string.length === 0) { - throw new RangeError('Inflated gzip data too long to fit into a string' + - ' (' + inflated_data.length + ').'); - } - - return string; - }; - - /** - * Transforms an array-like object to a string. - * - * Note that the following two expressions yield identical results: - * - * GzipImporter.transformToString_(data) - * JSZip.utils.transformTo('string', data) - * - * We use a custom static method because it is faster and, more importantly, - * avoids OOMing on large traces. See - * https://github.com/catapult-project/catapult/issues/2051. - */ - GzipImporter.transformToString = function(data) { - if (typeof TextDecoder === 'undefined') { - // Fall back to jszip if TextDecoder is not available. - return JSZip.utils.transformTo('string', data); - } - - var type = JSZip.utils.getTypeOf(data); - if (type === 'string') - return data; // We already have a string. - - if (type === 'array') { - // TextDecoder requires an ArrayBuffer or an ArrayBufferView. - data = new Uint8Array(data); - } - - var decoder = new TextDecoder('utf-8'); - return decoder.decode(data); - }; - - GzipImporter.prototype = { - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'GzipImporter'; - }, - - /** - * Called by the Model to check whether the importer just encapsulates - * the actual trace data which needs to be imported by another importer. - */ - isTraceDataContainer: function() { - return true; - }, - - /** - * Called by the Model to extract subtraces from the event data. The - * subtraces are passed on to other importers that can recognize them. - */ - extractSubtraces: function() { - var eventData = GzipImporter.inflateGzipData_(this.gzipData_); - return eventData ? [eventData] : []; - } - }; - - tr.importer.Importer.register(GzipImporter); - - return { - GzipImporter: GzipImporter - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/gzip_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/gzip_importer_test.html deleted file mode 100644 index f226aae6813..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/gzip_importer_test.html +++ /dev/null @@ -1,105 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/base/base64.html"> -<link rel="import" href="/tracing/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/gzip_importer.html"> -<link rel="import" href="/tracing/extras/importer/trace_event_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - var Base64 = tr.b.Base64; - var findSliceNamed = tr.c.TestUtils.findSliceNamed; - var original_data = - '[{"name":"a","args":{},"pid":52,"ts":520,"cat":"foo","tid":53,' + - '"ph":"B"},{"name":"a","args":{},"pid":52,"ts":520,"cat":"foo",' + - '"tid":53,"ph":"E"}]\n'; - var gzip_data_base64 = - 'H4sICHr4HVIAA3RyYWNlAIuuVspLzE1VslJKVNJRSixKL1ayqq7VUSrITFGy' + - 'MjXSUSopBtEGOkrJiSVAVWn5+UB1JWBZY6CyDKCYk1KtDhWMcVWqjeUCALak' + - 'EH+QAAAA'; - - test('failImportEmpty', function() { - assert.isFalse(tr.e.importer.GzipImporter.canImport([])); - assert.isFalse(tr.e.importer.GzipImporter.canImport('')); - }); - - test('inflateString', function() { - // Test inflating the data from a string. - var gzip_data = Base64.atob(gzip_data_base64); - var importer = new tr.e.importer.GzipImporter(null, gzip_data); - assert.isTrue(tr.e.importer.GzipImporter.canImport(gzip_data)); - assert.equal(importer.extractSubtraces()[0], original_data); - }); - - test('inflateArrayBuffer', function() { - // Test inflating the data from an ArrayBuffer. - var gzip_data = Base64.atob(gzip_data_base64); - var buffer = new ArrayBuffer(gzip_data.length); - var view = new Uint8Array(buffer); - for (var i = 0; i < gzip_data.length; i++) - view[i] = gzip_data.charCodeAt(i); - var importer = new tr.e.importer.GzipImporter(null, buffer); - assert.isTrue(tr.e.importer.GzipImporter.canImport(buffer)); - assert.equal(importer.extractSubtraces()[0], original_data); - }); - - test('import', function() { - var gzip_data = Base64.atob(gzip_data_base64); - assert.isTrue(tr.e.importer.GzipImporter.canImport(gzip_data)); - - var model = tr.c.TestUtils.newModelWithEvents(gzip_data); - var threads = model.getAllThreads(); - assert.equal(threads.length, 1); - - var slice = findSliceNamed(threads[0].sliceGroup, 'a'); - assert.equal(slice.category, 'foo'); - }); - - test('transformToString', function() { - function checkTransform(data, expectedString) { - assert.strictEqual(tr.e.importer.GzipImporter.transformToString(data), - expectedString); - } - - function createArrayBuffer(values) { - var buffer = new ArrayBuffer(values.length); - var view = new Uint8Array(buffer); - view.set(values); - return buffer; - } - - // If the browser supports TextDecoder, this will test our custom - // implementation. Otherwise, the jszip fallback will be tested. - checkTransform('abc012', 'abc012'); - checkTransform([100, 101, 102, 51, 52, 53], 'def345'); - checkTransform(createArrayBuffer([103, 104, 105, 54, 55, 56]), 'ghi678'); - checkTransform(new Uint8Array([106, 107, 108, 57, 58, 59]), 'jkl9:;'); - - if (typeof TextDecoder === 'undefined') { - // The browser doesn't support TextDecoder, so we have already checked - // the jszip fallback. - return; - } - - // The browser supports TextDecoder, so we now check the jszip fallback. - var oldTextDecoder = TextDecoder; - TextDecoder = undefined; - try { - checkTransform('abc012', 'abc012'); - checkTransform([100, 101, 102, 51, 52, 53], 'def345'); - checkTransform(createArrayBuffer([103, 104, 105, 54, 55, 56]), 'ghi678'); - checkTransform(new Uint8Array([106, 107, 108, 57, 58, 59]), 'jkl9:;'); - } finally { - TextDecoder = oldTextDecoder; - } - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/jszip.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/jszip.html deleted file mode 100644 index 0840c06ff74..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/jszip.html +++ /dev/null @@ -1,35 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/base/base.html"> - -<script> -'use strict'; -// Vinn workaround for JSzip requiring window. -if (tr.isVinn) { - /** - * Hack. - */ - global.window = {}; -} -</script> -<script src="/jszip.min.js"></script> -<script> -'use strict'; -// Vinn workaround for JSzip requiring window. -if (tr.isVinn) { - /** - * Hack. - */ - global.JSZip = global.window.JSZip; - global.window = undefined; -} else if (tr.isNode) { - var jsZipAbsPath = HTMLImportsLoader.hrefToAbsolutePath( - '/jszip.min.js'); - var jsZipModule = require(jsZipAbsPath); - global.JSZip = jsZipModule; -} -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/android_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/android_parser.html deleted file mode 100644 index 5e9dda90f42..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/android_parser.html +++ /dev/null @@ -1,240 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> -<link rel="import" href="/tracing/model/counter_series.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses trace_marker events that were inserted in the trace by - * userland. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux trace mark events that were inserted in the trace by userland. - * @constructor - */ - function AndroidParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('tracing_mark_write:android', - AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this)); - importer.registerEventHandler('0:android', - AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this)); - - this.model_ = importer.model_; - this.ppids_ = {}; - } - - function parseArgs(argsString) { - var args = {}; - if (argsString) { - var argsArray = argsString.split(';'); - for (var i = 0; i < argsArray.length; ++i) { - var parts = argsArray[i].split('='); - if (parts[0]) - args[parts.shift()] = parts.join('='); - } - } - return args; - } - - AndroidParser.prototype = { - __proto__: Parser.prototype, - - openAsyncSlice: function(thread, category, name, cookie, ts, args) { - var asyncSliceConstructor = - tr.model.AsyncSlice.getConstructor( - category, name); - var slice = new asyncSliceConstructor( - category, name, - ColorScheme.getColorIdForGeneralPurposeString(name), ts, args); - var key = category + ':' + name + ':' + cookie; - slice.id = cookie; - slice.startThread = thread; - - if (!this.openAsyncSlices) { - this.openAsyncSlices = { }; - } - this.openAsyncSlices[key] = slice; - }, - - closeAsyncSlice: function(thread, category, name, cookie, ts, args) { - if (!this.openAsyncSlices) { - // No async slices have been started. - return; - } - - var key = category + ':' + name + ':' + cookie; - var slice = this.openAsyncSlices[key]; - if (!slice) { - // No async slices w/ this key have been started. - return; - } - - for (var arg in args) { - if (slice.args[arg] !== undefined) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Both the S and F events of ' + slice.title + - ' provided values for argument ' + arg + '.' + - ' The value of the F event will be used.' - }); - } - slice.args[arg] = args[arg]; - } - - slice.endThread = thread; - slice.duration = ts - slice.start; - slice.startThread.asyncSliceGroup.push(slice); - slice.subSlices = [new tr.model.AsyncSlice(slice.category, - slice.title, slice.colorId, slice.start, slice.args, slice.duration)]; - delete this.openAsyncSlices[key]; - }, - - traceMarkWriteAndroidEvent: function(eventName, cpuNumber, pid, ts, - eventBase) { - var eventData = eventBase.details.split('|'); - switch (eventData[0]) { - case 'B': - var ppid = parseInt(eventData[1]); - var title = eventData[2]; - var args = parseArgs(eventData[3]); - var category = eventData[4]; - if (category === undefined) - category = 'android'; - - var thread = this.model_.getOrCreateProcess(ppid) - .getOrCreateThread(pid); - thread.name = eventBase.threadName; - if (!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Timestamps are moving backward.' - }); - return false; - } - - this.ppids_[pid] = ppid; - thread.sliceGroup.beginSlice(category, title, ts, args); - - break; - - case 'E': - var ppid = this.ppids_[pid]; - if (ppid === undefined) { - // Silently ignore unmatched E events. - break; - } - - var thread = this.model_.getOrCreateProcess(ppid) - .getOrCreateThread(pid); - if (!thread.sliceGroup.openSliceCount) { - // Silently ignore unmatched E events. - break; - } - - var slice = thread.sliceGroup.endSlice(ts); - - var args = parseArgs(eventData[3]); - for (var arg in args) { - if (slice.args[arg] !== undefined) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Both the B and E events of ' + slice.title + - ' provided values for argument ' + arg + '.' + - ' The value of the E event will be used.' - }); - } - slice.args[arg] = args[arg]; - } - - break; - - case 'C': - var ppid = parseInt(eventData[1]); - var name = eventData[2]; - var value = parseInt(eventData[3]); - var category = eventData[4]; - if (category === undefined) - category = 'android'; - - var ctr = this.model_.getOrCreateProcess(ppid) - .getOrCreateCounter(category, name); - // Initialize the counter's series fields if needed. - if (ctr.numSeries === 0) { - ctr.addSeries(new tr.model.CounterSeries(value, - ColorScheme.getColorIdForGeneralPurposeString( - ctr.name + '.' + 'value'))); - } - - ctr.series.forEach(function(series) { - series.addCounterSample(ts, value); - }); - - break; - - case 'S': - var ppid = parseInt(eventData[1]); - var name = eventData[2]; - var cookie = parseInt(eventData[3]); - var args = parseArgs(eventData[4]); - var category = eventData[5]; - if (category === undefined) - category = 'android'; - - - var thread = this.model_.getOrCreateProcess(ppid) - .getOrCreateThread(pid); - thread.name = eventBase.threadName; - - this.ppids_[pid] = ppid; - this.openAsyncSlice(thread, category, name, cookie, ts, args); - - break; - - case 'F': - // Note: An async slice may end on a different thread from the one - // that started it so this thread may not have been seen yet. - var ppid = parseInt(eventData[1]); - - var name = eventData[2]; - var cookie = parseInt(eventData[3]); - var args = parseArgs(eventData[4]); - var category = eventData[5]; - if (category === undefined) - category = 'android'; - - var thread = this.model_.getOrCreateProcess(ppid) - .getOrCreateThread(pid); - thread.name = eventBase.threadName; - - this.ppids_[pid] = ppid; - this.closeAsyncSlice(thread, category, name, cookie, ts, args); - - break; - - default: - return false; - } - - return true; - } - }; - - Parser.register(AndroidParser); - - return { - AndroidParser: AndroidParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/android_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/android_parser_test.html deleted file mode 100644 index ddc5ba99823..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/android_parser_test.html +++ /dev/null @@ -1,230 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('androidUserlandImport', function() { - var lines = [ - 'SurfaceFlinger-4831 [001] ...1 80909.598554: tracing_mark_write: B|4829|onMessageReceived', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598572: tracing_mark_write: B|4829|handleMessageInvalidate', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598590: tracing_mark_write: B|4829|latchBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598604: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598627: tracing_mark_write: B|4829|latchBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598651: tracing_mark_write: B|4829|updateTexImage', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598675: tracing_mark_write: B|4829|acquireBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598695: tracing_mark_write: B|4829|' + // @suppress longLineCheck - 'com.android.launcher/com.android.launcher2.Launcher: 0', - 'SurfaceFlinger-4831 [001] ...1 80909.598709: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598733: tracing_mark_write: C|4829|' + // @suppress longLineCheck - 'com.android.launcher/com.android.launcher2.Launcher|0', - 'SurfaceFlinger-4831 [001] ...1 80909.598746: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598844: tracing_mark_write: B|4829|releaseBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598862: tracing_mark_write: B|4829|' + // @suppress longLineCheck - 'com.android.launcher/com.android.launcher2.Launcher: 2', - 'SurfaceFlinger-4831 [001] ...1 80909.598876: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598892: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598925: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598955: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598988: tracing_mark_write: B|4829|latchBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.599001: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.599021: tracing_mark_write: B|4829|latchBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.599036: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.599068: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.599087: tracing_mark_write: E', - 'SurfaceFlinger-4831 [001] ...1 80909.599104: tracing_mark_write: E' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.parent.pid, 4829); - assert.equal(thread.tid, 4831); - assert.equal(thread.name, 'SurfaceFlinger'); - assert.equal(thread.sliceGroup.length, 11); - }); - - test('androidUserlandImportWithSpacesInThreadName', function() { - var lines = [ - 'Surface Flinger -4831 [001] ...1 80909.598590: tracing_mark_write: B|4829|latchBuffer', // @suppress longLineCheck - 'Surface Flinger -4831 [001] ...1 80909.598604: tracing_mark_write: E' // @suppress longLineCheck - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.parent.pid, 4829); - assert.equal(thread.tid, 4831); - assert.equal(thread.name, 'Surface Flinger '); - assert.equal(thread.sliceGroup.length, 1); - }); - - test('androidAsyncUserlandImport', function() { - var lines = [ - 'ndroid.launcher-9649 ( 9649) [000] ...1 1990280.663276: ' + - 'tracing_mark_write: S|9649|animator:childrenOutlineAlpha|' + - '1113053968', - 'ndroid.launcher-9649 ( 9649) [000] ...1 1990280.781445: ' + - 'tracing_mark_write: F|9649|animator:childrenOutlineAlpha|' + - '1113053968' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.parent.pid, 9649); - assert.equal(thread.tid, 9649); - assert.equal(thread.name, 'ndroid.launcher'); - assert.equal(thread.sliceGroup.length, 0); - assert.equal(thread.asyncSliceGroup.length, 1); - - var slice = thread.asyncSliceGroup.slices[0]; - assert.equal(slice.title, 'animator:childrenOutlineAlpha'); - assert.closeTo(118.169, slice.duration, 1e-5); - }); - - test('androidUserlandLegacyKernelImport', function() { - var lines = [ - 'SurfaceFlinger-4831 [001] ...1 80909.598554: 0: B|4829|onMessageReceived', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598572: 0: B|4829|handleMessageInvalidate', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598590: 0: B|4829|latchBuffer', - 'SurfaceFlinger-4831 [001] ...1 80909.598604: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598627: 0: B|4829|latchBuffer', - 'SurfaceFlinger-4831 [001] ...1 80909.598651: 0: B|4829|updateTexImage', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598675: 0: B|4829|acquireBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598695: 0: B|4829|' + - 'com.android.launcher/com.android.launcher2.Launcher: 0', - 'SurfaceFlinger-4831 [001] ...1 80909.598709: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598733: 0: C|4829|' + - 'com.android.launcher/com.android.launcher2.Launcher|0', - 'SurfaceFlinger-4831 [001] ...1 80909.598746: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598844: 0: B|4829|releaseBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.598862: 0: B|4829|' + - 'com.android.launcher/com.android.launcher2.Launcher: 2', - 'SurfaceFlinger-4831 [001] ...1 80909.598876: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598892: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598925: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598955: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.598988: 0: B|4829|latchBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.599001: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.599021: 0: B|4829|latchBuffer', // @suppress longLineCheck - 'SurfaceFlinger-4831 [001] ...1 80909.599036: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.599068: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.599087: 0: E', - 'SurfaceFlinger-4831 [001] ...1 80909.599104: 0: E' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.parent.pid, 4829); - assert.equal(thread.tid, 4831); - assert.equal(thread.name, 'SurfaceFlinger'); - assert.equal(thread.sliceGroup.length, 11); - }); - - test('androidUserlandChromiumImport', function() { - var lines = [ - 'SandboxedProces-2894 [001] ...1 253.780659: tracing_mark_write: B|2867|DoWorkLoop|arg1=1|cat1', // @suppress longLineCheck - 'SandboxedProces-2894 [001] ...1 253.780671: tracing_mark_write: B|2867|DeferOrRunPendingTask|source=test=test;task=xyz|cat2', // @suppress longLineCheck - 'SandboxedProces-2894 [001] ...1 253.780671: tracing_mark_write: E|2867|DeferOrRunPendingTask||cat1', // @suppress longLineCheck - 'SandboxedProces-2894 [001] ...1 253.780686: tracing_mark_write: B|2867|MessageLoop::RunTask|source=ipc/ipc_sync_message_filter.cc:Send|cat2', // @suppress longLineCheck - 'SandboxedProces-2894 [001] ...1 253.780700: tracing_mark_write: E|2867|MessageLoop::RunTask||cat1', // @suppress longLineCheck - 'SandboxedProces-2894 [001] ...1 253.780750: tracing_mark_write: C|2867|counter1|10|cat1', // @suppress longLineCheck - 'SandboxedProces-2894 [001] ...1 253.780859: tracing_mark_write: E|2867|DoWorkLoop|arg2=2|cat2', // @suppress longLineCheck - 'SandboxedProces-2894 [000] ...1 255.663276: tracing_mark_write: S|2867|async|1113053968|arg1=1;arg2=2|cat1', // @suppress longLineCheck - 'SandboxedProces-2894 [000] ...1 255.663276: tracing_mark_write: F|2867|async|1113053968|arg3=3|cat1', // @suppress longLineCheck - 'SandboxedProces-2894 [000] ...1 255.663276: tracing_mark_write: trace_event_clock_sync: parent_ts=128' // @suppress longLineCheck - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.parent.pid, 2867); - assert.equal(thread.tid, 2894); - assert.equal(thread.name, 'SandboxedProces'); - assert.equal(thread.sliceGroup.length, 3); - - assert.equal(thread.sliceGroup.slices[0].args['arg1'], '1'); - assert.equal(thread.sliceGroup.slices[0].args['arg2'], '2'); - - assert.equal(thread.sliceGroup.slices[1].args['source'], 'test=test'); - assert.equal(thread.sliceGroup.slices[1].category, 'cat2'); - assert.equal('DeferOrRunPendingTask', - thread.sliceGroup.slices[1].title); - assert.equal(thread.sliceGroup.slices[1].args['task'], 'xyz'); - - assert.equal('ipc/ipc_sync_message_filter.cc:Send', - thread.sliceGroup.slices[2].args['source']); - - assert.equal(thread.asyncSliceGroup.length, 1); - assert.equal(thread.asyncSliceGroup.slices[0].args['arg1'], '1'); - assert.equal(thread.asyncSliceGroup.slices[0].args['arg2'], '2'); - assert.equal(thread.asyncSliceGroup.slices[0].args['arg3'], '3'); - - var counters = m.getAllCounters(); - assert.equal(counters.length, 1); - assert.equal(counters[0].category, 'cat1'); - assert.equal(counters[0].name, 'counter1'); - - assert.equal(counters[0].numSamples, 1); - assert.equal(counters[0].getSeries(0).getSample(0).value, 10); - - assert.equal(Math.round((253.780659 - (255.663276 - 128)) * 1000), - Math.round(thread.sliceGroup.slices[0].start)); - }); - - test('androidNeedReschedImport', function() { - var lines = [ - 'RenderThread-3894 [001] ...1 253.780659: tracing_mark_write: B|3586|DrawFrame', // @suppress longLineCheck - 'RenderThread-3894 [001] ...1 253.780671: tracing_mark_write: B|3586|waitForTask', // @suppress longLineCheck - 'RenderThread-3894 [001] .N.1 253.780671: tracing_mark_write: E', // @suppress longLineCheck - 'RenderThread-3894 [001] ...1 253.780671: tracing_mark_write: B|3586|waitForTask', // @suppress longLineCheck - 'RenderThread-3894 [001] .n.1 253.780671: tracing_mark_write: E', // @suppress longLineCheck - 'RenderThread-3894 [001] ...1 253.780671: tracing_mark_write: B|3586|waitForTask', // @suppress longLineCheck - 'RenderThread-3894 [001] .p.1 253.780671: tracing_mark_write: E', // @suppress longLineCheck - 'RenderThread-3894 [001] ...1 253.780686: tracing_mark_write: E' // @suppress longLineCheck - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings, 'hasImportWarnings'); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.parent.pid, 3586); - assert.equal(thread.tid, 3894); - assert.equal(thread.name, 'RenderThread'); - assert.equal(thread.sliceGroup.length, 4); - }); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/binder_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/binder_parser.html deleted file mode 100644 index 4cebf557bdf..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/binder_parser.html +++ /dev/null @@ -1,694 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses Binder events - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - // Matches binder transactions: - // transaction=%d dest_node=%d dest_proc=%d dest_thread=%d reply=%d flags=0x%x - // code=0x%x - var binderTransRE = new RegExp('transaction=(\\d+) dest_node=(\\d+) ' + - 'dest_proc=(\\d+) dest_thread=(\\d+) ' + - 'reply=(\\d+) flags=(0x[0-9a-fA-F]+) ' + - 'code=(0x[0-9a-fA-F]+)'); - - var binderTransReceivedRE = /transaction=(\d+)/; - - function isBinderThread(name) { - return (name.indexOf('Binder') > -1); - } - - // Taken from kernel source: include/uapi/linux/android/binder.h. - var TF_ONE_WAY = 0x01; - var TF_ROOT_OBJECT = 0x04; - var TF_STATUS_CODE = 0x08; - var TF_ACCEPT_FDS = 0x10; - var NO_FLAGS = 0; - - function binderFlagsToHuman(num) { - var flag = parseInt(num, 16); - var str = ''; - - if (flag & TF_ONE_WAY) - str += 'this is a one-way call: async, no return; '; - if (flag & TF_ROOT_OBJECT) - str += 'contents are the components root object; '; - if (flag & TF_STATUS_CODE) - str += 'contents are a 32-bit status code; '; - if (flag & TF_ACCEPT_FDS) - str += 'allow replies with file descriptors; '; - if (flag === NO_FLAGS) - str += 'No Flags Set'; - - return str; - } - - function isReplyToOrigin(calling, called) { - return (called.dest_proc === calling.calling_pid || - called.dest_thread === calling.calling_pid); - } - - function binderCodeToHuman(code) { - return 'Java Layer Dependent'; - } - - function doInternalSlice(trans, slice, ts) { - if (slice.subSlices.length !== 0) { - /* We want to make sure we keep moving the small slice to the end of - the big slice or else the arrows will not point to the end. - */ - slice.subSlices[0].start = ts; - return slice.subSlices[0]; - } - var kthread = trans.calling_kthread.thread; - var internal_slice = kthread.sliceGroup.pushCompleteSlice('binder', - slice.title, - ts, .001, 0, 0, - slice.args); - - internal_slice.title = slice.title; - internal_slice.id = slice.id; - internal_slice.colorId = slice.colorId; - slice.subSlices.push(internal_slice); - return internal_slice; - } - - function generateBinderArgsForSlice(trans, c_threadName) { - return { - 'Transaction Id': trans.transaction_key, - 'Destination Node': trans.dest_node, - 'Destination Process': trans.dest_proc, - 'Destination Thread': trans.dest_thread, - 'Destination Name': c_threadName, - 'Reply transaction?': trans.is_reply_transaction, - 'Flags': trans.flags + ' ' + - binderFlagsToHuman(trans.flags), - - 'Code': trans.code + ' ' + - binderCodeToHuman(trans.code), - - 'Calling PID': trans.calling_pid, - 'Calling tgid': trans.calling_kthread.thread.parent.pid - }; - } - - /** @constructor */ - function BinderTransaction(events, calling_pid, calling_ts, calling_kthread) { - this.transaction_key = parseInt(events[1]); - this.dest_node = parseInt(events[2]); - this.dest_proc = parseInt(events[3]); - this.dest_thread = parseInt(events[4]); - this.is_reply_transaction = parseInt(events[5]) === 1 ? true : false; - this.expect_reply = ((this.is_reply_transaction === false) && - (parseInt(events[6], 16) & TF_ONE_WAY) === 0); - - this.flags = events[6]; - this.code = events[7]; - this.calling_pid = calling_pid; - this.calling_ts = calling_ts; - this.calling_kthread = calling_kthread; - } - - - /** @constructor */ - function BinderParser(importer) { - Parser.call(this, importer); - importer.registerEventHandler('binder_locked', - BinderParser.prototype. - binderLocked.bind(this)); - importer.registerEventHandler('binder_unlock', - BinderParser.prototype. - binderUnlock.bind(this)); - importer.registerEventHandler('binder_lock', - BinderParser.prototype.binderLock.bind(this)); - importer.registerEventHandler('binder_transaction', - BinderParser.prototype. - binderTransaction.bind(this)); - importer.registerEventHandler('binder_transaction_received', - BinderParser.prototype. - binderTransactionReceived.bind(this)); - - this.model_ = importer.model; - this.kthreadlookup = {}; - this.importer_ = importer; - this.transWaitingRecv = {}; - this.syncTransWaitingCompletion = {}; - this.recursiveSyncTransWaitingCompletion_ByPID = {}; - this.receivedTransWaitingConversion = {}; - } - - BinderParser.prototype = { - __proto__: Parser.prototype, - - binderLock: function(eventName, cpuNumber, pid, ts, eventBase) { - var tgid = parseInt(eventBase.tgid); - this.doNameMappings(pid, tgid, eventName.threadName); - - var kthread = this.importer_. - getOrCreateBinderKernelThread(eventBase.threadName, tgid, pid); - - kthread.binderAttemptLockTS = ts; - kthread.binderOpenTsA = ts; - return true; - }, - - binderLocked: function(eventName, cpuNumber, pid, ts, eventBase) { - var binder_thread = isBinderThread(eventBase.threadName); - var tgid, name; - var as_slice; - var need_push = false; - var kthread, rthread; - - tgid = parseInt(eventBase.tgid); - name = eventBase.threadName; - - kthread = this.importer_. - getOrCreateBinderKernelThread(eventBase.threadName, tgid, pid); - - this.doNameMappings(pid, tgid, name); - - rthread = kthread.thread; - kthread.binderLockAquiredTS = ts; - - if (kthread.binderAttemptLockTS === undefined) - return false; - - var args = this.generateArgsForSlice(tgid, pid, name, kthread); - rthread.sliceGroup.pushCompleteSlice('binder', 'binder lock waiting', - kthread.binderAttemptLockTS, - ts - kthread.binderAttemptLockTS, - 0, 0, args); - - kthread.binderAttemptLockTS = undefined; - return true; - }, - - binderUnlock: function(eventName, cpuNumber, pid, ts, eventBase) { - var tgid = parseInt(eventBase.tgid); - var kthread = this.importer_. - getOrCreateBinderKernelThread( - eventBase.threadName, tgid, pid); - - if (kthread.binderLockAquiredTS === undefined) - return false; - - var args = this.generateArgsForSlice(tgid, pid, eventBase.threadName, - kthread); - kthread.thread.sliceGroup.pushCompleteSlice( - 'binder', - 'binder lock held', - kthread.binderLockAquiredTS, - ts - kthread.binderLockAquiredTS, - 0, 0, args); - - kthread.binderLockAquiredTS = undefined; - return true; - }, - - /** There are a few transaction status changes that signify - * progress through a binder transaction: - * - * Case One: Sync transaction. - * Thread A calls a blocking function on Thread B. We receive a - * binder_transaction msg From thread A stating that it is going to Call - * thread B. We create a slice and a binder object for this transaction and - * add it to addTransactionWaitingForRecv(transaction key, binder object) - * This notifies thread B and passes the slice, binder object and time - * stamp. - * - * Case Two: Async transaction. - * Thread A calls an async function on Thread B. Like above we receive a - * binder_transaction message, but the flags differ from above. The - * TF_ONEWAY flags are set so we know that when Thread B gets the - * binder_transaction_received with the same transaciton key the total - * transaction is complete. - * - * Case Three: 'Prior_receive' - * Prior_receive occurs when the thread being called (think A calls B), - * receives a binder_transaction_received message, but cannot correlate it - * to any current outstanding recursive transactions. That means the - * message it just received is the start of some communication, not some - * ongoing communication. - * Once the execution flow has been passed to thread B, from A: - * Thread B enters binder_transaction_received() we see that Thread A - * had notified us that it sent us a message by calling - * getTransactionWaitingForRecv(transaction key); - * What can happen now is either this was a simple Call reply, - * or this is a call -> recursion -> reply. We call modelPriorReceive() - * which sets up the slices accordingly. - * If this is a call -> recursion -> reply - * we will go to case 4 by calling addRecursiveSyncTransNeedingCompletion() - * The function takes B's PID, the binder object from A and the current - * binder object from B. This function adds outstanding non-complete - * transactions to a stack on thread B. - * - * Case Four: 'recursive_trans' - * This case follows Like above: - * A sent binder_transaction - * B got binder_transaction_received - * B instead of replying to A can Call C or call 'into' A, ie recursion - * Case four also deals with setting up a large slice to 'contain' - * all the recursive transactions that happen until B finally replies to - * A. - * - * - * An example: A-> B-> C-> B-> A - * - * (1) A starts a synchronous transaction to B. - * (2) A enters binderTransaction() event handler, hits the else statement - * (3) A calls addTransactionWaitingForRecv(trans key, object) to notify - * Thread B. - * (4) B Enters binderTransactionReceived(). - * (5) B hits the second if after calling - * getTransactionWaitingForRecv(trans key) - * This function returns us the object set up in step (3). - * (6) This is not an async transaction, B calls - * setCurrentReceiveOnPID(B's PID, [ts for (4), object from (3)]). - * - * (7) B enters binderTransaction() event handler, first if triggers after - * calling getPriorReceiveOnPID(B's PID) the tuple from (6) is returned. - * - * (8) Execution enters modelPriorReceive(). - * (8a) A slice is setup for this binder transaction in B's timeline. - * (9) This is not a reply to thread A, B is going to call Thread C. - * (10) else statement is hit. - * (11) We set the tile from (8a) to be binder_reply this is the - * 'containg slice' for the recursion - * (12) We create a new slice 'binder_transaction' this slice is the - * recursive slice that will have arrows to Thread C's slice. - * (13) addRecursiveSyncTransNeedingCompletion(B's PID, - * [obj from (3), obj from 7]) - * this sets up notification that B's pid has outstanding recursive - * transactions that need to be completed. - * (14) B notifies C that a transaction is waiting for it by calling - * addTransactionWaitingForRecv like in step (3). - * (15) C enters binderTransactionReceived() step 5 6 7 8 8a happen, but in - * the context of Thread C. - * (16) C is in modelPriorReceive(), it hits the first if statement, - * this transaction _IS_ a reply, and it is a reply to B. - * (17) C calls addSyncTransNeedingCompletion(trans key, - * [object from(3), object from 15-5]) - * (18) B enters binderTransactionReceived() hits the first if after calling - * getSyncTransNeedingCompletion(trans key from (17)) the tuple from - * (17) gets returned. - * - * (19) B scales up the slice created in (12) and sets up flows from 15-8a - * slice. - * (20) B enters BinderTransaction() event handler and the second if is hit - * after calling getRecursiveTransactionNeedingCompletion(B's pid). - * (21) modelRecursiveTransactions() gets called, first if executes. - * (22) slice durations are fixed up. - * (23) B notifies A via - * addSyncTransNeedingCompletion(trans key, binder obj from 8a). - * (24) B deletes the outstanding asynctrans via - ( removeRecursiveTransaction(B's pid). - * (25) A enters binderTransactionReceived() event handler and finishes up - * some flows, and slices. - */ - binderTransaction: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = binderTransRE.exec(eventBase.details); - if (event === undefined) - return false; - - var tgid = parseInt(eventBase.tgid); - - this.doNameMappings(pid, tgid, eventBase.threadName); - - var kthread; - kthread = this.importer_. - getOrCreateBinderKernelThread(eventBase.threadName, tgid, pid); - - var trans = new BinderTransaction(event, pid, ts, kthread); - var args = generateBinderArgsForSlice(trans, eventBase.threadName); - /** - * This thread previously ack'd the transaction with a - * transaction_received. That means someone sent us a message we processed - * it and are now sending a transaction. - * The transaction could be a response, or it could be recursive. - */ - var prior_receive = this.getPriorReceiveOnPID(pid); - - if (prior_receive !== false) { - return this.modelPriorReceive(prior_receive, ts, pid, tgid, kthread, - trans, args, event); - } - /** - * This Thread has an already established recursive slice. We will now - * either complete the entire transaction, OR do more recursive calls. - */ - var recursive_trans = this.getRecursiveTransactionNeedingCompletion(pid); - - if (recursive_trans !== false) - return this.modelRecursiveTransactions(recursive_trans, ts, pid, - kthread, trans, args); - - /** - * Start of a Transaction. This thread is the initiator of either a call - * response, an async call -> ack, or a call -> recursion -> response. - * Note, we put a fake duration into this slice and patch it up later. - */ - var slice = kthread.thread.sliceGroup.pushCompleteSlice('binder', - '', ts, .03, 0, 0, args); - - slice.colorId = ColorScheme.getColorIdForGeneralPurposeString( - ts.toString()); - trans.slice = slice; - - if (trans.expect_reply) - slice.title = 'binder transaction'; - else - slice.title = 'binder transaction async'; - - this.addTransactionWaitingForRecv(trans.transaction_key, trans); - - return true; - }, - - binderTransactionReceived: function(eventName, cpuNumber, pid, ts, - eventBase) { - var event = binderTransReceivedRE.exec(eventBase.details); - - if (event === undefined) - return false; - - var transactionkey = parseInt(event[1]); - var tgid = parseInt(eventBase.tgid); - var kthread; - kthread = this.importer_. - getOrCreateBinderKernelThread(eventBase.threadName, tgid, pid); - - var syncComplete = this.getSyncTransNeedsCompletion(transactionkey); - - if (syncComplete !== false) { - /* This recv is the completion of a synchronous transaction. - * We need to scale the slice up to the current ts and finish - * creating some flows. - */ - var sync_trans = syncComplete[0]; - var sync_slice = sync_trans.slice; - var response_trans = syncComplete[1]; - var response_slice = response_trans.slice; - - sync_slice.duration = ts - sync_slice.start; - /** These calls are a little hack that places a very small slice at - * the end of the sync slice and the response slice. This allows us - * to hook flow events (arrows) from the start to the end of the - * slices. - */ - var sync_internal = doInternalSlice(sync_trans, sync_slice, ts); - var response_ts = response_slice.start + response_slice.duration; - var response_internal = doInternalSlice(response_trans, - response_slice, response_ts); - - if (response_slice.outFlowEvents.length === 0 || - sync_slice.inFlowEvents.length === 0) { - var flow = this.generateFlow(response_internal, sync_internal, - response_trans, sync_trans); - - sync_slice.inFlowEvents.push(flow); - response_slice.outFlowEvents.push(flow); - this.model_.flowEvents.push(flow); - } - // Move flow arrows -- but not the first one. - for (var i = 1; i < sync_slice.inFlowEvents.length; i++) { - sync_slice.inFlowEvents[i].duration = - ts - sync_slice.inFlowEvents[i].start; - } - return true; - } - - var tr_for_recv = this.getTransactionWaitingForRecv(transactionkey); - - if (tr_for_recv !== false) { - if (!tr_for_recv.expect_reply) { - // This is an async call place an Async slice. - var args = generateBinderArgsForSlice(tr_for_recv, - eventBase.threadName); - var slice = kthread.thread.sliceGroup. - pushCompleteSlice('binder', - 'binder Async recv', - ts, .03, 0, 0, - args); - - var fake_event = [0, 0, 0, 0, 0, 0, 0]; - var fake_trans = new BinderTransaction(fake_event, pid, ts, kthread); - var flow = this.generateFlow(tr_for_recv.slice, slice, - tr_for_recv, fake_trans); - - this.model_.flowEvents.push(flow); - tr_for_recv.slice.title = 'binder transaction async'; - tr_for_recv.slice.duration = .03; - return true; - } - // Setup prior receive. - tr_for_recv.slice.title = 'binder transaction'; - this.setCurrentReceiveOnPID(pid, [ts, tr_for_recv]); - return true; - } - /** This case is when we received an ack for a transaction we have - * never seen before. This usually happens at the start of a trace. - * We will get incomplete transactions that started before started - * tracing. Just discard them. - */ - return false; - }, - - // helper functions - modelRecursiveTransactions: function(recursive_trans, ts, pid, kthread, - trans, args) { - - var recursive_slice = recursive_trans[1].slice; - var orig_slice = recursive_trans[0].slice; - recursive_slice.duration = ts - recursive_slice.start; - trans.slice = recursive_slice; - - if (trans.is_reply_transaction) { - /* Case one: - * This transaction is finally the reply of the recursion. - */ - orig_slice.duration = ts - orig_slice.start; - this.addSyncTransNeedingCompletion(trans.transaction_key, - recursive_trans); - - if (isReplyToOrigin(recursive_trans[0], trans)) - this.removeRecursiveTransaction(pid); - } else { - /** - * Case two: - * This transaction is more recursive calls. - * This is a nested call within an already started transaction, - * it can either be a async or a normal sync transaction. - */ - var slice = kthread.thread.sliceGroup.pushCompleteSlice('binder', - '' , ts, .03, 0, - 0, args); - - trans.slice = slice; - this.addTransactionWaitingForRecv(trans.transaction_key, trans); - } - return true; - }, - - modelPriorReceive: function(prior_receive, ts, pid, tgid, kthread, trans, - args, event) { - var callee_slice = prior_receive[1].slice; - var callee_trans = prior_receive[1]; - var recv_ts = prior_receive[0]; - var slice = kthread.thread.sliceGroup.pushCompleteSlice('binder', - '', recv_ts, ts - recv_ts, 0, 0, args); - - var flow = this.generateFlow(callee_slice, slice, callee_trans, trans); - this.model_.flowEvents.push(flow); - trans.slice = slice; - - if (trans.is_reply_transaction) { - /* This is a response to a synchronous or a recursive sync - * transaction. - */ - slice.title = 'binder reply'; - /* Notify this transaction key that when it recv's it is completing - * a sync transaction. - */ - this.addSyncTransNeedingCompletion(trans.transaction_key, - [callee_trans, trans]); - } else { - /** - * Recursive calls and or calls around, either way it's not - * going to complete a transaction. - */ - slice.title = 'binder reply'; - /* Since this is a recursive transaction we want to create the main - * large slice which will contain all these recursive transactions. - * For that we created the main slice above and this is a recursive - * transaction that will be placed right below it. Note, that this - * is only for the first recursive transaction. If more come they will - * be handled below in the getRecursiveTransactionNeedingCompletion - */ - var trans1 = new BinderTransaction(event, pid, ts, kthread); - - slice = kthread.thread.sliceGroup. - pushCompleteSlice('binder', - 'binder transaction', - recv_ts, - (ts - recv_ts), 0, - 0, args); - - /* could be a async trans if so set the length to be a small one */ - if (!trans.expect_reply) { - slice.title = 'binder transaction async'; - slice.duration = .03; - } else { - /* stupid hack to stop merging of AIDL slices and - * this slice. This is currently disabled, if AIDL tracing is on we - * will see merging of this slice and the AIDL slice. Once upstream - * has a solution for flow events to be placed in the middle of - * slices this part can be fixed. - * - * This is commented out because AIDL tracing doesn't exit yet. - */ - //slice.start += .15; - } - trans1.slice = slice; - this.addRecursiveSyncTransNeedingCompletion(pid, - [callee_trans, trans]); - this.addTransactionWaitingForRecv(trans.transaction_key, trans1); - } - return true; - }, - - getRecursiveTransactionNeedingCompletion: function(pid) { - if (this.recursiveSyncTransWaitingCompletion_ByPID[pid] === undefined) - return false; - - var len = this.recursiveSyncTransWaitingCompletion_ByPID[pid].length; - if (len === 0) - return false; - - return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len - 1]; - }, - - addRecursiveSyncTransNeedingCompletion: function(pid, tuple) { - if (this.recursiveSyncTransWaitingCompletion_ByPID[pid] === undefined) - this.recursiveSyncTransWaitingCompletion_ByPID[pid] = []; - - this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple); - }, - - removeRecursiveTransaction: function(pid) { - var len = this.recursiveSyncTransWaitingCompletion_ByPID[pid].length; - if (len === 0) { - delete this.recursiveSyncTransWaitingCompletion_ByPID[pid]; - return; - } - - this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len - 1, 1); - }, - - setCurrentReceiveOnPID: function(pid, tuple) { - if (this.receivedTransWaitingConversion[pid] === undefined) { - this.receivedTransWaitingConversion[pid] = []; - } - this.receivedTransWaitingConversion[pid].push(tuple); - }, - - getPriorReceiveOnPID: function(pid) { - if (this.receivedTransWaitingConversion[pid] === undefined) - return false; - - var len = this.receivedTransWaitingConversion[pid].length; - if (len === 0) - return false; - - return this.receivedTransWaitingConversion[pid].splice(len - 1, 1)[0]; - }, - - addSyncTransNeedingCompletion: function(transactionkey, tuple) { - var dict = this.syncTransWaitingCompletion; - dict[transactionkey] = tuple; - }, - - getSyncTransNeedsCompletion: function(transactionkey) { - var ret = this.syncTransWaitingCompletion[transactionkey]; - if (ret === undefined) - return false; - - delete this.syncTransWaitingCompletion[transactionkey]; - return ret; - }, - - getTransactionWaitingForRecv: function(transactionkey) { - var ret = this.transWaitingRecv[transactionkey]; - if (ret === undefined) - return false; - - delete this.transWaitingRecv[transactionkey]; - return ret; - }, - - addTransactionWaitingForRecv: function(transactionkey, transaction) { - this.transWaitingRecv[transactionkey] = transaction; - }, - - generateFlow: function(from, to, from_trans, to_trans) { - var title = 'Transaction from : ' + - this.pid2name(from_trans.calling_pid) + - ' From PID: ' + from_trans.calling_pid + ' to pid: ' + - to_trans.calling_pid + - ' Thread Name: ' + this.pid2name(to_trans.calling_pid); - - var ts = from.start; - var flow = new tr.model.FlowEvent('binder', 'binder', - title, 1, ts, []); - flow.startSlice = from; - flow.endSlice = to; - flow.start = from.start; - flow.duration = to.start - ts; - - from.outFlowEvents.push(flow); - to.inFlowEvents.push(flow); - - return flow; - }, - - generateArgsForSlice: function(tgid, pid, name, kthread) { - return { - 'Thread Name': name, - 'pid': pid, - 'gid': tgid - }; - }, - - pid2name: function(pid) { - return this.kthreadlookup[pid]; - }, - - doNameMappings: function(pid, tgid, name) { - this.registerPidName(pid, name); - this.registerPidName(tgid, name); - }, - - registerPidName: function(pid, name) { - if (this.pid2name(pid) === undefined) - this.kthreadlookup[pid] = name; - } - }; - - Parser.register(BinderParser); - return { - BinderParser: BinderParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/binder_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/binder_parser_test.html deleted file mode 100644 index 513279adbea..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/binder_parser_test.html +++ /dev/null @@ -1,225 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('binderParserImport', function() { - var lines = [ - 'binderLibTest-10619 (10619) [001] ...1 25191.335749: binder_transaction' + - ': transaction=489053 dest_node=489048 dest_proc=10670 dest_thread=0 ' + - 'reply=0 flags=0x10 code=0xd', - 'binderLibTest-10670 (10670) [000] ...1 25191.335996:' + - ' binder_transaction_received: transaction=489053', - 'binderLibTest-10670 (10670) [000] ...1 25191.336167:' + - ' binder_transaction: transaction=489056 dest_node=161277 ' + - 'dest_proc=3454 dest_thread=0 reply=0 flags=0x10 code=0x2', - '/system/bin/servicemanager-3454 ( 3454) [000] ...1 25191.336199:' + - ' binder_transaction_received: transaction=489056', - '/system/bin/servicemanager-3454 ( 3454) [000] ...1 25191.336302:' + - ' binder_transaction: transaction=489057 dest_node=0 dest_proc=10670' + - ' dest_thread=10670 reply=1 flags=0x0 code=0x0', - 'binderLibTest-10670 (10670) [000] ...1 25191.336334:' + - ' binder_transaction_received: transaction=489057', - 'binderLibTest-10670 (10670) [000] ...1 25191.336655:' + - ' binder_transaction: transaction=489059 dest_node=488755' + - ' dest_proc=10622 dest_thread=0 reply=0 flags=0x10 code=0x1', - 'Binder_4-10645 (10622) [001] ...1 25191.336693:' + - ' binder_transaction_received: transaction=489059', - 'Binder_4-10645 (10622) [001] ...1 25191.336754: binder_transaction:' + - ' transaction=489060 dest_node=0 dest_proc=10670 dest_thread=10670' + - ' reply=1 flags=0x0 code=0x0', - 'binderLibTest-10670 (10670) [000] ...1 25191.337003:' + - ' binder_transaction_received: transaction=489060', - 'binderLibTest-10670 (10670) [000] ...1 25191.337052:' + - ' binder_transaction: transaction=489061 dest_node=0 dest_proc=10619' + - ' dest_thread=10619 reply=1 flags=0x8 code=0x0', - 'binderLibTest-10619 (10619) [001] ...1 25191.337085:' + - ' binder_transaction_received: transaction=489061', - 'atrace-10618 (10618) [000] ...1 25196.059954: tracing_mark_write:' + - ' trace_event_clock_sync: parent_ts=25196.050781' - ]; - - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shfitWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 4); - - }); - - test('binderRecursiveTest', function() { - var lines = [ - 'binderLibTest-10619 (10619) [001] ...1 25191.335749: binder_transaction' + - ': transaction=489053 dest_node=489048 dest_proc=10670 dest_thread=0 ' + - 'reply=0 flags=0x10 code=0xd', - 'binderLibTest-10670 (10670) [000] ...1 25191.335996:' + - ' binder_transaction_received: transaction=489053', - 'binderLibTest-10670 (10670) [000] ...1 25191.336167:' + - ' binder_transaction: transaction=489056 dest_node=161277 ' + - 'dest_proc=3454 dest_thread=0 reply=0 flags=0x10 code=0x2', - '/system/bin/servicemanager-3454 ( 3454) [000] ...1 25191.336199:' + - ' binder_transaction_received: transaction=489056', - '/system/bin/servicemanager-3454 ( 3454) [000] ...1 25191.336302:' + - ' binder_transaction: transaction=489057 dest_node=0 dest_proc=10670' + - ' dest_thread=10670 reply=1 flags=0x0 code=0x0', - 'binderLibTest-10670 (10670) [000] ...1 25191.336334:' + - ' binder_transaction_received: transaction=489057', - 'binderLibTest-10670 (10670) [000] ...1 25191.336655:' + - ' binder_transaction: transaction=489059 dest_node=488755' + - ' dest_proc=10622 dest_thread=0 reply=0 flags=0x10 code=0x1', - 'Binder_4-10645 (10622) [001] ...1 25191.336693:' + - ' binder_transaction_received: transaction=489059', - 'Binder_4-10645 (10622) [001] ...1 25191.336754: binder_transaction:' + - ' transaction=489060 dest_node=0 dest_proc=10670 dest_thread=10670' + - ' reply=1 flags=0x0 code=0x0', - 'binderLibTest-10670 (10670) [000] ...1 25191.337003:' + - ' binder_transaction_received: transaction=489060', - 'binderLibTest-10670 (10670) [000] ...1 25191.337052:' + - ' binder_transaction: transaction=489061 dest_node=0 dest_proc=10619' + - ' dest_thread=10619 reply=1 flags=0x8 code=0x0', - 'binderLibTest-10619 (10619) [001] ...1 25191.337085:' + - ' binder_transaction_received: transaction=489061', - 'atrace-10618 (10618) [000] ...1 25196.059954: tracing_mark_write:' + - ' trace_event_clock_sync: parent_ts=25196.050781' - ]; - - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shfitWorldToZero: false - }); - var threads = m.getAllThreads(); - - var thread = threads[0]; - assert.equal(thread.parent.pid, 3454); - assert.equal(thread.tid, 3454); - assert.equal(thread.name, '/system/bin/servicemanager'); - /* one main slice and one 'internal slice' for the end flow event' */ - assert.equal(thread.sliceGroup.length, 2); - - /* check flow events for service manager */ - var main_slice = thread.sliceGroup.slices[0]; - assert.equal(main_slice.inFlowEvents.length, 1); - assert.equal(main_slice.outFlowEvents.length, 1); - var internal_slice = thread.sliceGroup.slices[1]; - assert.equal(internal_slice.outFlowEvents.length, 1); - - /* check name of slice */ - assert.equal(main_slice.title, 'binder reply'); - - /* check binderLibTest */ - thread = threads[1]; - assert.equal(thread.parent.pid, 10619); - assert.equal(thread.tid, 10619); - assert.equal(thread.name, 'binderLibTest'); - - assert.equal(2, thread.sliceGroup.length); - - main_slice = thread.sliceGroup.slices[0]; - assert.equal(main_slice.inFlowEvents.length, 1); - assert.equal(main_slice.outFlowEvents.length, 1); - internal_slice = thread.sliceGroup.slices[1]; - assert.equal(internal_slice.inFlowEvents.length, 1); - - assert.equal(main_slice.title, 'binder transaction'); - - /* check Binder_4 */ - thread = threads[2]; - assert.equal(thread.parent.pid, 10622); - assert.equal(thread.tid, 10645); - assert.equal(thread.name, 'Binder_4'); - assert.equal(2, thread.sliceGroup.length); - - main_slice = thread.sliceGroup.slices[0]; - assert.equal(main_slice.inFlowEvents.length, 1); - assert.equal(main_slice.outFlowEvents.length, 1); - internal_slice = thread.sliceGroup.slices[1]; - assert.equal(internal_slice.outFlowEvents.length, 1); - - assert.equal(main_slice.title, 'binder reply'); - - /* check last binderLibTest with recursive slices */ - thread = threads[3]; - assert.equal(thread.parent.pid, 10670); - assert.equal(thread.tid, 10670); - assert.equal(thread.name, 'binderLibTest'); - assert.equal(6, thread.sliceGroup.length); - - main_slice = thread.sliceGroup.slices[0]; - assert.equal(main_slice.inFlowEvents.length, 1); - assert.equal(main_slice.outFlowEvents.length, 1); - internal_slice = thread.sliceGroup.slices[5]; - assert.equal(internal_slice.outFlowEvents.length, 1); - - assert.equal(main_slice.title, 'binder reply'); - - var recursive = thread.sliceGroup.slices[1]; - var recursive_internal = thread.sliceGroup.slices[2]; - assert.equal(recursive.inFlowEvents.length, 1); - assert.equal(recursive.outFlowEvents.length, 1); - assert.equal(recursive_internal.inFlowEvents.length, 1); - - assert.equal(recursive.title, 'binder transaction'); - - /* check second recursive slice and internal */ - - var recursive = thread.sliceGroup.slices[3]; - var recursive_internal = thread.sliceGroup.slices[4]; - assert.equal(recursive.inFlowEvents.length, 1); - assert.equal(recursive.outFlowEvents.length, 1); - assert.equal(recursive_internal.inFlowEvents.length, 1); - - assert.equal(recursive.title, 'binder transaction'); - }); - - test('binderSimpleAsync', function() { - var lines = [ - '/system/bin/surfaceflinger-3462 ( 3462) [000] ...1 108286.109437:' + - ' binder_transaction: transaction=923419 dest_node=175950' + - ' dest_proc=4044 dest_thread=0 reply=0 flags=0x11 code=0x1', - 'Binder_5-12869 ( 4044) [000] ...1 108286.109835:' + - ' binder_transaction_received: transaction=923419' - ]; - - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shfitWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(0); - assert.equal(threads.length, 2); - - var thread = threads[0]; - assert.equal(thread.tid, 3462); - assert.equal(thread.name, '/system/bin/surfaceflinger'); - assert.equal(thread.sliceGroup.length, 1); - - var slice = thread.sliceGroup.slices[0]; - assert.equal(slice.outFlowEvents.length, 1); - assert.equal(slice.inFlowEvents.length, 0); - assert.equal(slice.title, 'binder transaction async'); - - thread = threads[1]; - assert.equal(thread.tid, 12869); - assert.equal(thread.name, 'Binder_5'); - assert.equal(thread.sliceGroup.length, 1); - - slice = thread.sliceGroup.slices[0]; - assert.equal(slice.inFlowEvents.length, 1); - assert.equal(slice.outFlowEvents.length, 0); - assert.equal(slice.title, 'binder Async recv'); - - }); -}); - -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/bus_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/bus_parser.html deleted file mode 100644 index 55d80730405..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/bus_parser.html +++ /dev/null @@ -1,90 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> -<link rel="import" href="/tracing/model/counter_series.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses trace_marker events that were inserted in the trace by - * userland. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux trace mark events that were inserted in the trace by userland. - * @constructor - */ - function BusParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('memory_bus_usage', - BusParser.prototype.traceMarkWriteBusEvent.bind(this)); - - this.model_ = importer.model_; - this.ppids_ = {}; - } - - BusParser.prototype = { - __proto__: Parser.prototype, - - traceMarkWriteBusEvent: function(eventName, cpuNumber, pid, ts, - eventBase, threadName) { - var re = new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) ' + - 'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)'); - var event = re.exec(eventBase.details); - - var name = event[1]; - var rw_bytes = parseInt(event[2]); - var r_bytes = parseInt(event[3]); - var w_bytes = parseInt(event[4]); - var cycles = parseInt(event[5]); - var ns = parseInt(event[6]); - - // BW in MB/s - var r_bw = r_bytes * 1000000000 / ns; - r_bw /= 1024 * 1024; - var w_bw = w_bytes * 1000000000 / ns; - w_bw /= 1024 * 1024; - - var ctr = this.model_.kernel - .getOrCreateCounter(null, 'bus ' + name + ' read'); - if (ctr.numSeries === 0) { - ctr.addSeries(new tr.model.CounterSeries('value', - ColorScheme.getColorIdForGeneralPurposeString( - ctr.name + '.' + 'value'))); - } - ctr.series.forEach(function(series) { - series.addCounterSample(ts, r_bw); - }); - - ctr = this.model_.kernel - .getOrCreateCounter(null, 'bus ' + name + ' write'); - if (ctr.numSeries === 0) { - ctr.addSeries(new tr.model.CounterSeries('value', - ColorScheme.getColorIdForGeneralPurposeString( - ctr.name + '.' + 'value'))); - } - ctr.series.forEach(function(series) { - series.addCounterSample(ts, r_bw); - }); - - return true; - } - }; - - Parser.register(BusParser); - - return { - BusParser: BusParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/bus_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/bus_parser_test.html deleted file mode 100644 index 6222067d64c..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/bus_parser_test.html +++ /dev/null @@ -1,68 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('exynos5Bus', function() { - var lines = [ - 's3c-fb-vsync-85 [001] d..2 8116.730115: memory_bus_usage: ' + - 'bus=RIGHT rw_bytes=0 r_bytes=0 w_bytes=0 cycles=2681746 ns=16760792', - - 's3c-fb-vsync-85 [001] d..2 8116.730118: memory_bus_usage: ' + - 'bus=CPU rw_bytes=2756608 r_bytes=2267328 w_bytes=491328 ' + - 'cycles=6705198 ns=16763375', - - 's3c-fb-vsync-85 [001] d..2 8116.746788: memory_bus_usage: ' + - 'bus=DDR_C rw_bytes=2736128 r_bytes=2260864 w_bytes=479248 ' + - 'cycles=6670677 ns=16676375', - - 's3c-fb-vsync-85 [001] d..2 8116.746790: memory_bus_usage: ' + - 'bus=DDR_R1 rw_bytes=31457280 r_bytes=31460912 w_bytes=0 ' + - 'cycles=6670521 ns=16676500', - - 's3c-fb-vsync-85 [001] d..2 8116.746792: memory_bus_usage: ' + - 'bus=DDR_L rw_bytes=16953344 r_bytes=16731088 w_bytes=223664 ' + - 'cycles=6669885 ns=16674833', - - 's3c-fb-vsync-85 [001] d..2 8116.746793: memory_bus_usage: ' + - 'bus=RIGHT rw_bytes=0 r_bytes=0 w_bytes=0 cycles=2667378 ns=16671250', - - 's3c-fb-vsync-85 [001] d..2 8116.746798: memory_bus_usage: ' + - 'bus=CPU rw_bytes=2797568 r_bytes=2309424 w_bytes=491968 ' + - 'cycles=6672156 ns=16680458', - - 's3c-fb-vsync-85 [001] d..2 8116.763521: memory_bus_usage: ' + - 'bus=DDR_C rw_bytes=2408448 r_bytes=1968448 w_bytes=441456 ' + - 'cycles=6689562 ns=16723458', - - 's3c-fb-vsync-85 [001] d..2 8116.763523: memory_bus_usage: ' + - 'bus=DDR_R1 rw_bytes=31490048 r_bytes=31493360 w_bytes=0 ' + - 'cycles=6690012 ns=16725083', - - 's3c-fb-vsync-85 [001] d..2 8116.763525: memory_bus_usage: ' + - 'bus=DDR_L rw_bytes=16941056 r_bytes=16719136 w_bytes=223472 ' + - 'cycles=6690156 ns=16725375' - - ]; - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var counters = m.getAllCounters(); - assert.equal(counters.length, 10); - - assert.equal(counters[0].series[0].samples.length, 2); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/clock_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/clock_parser.html deleted file mode 100644 index 41c12d7f0c3..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/clock_parser.html +++ /dev/null @@ -1,70 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> -<link rel="import" href="/tracing/model/counter_series.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses trace_marker events that were inserted in the trace by - * userland. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux trace mark events that were inserted in the trace by userland. - * @constructor - */ - function ClockParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('clock_set_rate', - ClockParser.prototype.traceMarkWriteClockEvent.bind(this)); - - this.model_ = importer.model_; - this.ppids_ = {}; - } - - ClockParser.prototype = { - __proto__: Parser.prototype, - - traceMarkWriteClockEvent: function(eventName, cpuNumber, pid, ts, - eventBase, threadName) { - var event = /(\S+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details); - - - var name = event[1]; - var rate = parseInt(event[2]); - - var ctr = this.model_.kernel - .getOrCreateCounter(null, name); - // Initialize the counter's series fields if needed. - if (ctr.numSeries === 0) { - ctr.addSeries(new tr.model.CounterSeries('value', - ColorScheme.getColorIdForGeneralPurposeString( - ctr.name + '.' + 'value'))); - } - ctr.series.forEach(function(series) { - series.addCounterSample(ts, rate); - }); - - return true; - } - }; - - Parser.register(ClockParser); - - return { - ClockParser: ClockParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/clock_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/clock_parser_test.html deleted file mode 100644 index a348fe07cbc..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/clock_parser_test.html +++ /dev/null @@ -1,60 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('clock', function() { - var lines = [ - 'cfinteractive-23 [000] d..2 8113.233768: clock_set_rate: ' + - 'fout_apll state=500000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.249509: clock_set_rate: ' + - 'fout_apll state=300000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.289796: clock_set_rate: ' + - 'fout_apll state=400000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.294568: clock_set_rate: ' + - 'fout_apll state=500000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.309509: clock_set_rate: ' + - 'fout_apll state=800000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.388732: clock_set_rate: ' + - 'fout_apll state=200000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.410182: clock_set_rate: ' + - 'fout_apll state=300000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.414872: clock_set_rate: ' + - 'fout_apll state=600000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.494455: clock_set_rate: ' + - 'fout_apll state=200000000 cpu_id=0', - - 'cfinteractive-23 [000] d..2 8113.515254: clock_set_rate: ' + - 'fout_apll state=500000000 cpu_id=0' - ]; - - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var counters = m.getAllCounters(); - assert.equal(counters.length, 1); - - assert.equal(counters[0].series[0].samples.length, 10); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/cpufreq_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/cpufreq_parser.html deleted file mode 100644 index cd7f357c8e5..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/cpufreq_parser.html +++ /dev/null @@ -1,115 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses cpufreq events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux cpufreq trace events. - * @constructor - */ - function CpufreqParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('cpufreq_interactive_up', - CpufreqParser.prototype.cpufreqUpDownEvent.bind(this)); - importer.registerEventHandler('cpufreq_interactive_down', - CpufreqParser.prototype.cpufreqUpDownEvent.bind(this)); - importer.registerEventHandler('cpufreq_interactive_already', - CpufreqParser.prototype.cpufreqTargetEvent.bind(this)); - importer.registerEventHandler('cpufreq_interactive_notyet', - CpufreqParser.prototype.cpufreqTargetEvent.bind(this)); - importer.registerEventHandler('cpufreq_interactive_setspeed', - CpufreqParser.prototype.cpufreqTargetEvent.bind(this)); - importer.registerEventHandler('cpufreq_interactive_target', - CpufreqParser.prototype.cpufreqTargetEvent.bind(this)); - importer.registerEventHandler('cpufreq_interactive_boost', - CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this)); - importer.registerEventHandler('cpufreq_interactive_unboost', - CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this)); - } - - function splitData(input) { - // TODO(sleffler) split by cpu - var data = {}; - var args = input.split(/\s+/); - var len = args.length; - for (var i = 0; i < len; i++) { - var item = args[i].split('='); - data[item[0]] = parseInt(item[1]); - } - return data; - } - - CpufreqParser.prototype = { - __proto__: Parser.prototype, - - cpufreqSlice: function(ts, eventName, cpu, args) { - // TODO(sleffler) should be per-cpu - var kthread = this.importer.getOrCreatePseudoThread('cpufreq'); - kthread.openSlice = eventName; - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - ts, args, 0); - - kthread.thread.sliceGroup.pushSlice(slice); - }, - - cpufreqBoostSlice: function(ts, eventName, args) { - var kthread = this.importer.getOrCreatePseudoThread('cpufreq_boost'); - kthread.openSlice = eventName; - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - ts, args, 0); - - kthread.thread.sliceGroup.pushSlice(slice); - }, - - /** - * Parses cpufreq events and sets up state in the importer. - */ - cpufreqUpDownEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var data = splitData(eventBase.details); - this.cpufreqSlice(ts, eventName, data.cpu, data); - return true; - }, - - cpufreqTargetEvent: function(eventName, cpuNumber, pid, ts, - eventBase) { - var data = splitData(eventBase.details); - this.cpufreqSlice(ts, eventName, data.cpu, data); - return true; - }, - - cpufreqBoostUnboostEvent: function(eventName, cpuNumber, pid, ts, - eventBase) { - this.cpufreqBoostSlice(ts, eventName, - { - type: eventBase.details - }); - return true; - } - }; - - Parser.register(CpufreqParser); - - return { - CpufreqParser: CpufreqParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/cpufreq_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/cpufreq_parser_test.html deleted file mode 100644 index 114b8aa4c1a..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/cpufreq_parser_test.html +++ /dev/null @@ -1,173 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('cpuFreqTargetImport', function() { - var lines = [ - '<idle>-0 [000] ..s3 1043.718825: cpufreq_interactive_target: ' + - 'cpu=0 load=2 cur=2000000 targ=300000\n', - '<idle>-0 [000] ..s3 1043.718825: cpufreq_interactive_target: ' + - 'cpu=0 load=12 cur=1000000 actual=1000000 targ=200000\n' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.sliceGroup.slices[0].args['cpu'], 0); - assert.equal(thread.sliceGroup.slices[0].args['load'], 2); - assert.equal(thread.sliceGroup.slices[0].args['cur'], 2000000); - assert.equal(thread.sliceGroup.slices[0].args['targ'], 300000); - - assert.equal(thread.sliceGroup.slices[1].args['cpu'], 0); - assert.equal(thread.sliceGroup.slices[1].args['load'], 12); - assert.equal(thread.sliceGroup.slices[1].args['cur'], 1000000); - assert.equal(thread.sliceGroup.slices[1].args['actual'], 1000000); - assert.equal(thread.sliceGroup.slices[1].args['targ'], 200000); - }); - - test('cpuFreqNotYetImport', function() { - var lines = [ - '<idle>-0 [001] ..s3 1043.718832: cpufreq_interactive_notyet: ' + - 'cpu=1 load=10 cur=700000 targ=200000\n', - '<idle>-0 [001] ..s3 1043.718832: cpufreq_interactive_notyet: ' + - 'cpu=1 load=10 cur=700000 actual=1000000 targ=200000\n' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.sliceGroup.slices[0].args['cpu'], 1); - assert.equal(thread.sliceGroup.slices[0].args['load'], 10); - assert.equal(thread.sliceGroup.slices[0].args['cur'], 700000); - assert.equal(thread.sliceGroup.slices[0].args['targ'], 200000); - - assert.equal(thread.sliceGroup.slices[1].args['cpu'], 1); - assert.equal(thread.sliceGroup.slices[1].args['load'], 10); - assert.equal(thread.sliceGroup.slices[1].args['cur'], 700000); - assert.equal(thread.sliceGroup.slices[1].args['actual'], 1000000); - assert.equal(thread.sliceGroup.slices[1].args['targ'], 200000); - }); - - test('cpuFreqSetSpeedImport', function() { - var lines = [ - 'cfinteractive-23 [001] ...1 1043.719688: ' + - 'cpufreq_interactive_setspeed: cpu=0 targ=200000 actual=700000\n' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.sliceGroup.slices[0].args['cpu'], 0); - assert.equal(thread.sliceGroup.slices[0].args['targ'], 200000); - assert.equal(thread.sliceGroup.slices[0].args['actual'], 700000); - }); - - test('cpuFreqAlreadyImport', function() { - var lines = [ - '<idle>-0 [000] ..s3 1043.738822: cpufreq_interactive_already: cpu=0 load=18 cur=200000 actual=700000 targ=200000\n' // @suppress longLineCheck - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.sliceGroup.slices[0].args['cpu'], 0); - assert.equal(thread.sliceGroup.slices[0].args['load'], 18); - assert.equal(thread.sliceGroup.slices[0].args['cur'], 200000); - assert.equal(thread.sliceGroup.slices[0].args['actual'], 700000); - assert.equal(thread.sliceGroup.slices[0].args['targ'], 200000); - }); - - test('cpuFreqBoostImport', function() { - var lines = [ - 'InputDispatcher-465 [001] ...1 1044.213948: ' + - 'cpufreq_interactive_boost: pulse\n' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.sliceGroup.slices[0].args['type'], 'pulse'); - }); - - test('cpuFreqUnBoostImport', function() { - var lines = [ - 'InputDispatcher-465 [001] ...1 1044.213948: ' + - 'cpufreq_interactive_unboost: pulse\n' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.sliceGroup.slices[0].args['type'], 'pulse'); - }); - - test('cpuFreqUpImport', function() { - var lines = [ - 'kinteractive-69 [003] .... 414324.164432: ' + - 'cpufreq_interactive_up: cpu=1 targ=1400000 actual=800000' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.sliceGroup.slices[0].args['cpu'], 1); - assert.equal(thread.sliceGroup.slices[0].args['targ'], 1400000); - assert.equal(thread.sliceGroup.slices[0].args['actual'], 800000); - }); - - test('cpuFreqDownImport', function() { - var lines = [ - 'kinteractive-69 [003] .... 414365.834193: ' + - 'cpufreq_interactive_down: cpu=3 targ=800000 actual=1000000' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - assert.equal(thread.sliceGroup.slices[0].args['cpu'], 3); - assert.equal(thread.sliceGroup.slices[0].args['targ'], 800000); - assert.equal(thread.sliceGroup.slices[0].args['actual'], 1000000); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/disk_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/disk_parser.html deleted file mode 100644 index bbbeae733f3..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/disk_parser.html +++ /dev/null @@ -1,313 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses filesystem and block device events in the Linux event - * trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux filesystem and block device trace events. - * @constructor - */ - function DiskParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('f2fs_write_begin', - DiskParser.prototype.f2fsWriteBeginEvent.bind(this)); - importer.registerEventHandler('f2fs_write_end', - DiskParser.prototype.f2fsWriteEndEvent.bind(this)); - importer.registerEventHandler('f2fs_sync_file_enter', - DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this)); - importer.registerEventHandler('f2fs_sync_file_exit', - DiskParser.prototype.f2fsSyncFileExitEvent.bind(this)); - importer.registerEventHandler('ext4_sync_file_enter', - DiskParser.prototype.ext4SyncFileEnterEvent.bind(this)); - importer.registerEventHandler('ext4_sync_file_exit', - DiskParser.prototype.ext4SyncFileExitEvent.bind(this)); - importer.registerEventHandler('ext4_da_write_begin', - DiskParser.prototype.ext4WriteBeginEvent.bind(this)); - importer.registerEventHandler('ext4_da_write_end', - DiskParser.prototype.ext4WriteEndEvent.bind(this)); - importer.registerEventHandler('block_rq_issue', - DiskParser.prototype.blockRqIssueEvent.bind(this)); - importer.registerEventHandler('block_rq_complete', - DiskParser.prototype.blockRqCompleteEvent.bind(this)); - } - - DiskParser.prototype = { - __proto__: Parser.prototype, - - openAsyncSlice: function(ts, category, threadName, pid, key, name) { - var kthread = this.importer.getOrCreateKernelThread( - category + ':' + threadName, pid); - var asyncSliceConstructor = - tr.model.AsyncSlice.getConstructor( - category, name); - var slice = new asyncSliceConstructor( - category, name, - ColorScheme.getColorIdForGeneralPurposeString(name), - ts); - slice.startThread = kthread.thread; - - if (!kthread.openAsyncSlices) { - kthread.openAsyncSlices = { }; - } - kthread.openAsyncSlices[key] = slice; - }, - - closeAsyncSlice: function(ts, category, threadName, pid, key, args) { - var kthread = this.importer.getOrCreateKernelThread( - category + ':' + threadName, pid); - if (kthread.openAsyncSlices) { - var slice = kthread.openAsyncSlices[key]; - if (slice) { - slice.duration = ts - slice.start; - slice.args = args; - slice.endThread = kthread.thread; - slice.subSlices = [ - new tr.model.AsyncSlice(category, slice.title, - slice.colorId, slice.start, slice.args, slice.duration) - ]; - kthread.thread.asyncSliceGroup.push(slice); - delete kthread.openAsyncSlices[key]; - } - } - }, - - /** - * Parses events and sets up state in the importer. - */ - f2fsWriteBeginEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/. // @suppress longLineCheck - exec(eventBase.details); - if (!event) - return false; - var device = event[1]; - var inode = parseInt(event[2]); - var pos = parseInt(event[3]); - var len = parseInt(event[4]); - var key = device + '-' + inode + '-' + pos + '-' + len; - this.openAsyncSlice(ts, 'f2fs', eventBase.threadName, eventBase.pid, - key, 'f2fs_write'); - return true; - }, - - f2fsWriteEndEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/. // @suppress longLineCheck - exec(eventBase.details); - if (!event) - return false; - - var device = event[1]; - var inode = parseInt(event[2]); - var pos = parseInt(event[3]); - var len = parseInt(event[4]); - var error = parseInt(event[5]) !== len; - var key = device + '-' + inode + '-' + pos + '-' + len; - this.closeAsyncSlice(ts, 'f2fs', eventBase.threadName, eventBase.pid, - key, { - device: device, - inode: inode, - error: error - }); - return true; - }, - - ext4WriteBeginEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/. - exec(eventBase.details); - if (!event) - return false; - var device = event[1]; - var inode = parseInt(event[2]); - var pos = parseInt(event[3]); - var len = parseInt(event[4]); - var key = device + '-' + inode + '-' + pos + '-' + len; - this.openAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid, - key, 'ext4_write'); - return true; - }, - - ext4WriteEndEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/. - exec(eventBase.details); - if (!event) - return false; - - var device = event[1]; - var inode = parseInt(event[2]); - var pos = parseInt(event[3]); - var len = parseInt(event[4]); - var error = parseInt(event[5]) !== len; - var key = device + '-' + inode + '-' + pos + '-' + len; - this.closeAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid, - key, { - device: device, - inode: inode, - error: error - }); - return true; - }, - - f2fsSyncFileEnterEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = new RegExp( - 'dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), ' + // @suppress longLineCheck - 'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)'). // @suppress longLineCheck - exec(eventBase.details); - if (!event) - return false; - - var device = event[1]; - var inode = parseInt(event[2]); - var key = device + '-' + inode; - this.openAsyncSlice(ts, 'f2fs', eventBase.threadName, eventBase.pid, - key, 'fsync'); - return true; - }, - - f2fsSyncFileExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), ' + // @suppress longLineCheck - 'datasync = (\\d+), ret = (\\d+)'). - exec(eventBase.details.replace('not needed', 'not_needed')); - if (!event) - return false; - - var device = event[1]; - var inode = parseInt(event[2]); - var error = parseInt(event[5]); - var key = device + '-' + inode; - this.closeAsyncSlice(ts, 'f2fs', eventBase.threadName, eventBase.pid, - key, { - device: device, - inode: inode, - error: error - }); - return true; - }, - - ext4SyncFileEnterEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/. - exec(eventBase.details); - if (!event) - return false; - - var device = event[1]; - var inode = parseInt(event[2]); - var datasync = event[4] == 1; - var key = device + '-' + inode; - var action = datasync ? 'fdatasync' : 'fsync'; - this.openAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid, - key, action); - return true; - }, - - ext4SyncFileExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details); - if (!event) - return false; - - var device = event[1]; - var inode = parseInt(event[2]); - var error = parseInt(event[3]); - var key = device + '-' + inode; - this.closeAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid, - key, { - device: device, - inode: inode, - error: error - }); - return true; - }, - - blockRqIssueEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' + - '\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details); - if (!event) - return false; - - var action; - switch (event[3]) { - case 'D': - action = 'discard'; - break; - case 'W': - action = 'write'; - break; - case 'R': - action = 'read'; - break; - case 'N': - action = 'none'; - break; - default: - action = 'unknown'; - break; - } - - if (event[2]) { - action += ' flush'; - } - if (event[4] == 'F') { - action += ' fua'; - } - if (event[5] == 'A') { - action += ' ahead'; - } - if (event[6] == 'S') { - action += ' sync'; - } - if (event[7] == 'M') { - action += ' meta'; - } - var device = event[1]; - var sector = parseInt(event[8]); - var numSectors = parseInt(event[9]); - var key = device + '-' + sector + '-' + numSectors; - this.openAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid, - key, action); - return true; - }, - - blockRqCompleteEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' + - '\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details); - if (!event) - return false; - - var device = event[1]; - var sector = parseInt(event[8]); - var numSectors = parseInt(event[9]); - var error = parseInt(event[10]); - var key = device + '-' + sector + '-' + numSectors; - this.closeAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid, - key, { - device: device, - sector: sector, - numSectors: numSectors, - error: error - }); - return true; - } - }; - - Parser.register(DiskParser); - - return { - DiskParser: DiskParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/disk_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/disk_parser_test.html deleted file mode 100644 index c2e9a14deab..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/disk_parser_test.html +++ /dev/null @@ -1,119 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('diskImport', function() { - var lines = [ - // NB: spliced from different traces; mismatched timestamps don't matter - 'AsyncTask #2-18830 [000] ...1 154578.668286: ext4_sync_file_enter: ' + - 'dev 259,1 ino 81993 parent 81906 datasync 1', - 'Binder_A-3179 [001] ...1 1354.510088: f2fs_sync_file_enter: ' + - 'dev = (259,14), ino = 4882, pino = 313, i_mode = 0x81b0, i_size = ' + - '25136, i_nlink = 1, i_blocks = 8, i_advise = 0x0', - 'Binder_A-3179 [001] ...1 1354.514013: f2fs_sync_file_exit: ' + - 'dev = (259,14), ino = 4882, checkpoint is not needed, datasync = 1, ret = 0', // @suppress longLineCheck - 'mmcqd/0-81 [000] d..2 154578.668390: block_rq_issue: ' + - '179,0 WS 0 () 3427120 + 16 [mmcqd/0]', - 'mmcqd/0-81 [000] d..2 154578.669181: block_rq_complete: ' + - '179,0 WS () 3427120 + 16 [0]', - 'mmcqd/0-81 [001] d..2 154578.670853: block_rq_issue: ' + - '179,0 FWS 0 () 18446744073709551615 + 0 [mmcqd/0]', - 'mmcqd/0-81 [001] d..2 154578.670869: block_rq_complete: ' + - '179,0 FWS () 18446744073709551615 + 0 [0]', - 'AsyncTask #2-18830 [001] ...1 154578.670901: ext4_sync_file_exit: ' + - 'dev 259,1 ino 81993 ret 0', - 'mmcqd/0-81 [001] d..2 154578.877038: block_rq_issue: ' + - '179,0 R 0 () 3255256 + 8 [mmcqd/0]', - 'mmcqd/0-81 [001] d..2 154578.877110: block_rq_issue: ' + - '179,0 R 0 () 3255288 + 8 [mmcqd/0]', - 'mmcqd/0-81 [000] d..2 154578.877345: block_rq_complete: ' + - '179,0 R () 3255256 + 8 [0]', - 'mmcqd/0-81 [000] d..2 154578.877466: block_rq_complete: ' + - '179,0 R () 3255288 + 8 [0]', - 'ContactsProvide-1184 [000] ...1 66.613719: f2fs_write_begin: ' + - 'dev = (253,2), ino = 3342, pos = 0, len = 75, flags = 0', - 'ContactsProvide-1184 [000] ...1 66.613733: f2fs_write_end: ' + - 'dev = (253,2), ino = 3342, pos = 0, len = 75, copied = 75' - ]; - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var blockThread = undefined; - var ext4Thread = undefined; - var f2fsSyncThread = undefined; - var f2fsWriteThread = undefined; - - m.getAllThreads().forEach(function(t) { - switch (t.name) { - case 'block:mmcqd/0': - blockThread = t; - break; - case 'ext4:AsyncTask #2': - ext4Thread = t; - break; - case 'f2fs:Binder_A': - f2fsSyncThread = t; - break; - case 'f2fs:ContactsProvide': - f2fsWriteThread = t; - break; - default: - throw new unittest.TestError('Unexpected thread named ' + t.name); - } - }); - assert.isDefined(blockThread); - assert.isDefined(ext4Thread); - assert.isDefined(f2fsSyncThread); - assert.isDefined(f2fsWriteThread); - - assert.equal(blockThread.asyncSliceGroup.length, 4); - - var slice = blockThread.asyncSliceGroup.slices[0]; - assert.equal(slice.category, 'block'); - assert.equal(slice.title, 'write sync'); - assert.equal(slice.args.device, '179,0'); - assert.equal(slice.args.error, 0); - assert.equal(slice.args.numSectors, 16); - assert.equal(slice.args.sector, 3427120); - - assert.equal(ext4Thread.asyncSliceGroup.length, 1); - - slice = ext4Thread.asyncSliceGroup.slices[0]; - assert.equal(slice.category, 'ext4'); - assert.equal(slice.title, 'fdatasync'); - assert.equal(slice.args.device, '259,1'); - assert.equal(slice.args.error, 0); - assert.equal(slice.args.inode, 81993); - - assert.equal(f2fsSyncThread.asyncSliceGroup.length, 1); - - slice = f2fsSyncThread.asyncSliceGroup.slices[0]; - assert.equal(slice.category, 'f2fs'); - assert.equal(slice.title, 'fsync'); - assert.equal(slice.args.device, '259,14'); - assert.equal(slice.args.error, 0); - assert.equal(slice.args.inode, 4882); - - assert.equal(f2fsWriteThread.asyncSliceGroup.length, 1); - - slice = f2fsWriteThread.asyncSliceGroup.slices[0]; - assert.equal(slice.category, 'f2fs'); - assert.equal(slice.title, 'f2fs_write'); - assert.equal(slice.args.device, '253,2'); - assert.equal(slice.args.inode, 3342); - assert.equal(slice.args.error, false); - }); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/drm_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/drm_parser.html deleted file mode 100644 index 78dd9515f25..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/drm_parser.html +++ /dev/null @@ -1,71 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses drm driver events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux drm trace events. - * @constructor - */ - function DrmParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('drm_vblank_event', - DrmParser.prototype.vblankEvent.bind(this)); - } - - DrmParser.prototype = { - __proto__: Parser.prototype, - - drmVblankSlice: function(ts, eventName, args) { - var kthread = this.importer.getOrCreatePseudoThread('drm_vblank'); - kthread.openSlice = eventName; - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - ts, args, 0); - - kthread.thread.sliceGroup.pushSlice(slice); - }, - - /** - * Parses drm driver events and sets up state in the importer. - */ - vblankEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /crtc=(\d+), seq=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var crtc = parseInt(event[1]); - var seq = parseInt(event[2]); - this.drmVblankSlice(ts, 'vblank:' + crtc, - { - crtc: crtc, - seq: seq - }); - return true; - } - }; - - Parser.register(DrmParser); - - return { - DrmParser: DrmParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/drm_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/drm_parser_test.html deleted file mode 100644 index cdb214fb2de..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/drm_parser_test.html +++ /dev/null @@ -1,34 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('drmImport', function() { - var lines = [ - ' chrome-2465 [000] 71.653157: drm_vblank_event: crtc=0, seq=4233', - ' <idle>-0 [000] 71.669851: drm_vblank_event: crtc=0, seq=4234' - ]; - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var vblankThread = threads[0]; - assert.equal(vblankThread.name, 'drm_vblank'); - assert.equal(vblankThread.sliceGroup.length, 2); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/exynos_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/exynos_parser.html deleted file mode 100644 index e573b8d25a1..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/exynos_parser.html +++ /dev/null @@ -1,128 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses exynos events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux exynos trace events. - * @constructor - */ - function ExynosParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('exynos_busfreq_target_int', - ExynosParser.prototype.busfreqTargetIntEvent.bind(this)); - importer.registerEventHandler('exynos_busfreq_target_mif', - ExynosParser.prototype.busfreqTargetMifEvent.bind(this)); - - importer.registerEventHandler('exynos_page_flip_state', - ExynosParser.prototype.pageFlipStateEvent.bind(this)); - } - - ExynosParser.prototype = { - __proto__: Parser.prototype, - - exynosBusfreqSample: function(name, ts, frequency) { - var targetCpu = this.importer.getOrCreateCpu(0); - var counter = targetCpu.getOrCreateCounter('', name); - if (counter.numSeries === 0) { - counter.addSeries(new tr.model.CounterSeries('frequency', - ColorScheme.getColorIdForGeneralPurposeString( - counter.name + '.' + 'frequency'))); - } - counter.series.forEach(function(series) { - series.addCounterSample(ts, frequency); - }); - }, - - /** - * Parses exynos_busfreq_target_int events and sets up state. - */ - busfreqTargetIntEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /frequency=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - this.exynosBusfreqSample('INT Frequency', ts, parseInt(event[1])); - return true; - }, - - /** - * Parses exynos_busfreq_target_mif events and sets up state. - */ - busfreqTargetMifEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /frequency=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - this.exynosBusfreqSample('MIF Frequency', ts, parseInt(event[1])); - return true; - }, - - exynosPageFlipStateOpenSlice: function(ts, pipe, fb, state) { - var kthread = this.importer.getOrCreatePseudoThread( - 'exynos_flip_state (pipe:' + pipe + ', fb:' + fb + ')'); - kthread.openSliceTS = ts; - kthread.openSlice = state; - }, - - exynosPageFlipStateCloseSlice: function(ts, pipe, fb, args) { - var kthread = this.importer.getOrCreatePseudoThread( - 'exynos_flip_state (pipe:' + pipe + ', fb:' + fb + ')'); - if (kthread.openSlice) { - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - kthread.openSliceTS, - args, - ts - kthread.openSliceTS); - kthread.thread.sliceGroup.pushSlice(slice); - } - kthread.openSlice = undefined; - }, - - /** - * Parses page_flip_state events and sets up state in the importer. - */ - pageFlipStateEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details); - if (!event) - return false; - - var pipe = parseInt(event[1]); - var fb = parseInt(event[2]); - var state = event[3]; - - this.exynosPageFlipStateCloseSlice(ts, pipe, fb, - { - pipe: pipe, - fb: fb - }); - if (state !== 'flipped') - this.exynosPageFlipStateOpenSlice(ts, pipe, fb, state); - return true; - } - }; - - Parser.register(ExynosParser); - - return { - ExynosParser: ExynosParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/exynos_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/exynos_parser_test.html deleted file mode 100644 index c27e7c65a93..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/exynos_parser_test.html +++ /dev/null @@ -1,128 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('exynosBusfreqImport', function() { - var lines = [ - ' kworker/1:0-4177 [001] .... 2803.129806: ' + - 'exynos_busfreq_target_int: frequency=200000', - ' kworker/1:0-4177 [001] .... 2803.229207: ' + - 'exynos_busfreq_target_int: frequency=267000', - ' kworker/1:0-4177 [001] .... 2803.329031: ' + - 'exynos_busfreq_target_int: frequency=160000', - ' kworker/1:0-4177 [001] .... 2805.729039: ' + - 'exynos_busfreq_target_mif: frequency=200000' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c0 = m.kernel.cpus[0]; - assert.equal(c0.slices.length, 0); - assert.equal(c0.counters['.INT Frequency'].series[0].samples.length, 3); - assert.equal(c0.counters['.MIF Frequency'].series[0].samples.length, 1); - }); - - test('exynosPageFlipSlowRequestImport', function() { - var lines = [ - ' <idle>-0 [000] d.h. 1000.000000: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=wait_kds', - ' Chrome_IOThread-21603 [000] d.h. 1000.000001: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=wait_apply', - ' kworker/0:1-25931 [000] .... 1000.000002: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=wait_flip', - ' kworker/0:1-25931 [000] .... 1000.000003: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=flipped', - ' <idle>-0 [000] d.h. 1000.000004: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=wait_kds', - ' Chrome_IOThread-21603 [000] d.h. 1000.000005: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=wait_apply', - ' kworker/0:1-25931 [000] .... 1000.000006: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=wait_flip', - ' kworker/0:1-25931 [000] .... 1000.000007: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=flipped' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - // there are 2 threads: - // (1) "exynos_flip_state (pipe:0, fb:25)" - // (2) "exynos_flip_state (pipe:0, fb:26)" - assert.equal(threads.length, 2); - - // in the test data, event of fb=26 occurs first, so it's thread[0] - var gfxFbId26Thread = threads[0]; // thread where fb == 26 - var gfxFbId25Thread = threads[1]; // thread where fb == 25 - assert.equal(gfxFbId25Thread.name, 'exynos_flip_state (pipe:0, fb:25)'); - assert.equal(gfxFbId26Thread.name, 'exynos_flip_state (pipe:0, fb:26)'); - // Every state (except for 'flipped') will start a new slice. - // The last event will not be closed, so it's not a slice - assert.equal(gfxFbId25Thread.sliceGroup.length, 3); - assert.equal(gfxFbId26Thread.sliceGroup.length, 3); - }); - - test('exynosPageFlipFastRequestImport', function() { - var lines = [ - ' <idle>-0 [000] d.h. 1000.000000: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=wait_kds', - ' Chrome_IOThread-21603 [000] d.h. 1000.000001: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=wait_kds', - ' X-21385 [000] .... 1000.000002: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=wait_apply', - ' kworker/0:1-25931 [000] .... 1000.000003: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=wait_flip', - ' X-21385 [001] .... 1000.000004: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=wait_apply', - ' kworker/0:1-25931 [000] .... 1000.000005: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=flipped', - ' <idle>-0 [000] d.h. 1000.000006: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=wait_kds', - ' X-21385 [000] .... 1000.000007: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=wait_flip', - ' kworker/0:1-25931 [000] .... 1000.000008: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=flipped', - ' kworker/0:1-25931 [000] .... 1000.000009: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=wait_kds', - ' Chrome_IOThread-21603 [000] d.h. 1000.000010: ' + - 'exynos_page_flip_state: pipe=0, fb=25, state=wait_apply', - ' <idle>-0 [000] d.h. 1000.000011: ' + - 'exynos_page_flip_state: pipe=0, fb=26, state=wait_apply' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - // there are 2 threads: - // (1) "exynos_flip_state (pipe:0, fb:25)" - // (2) "exynos_flip_state (pipe:0, fb:26)" - assert.equal(threads.length, 2); - - // in the test data, event of fb=26 occurs first, so it's thread[0] - var gfxFbId26Thread = threads[0]; // thread where fb == 26 - var gfxFbId25Thread = threads[1]; // thread where fb == 25 - assert.equal(gfxFbId25Thread.name, 'exynos_flip_state (pipe:0, fb:25)'); - assert.equal(gfxFbId26Thread.name, 'exynos_flip_state (pipe:0, fb:26)'); - // Every state (except for 'flipped') will start a new slice. - // The last event will not be closed, so it's not a slice - assert.equal(gfxFbId25Thread.sliceGroup.length, 4); - assert.equal(gfxFbId26Thread.sliceGroup.length, 4); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer.html deleted file mode 100644 index 477223b1640..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer.html +++ /dev/null @@ -1,920 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/base/color_scheme.html"> -<link rel="import" href="/tracing/base/iteration_helpers.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/android_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/binder_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/bus_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/clock_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/cpufreq_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/disk_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/drm_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/exynos_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/gesture_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/i915_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/irq_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/kfunc_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/mali_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/memreclaim_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/power_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/regulator_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/sched_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/sync_parser.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/workqueue_parser.html"> -<link rel="import" href="/tracing/importer/importer.html"> -<link rel="import" href="/tracing/importer/simple_line_reader.html"> -<link rel="import" href="/tracing/model/clock_sync_manager.html"> -<link rel="import" href="/tracing/model/model.html"> - -<script> -/** - * @fileoverview Imports text files in the Linux event trace format into the - * Model. This format is output both by sched_trace and by Linux's perf tool. - * - * This importer assumes the events arrive as a string. The unit tests provide - * examples of the trace format. - * - * Linux scheduler traces use a definition for 'pid' that is different than - * tracing uses. Whereas tracing uses pid to identify a specific process, a pid - * in a linux trace refers to a specific thread within a process. Within this - * file, we the definition used in Linux traces, as it improves the importing - * code's readability. - */ -'use strict'; - -tr.exportTo('tr.e.importer.linux_perf', function() { - var MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID = - 'linux_clock_monotonic_to_ftrace_global'; - - /** - * Imports linux perf events into a specified model. - * @constructor - */ - function FTraceImporter(model, events) { - this.importPriority = 2; - this.model_ = model; - this.events_ = events; - this.wakeups_ = []; - this.blocked_reasons_ = []; - this.kernelThreadStates_ = {}; - this.buildMapFromLinuxPidsToThreads_(); - this.lines_ = []; - this.pseudoThreadCounter = 1; - this.parsers_ = []; - this.eventHandlers_ = {}; - this.haveClockSyncedMonotonicToGlobal_ = false; - } - - var TestExports = {}; - - // Matches the trace record in 3.2 and later with the print-tgid option: - // <idle>-0 0 [001] d... 1.23: sched_switch - // - // A TGID (Thread Group ID) is basically what the Linux kernel calls what - // userland refers to as a process ID (as opposed to a Linux pid, which is - // what userland calls a thread ID). - var lineREWithTGID = new RegExp( - '^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]' + - '\\s+[dX.][Nnp.][Hhs.][0-9a-f.]' + - '\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$'); - var lineParserWithTGID = function(line) { - var groups = lineREWithTGID.exec(line); - if (!groups) { - return groups; - } - - var tgid = groups[3]; - if (tgid[0] === '-') - tgid = undefined; - - return { - threadName: groups[1], - pid: groups[2], - tgid: tgid, - cpuNumber: groups[4], - timestamp: groups[5], - eventName: groups[6], - details: groups[7] - }; - }; - TestExports.lineParserWithTGID = lineParserWithTGID; - - // Matches the default trace record in 3.2 and later (includes irq-info): - // <idle>-0 [001] d... 1.23: sched_switch - var lineREWithIRQInfo = new RegExp( - '^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]' + - '\\s+[dX.][Nnp.][Hhs.][0-9a-f.]' + - '\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$'); - var lineParserWithIRQInfo = function(line) { - var groups = lineREWithIRQInfo.exec(line); - if (!groups) { - return groups; - } - return { - threadName: groups[1], - pid: groups[2], - cpuNumber: groups[3], - timestamp: groups[4], - eventName: groups[5], - details: groups[6] - }; - }; - TestExports.lineParserWithIRQInfo = lineParserWithIRQInfo; - - // Matches the default trace record pre-3.2: - // <idle>-0 [001] 1.23: sched_switch - var lineREWithLegacyFmt = - /^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/; - var lineParserWithLegacyFmt = function(line) { - var groups = lineREWithLegacyFmt.exec(line); - if (!groups) { - return groups; - } - return { - threadName: groups[1], - pid: groups[2], - cpuNumber: groups[3], - timestamp: groups[4], - eventName: groups[5], - details: groups[6] - }; - }; - TestExports.lineParserWithLegacyFmt = lineParserWithLegacyFmt; - - // Matches the trace_event_clock_sync marker: - // 0: trace_event_clock_sync: parent_ts=19581477508 - var traceEventClockSyncRE = /trace_event_clock_sync: parent_ts=(\d+\.?\d*)/; - TestExports.traceEventClockSyncRE = traceEventClockSyncRE; - - var realTimeClockSyncRE = /trace_event_clock_sync: realtime_ts=(\d+)/; - var genericClockSyncRE = /trace_event_clock_sync: name=(\w+)/; - - // Some kernel trace events are manually classified in slices and - // hand-assigned a pseudo PID. - var pseudoKernelPID = 0; - - /** - * Deduce the format of trace data. Linux kernels prior to 3.3 used one - * format (by default); 3.4 and later used another. Additionally, newer - * kernels can optionally trace the TGID. - * - * @return {function} the function for parsing data when the format is - * recognized; otherwise undefined. - */ - function autoDetectLineParser(line) { - if (line[0] == '{') - return false; - if (lineREWithTGID.test(line)) - return lineParserWithTGID; - if (lineREWithIRQInfo.test(line)) - return lineParserWithIRQInfo; - if (lineREWithLegacyFmt.test(line)) - return lineParserWithLegacyFmt; - return undefined; - }; - TestExports.autoDetectLineParser = autoDetectLineParser; - - /** - * Guesses whether the provided events is a Linux perf string. - * Looks for the magic string "# tracer" at the start of the file, - * or the typical task-pid-cpu-timestamp-function sequence of a typical - * trace's body. - * - * @return {boolean} True when events is a linux perf array. - */ - FTraceImporter.canImport = function(events) { - if (!(typeof(events) === 'string' || events instanceof String)) - return false; - - if (FTraceImporter._extractEventsFromSystraceHTML(events, false).ok) - return true; - - if (FTraceImporter._extractEventsFromSystraceMultiHTML(events, false).ok) - return true; - - if (/^# tracer:/.test(events)) - return true; - - var lineBreakIndex = events.indexOf('\n'); - if (lineBreakIndex > -1) - events = events.substring(0, lineBreakIndex); - - if (autoDetectLineParser(events)) - return true; - - return false; - }; - - FTraceImporter._extractEventsFromSystraceHTML = function( - incoming_events, produce_result) { - var failure = {ok: false}; - if (produce_result === undefined) - produce_result = true; - - if (/^<!DOCTYPE html>/.test(incoming_events) == false) - return failure; - var r = new tr.importer.SimpleLineReader(incoming_events); - - // Try to find the data... - if (!r.advanceToLineMatching(/^ <script>$/)) - return failure; - if (!r.advanceToLineMatching(/^ var linuxPerfData = "\\$/)) - return failure; - - var events_begin_at_line = r.curLineNumber + 1; - r.beginSavingLines(); - if (!r.advanceToLineMatching(/^ <\/script>$/)) - return failure; - - var raw_events = r.endSavingLinesAndGetResult(); - - // Drop off first and last event as it contains the tag. - raw_events = raw_events.slice(1, raw_events.length - 1); - - if (!r.advanceToLineMatching(/^<\/body>$/)) - return failure; - if (!r.advanceToLineMatching(/^<\/html>$/)) - return failure; - - function endsWith(str, suffix) { - return str.indexOf(suffix, str.length - suffix.length) !== -1; - } - function stripSuffix(str, suffix) { - if (!endsWith(str, suffix)) - return str; - return str.substring(str, str.length - suffix.length); - } - - // Strip off escaping in the file needed to preserve linebreaks. - var events = []; - if (produce_result) { - for (var i = 0; i < raw_events.length; i++) { - var event = raw_events[i]; - event = stripSuffix(event, '\\n\\'); - events.push(event); - } - } else { - events = [raw_events[raw_events.length - 1]]; - } - - // Last event ends differently. Strip that off too, - // treating absence of that trailing string as a failure. - var oldLastEvent = events[events.length - 1]; - var newLastEvent = stripSuffix(oldLastEvent, '\\n";'); - if (newLastEvent == oldLastEvent) - return failure; - events[events.length - 1] = newLastEvent; - - return {ok: true, - lines: produce_result ? events : undefined, - events_begin_at_line: events_begin_at_line}; - }; - - FTraceImporter._extractEventsFromSystraceMultiHTML = function( - incoming_events, produce_result) { - var failure = {ok: false}; - if (produce_result === undefined) - produce_result = true; - - if (new RegExp('^<!DOCTYPE HTML>', 'i').test(incoming_events) == false) - return failure; - - var r = new tr.importer.SimpleLineReader(incoming_events); - - // Try to find the Linux perf trace in any of the trace-data tags - var events = []; - while (!/^# tracer:/.test(events)) { - if (!r.advanceToLineMatching( - /^ <script class="trace-data" type="application\/text">$/)) - return failure; - - var events_begin_at_line = r.curLineNumber + 1; - - r.beginSavingLines(); - if (!r.advanceToLineMatching(/^ <\/script>$/)) - return failure; - - events = r.endSavingLinesAndGetResult(); - - // Drop off first and last event as it contains the tag. - events = events.slice(1, events.length - 1); - } - - if (!r.advanceToLineMatching(/^<\/body>$/)) - return failure; - if (!r.advanceToLineMatching(/^<\/html>$/)) - return failure; - - return {ok: true, - lines: produce_result ? events : undefined, - events_begin_at_line: events_begin_at_line}; - }; - - FTraceImporter.prototype = { - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'FTraceImporter'; - }, - - get model() { - return this.model_; - }, - - /** - * Imports clock sync markers into model_. - */ - importClockSyncMarkers: function() { - this.lazyInit_(); - - this.forEachLine_(function(text, eventBase, cpuNumber, pid, ts) { - var eventName = eventBase.eventName; - if (eventName !== 'tracing_mark_write' && eventName !== '0') - return; - - if (traceEventClockSyncRE.exec(eventBase.details) || - genericClockSyncRE.exec(eventBase.details)) { - this.traceClockSyncEvent_(eventName, cpuNumber, pid, ts, eventBase); - } else if (realTimeClockSyncRE.exec(eventBase.details)) { - // TODO(charliea): Migrate this sync to ClockSyncManager. - // This entry syncs CLOCK_REALTIME with CLOCK_MONOTONIC. Store the - // offset between the two in the model so that importers parsing files - // with CLOCK_REALTIME timestamps can map back to CLOCK_MONOTONIC. - var match = realTimeClockSyncRE.exec(eventBase.details); - this.model_.realtime_to_monotonic_offset_ms = ts - match[1]; - } - }.bind(this)); - }, - - /** - * Imports the data in this.events_ into model_. - */ - importEvents: function() { - var modelTimeTransformer = - this.model_.clockSyncManager.getModelTimeTransformer( - tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL); - - this.importCpuData_(modelTimeTransformer); - this.buildMapFromLinuxPidsToThreads_(); - this.buildPerThreadCpuSlicesFromCpuState_(); - }, - - /** - * Registers a linux perf event parser used by importCpuData_. - */ - registerEventHandler: function(eventName, handler) { - // TODO(sleffler) how to handle conflicts? - this.eventHandlers_[eventName] = handler; - }, - - /** - * @return {Cpu} A Cpu corresponding to the given cpuNumber. - */ - getOrCreateCpu: function(cpuNumber) { - return this.model_.kernel.getOrCreateCpu(cpuNumber); - }, - - /** - * @return {TimelineThread} A thread corresponding to the kernelThreadName. - */ - getOrCreateKernelThread: function(kernelThreadName, pid, tid) { - if (!this.kernelThreadStates_[kernelThreadName]) { - var thread = this.model_.getOrCreateProcess(pid).getOrCreateThread(tid); - thread.name = kernelThreadName; - this.kernelThreadStates_[kernelThreadName] = { - pid: pid, - thread: thread, - openSlice: undefined, - openSliceTS: undefined - }; - this.threadsByLinuxPid[pid] = thread; - } - return this.kernelThreadStates_[kernelThreadName]; - }, - - /** - * Processes can have multiple binder threads. - * Binder thread names are not unique across processes we therefore need to - * keep more information in order to return the correct threads. - */ - getOrCreateBinderKernelThread: function(kernelThreadName, pid, tid) { - var key = kernelThreadName + pid + tid; - if (!this.kernelThreadStates_[key]) { - var thread = this.model_.getOrCreateProcess(pid).getOrCreateThread(tid); - thread.name = kernelThreadName; - this.kernelThreadStates_[key] = { - pid: pid, - thread: thread, - openSlice: undefined, - openSliceTS: undefined - }; - this.threadsByLinuxPid[pid] = thread; - } - return this.kernelThreadStates_[key]; - }, - - /** - * @return {TimelineThread} A pseudo thread corresponding to the - * threadName. Pseudo threads are for events that we want to break - * out to a separate timeline but would not otherwise happen. - * These threads are assigned to pseudoKernelPID and given a - * unique (incrementing) TID. - */ - getOrCreatePseudoThread: function(threadName) { - var thread = this.kernelThreadStates_[threadName]; - if (!thread) { - thread = this.getOrCreateKernelThread(threadName, pseudoKernelPID, - this.pseudoThreadCounter); - this.pseudoThreadCounter++; - } - return thread; - }, - - /** - * Records the fact that a pid has become runnable. This data will - * eventually get used to derive each thread's timeSlices array. - */ - markPidRunnable: function(ts, pid, comm, prio, fromPid) { - // The the pids that get passed in to this function are Linux kernel - // pids, which identify threads. The rest of trace-viewer refers to - // these as tids, so the change of nomenclature happens in the following - // construction of the wakeup object. - this.wakeups_.push({ts: ts, tid: pid, fromTid: fromPid}); - }, - - /** - * Records the reason why a pid has gone into uninterruptible sleep. - */ - addPidBlockedReason: function(ts, pid, iowait, caller) { - // The the pids that get passed in to this function are Linux kernel - // pids, which identify threads. The rest of trace-viewer refers to - // these as tids, so the change of nomenclature happens in the following - // construction of the wakeup object. - this.blocked_reasons_.push({ts: ts, tid: pid, iowait: iowait, - caller: caller}); - }, - - /** - * Precomputes a lookup table from linux pids back to existing - * Threads. This is used during importing to add information to each - * thread about whether it was running, descheduled, sleeping, et - * cetera. - */ - buildMapFromLinuxPidsToThreads_: function() { - this.threadsByLinuxPid = {}; - this.model_.getAllThreads().forEach( - function(thread) { - this.threadsByLinuxPid[thread.tid] = thread; - }.bind(this)); - }, - - /** - * Builds the timeSlices array on each thread based on our knowledge of what - * each Cpu is doing. This is done only for Threads that are - * already in the model, on the assumption that not having any traced data - * on a thread means that it is not of interest to the user. - */ - buildPerThreadCpuSlicesFromCpuState_: function() { - var SCHEDULING_STATE = tr.model.SCHEDULING_STATE; - - // Push the cpu slices to the threads that they run on. - for (var cpuNumber in this.model_.kernel.cpus) { - var cpu = this.model_.kernel.cpus[cpuNumber]; - - for (var i = 0; i < cpu.slices.length; i++) { - var cpuSlice = cpu.slices[i]; - - var thread = this.threadsByLinuxPid[cpuSlice.args.tid]; - if (!thread) - continue; - - cpuSlice.threadThatWasRunning = thread; - - if (!thread.tempCpuSlices) - thread.tempCpuSlices = []; - thread.tempCpuSlices.push(cpuSlice); - } - } - - for (var i in this.wakeups_) { - var wakeup = this.wakeups_[i]; - var thread = this.threadsByLinuxPid[wakeup.tid]; - if (!thread) - continue; - thread.tempWakeups = thread.tempWakeups || []; - thread.tempWakeups.push(wakeup); - } - for (var i in this.blocked_reasons_) { - var reason = this.blocked_reasons_[i]; - var thread = this.threadsByLinuxPid[reason.tid]; - if (!thread) - continue; - thread.tempBlockedReasons = thread.tempBlockedReasons || []; - thread.tempBlockedReasons.push(reason); - } - - // Create slices for when the thread is not running. - this.model_.getAllThreads().forEach(function(thread) { - if (thread.tempCpuSlices === undefined) - return; - var origSlices = thread.tempCpuSlices; - delete thread.tempCpuSlices; - - origSlices.sort(function(x, y) { - return x.start - y.start; - }); - - var wakeups = thread.tempWakeups || []; - delete thread.tempWakeups; - wakeups.sort(function(x, y) { - return x.ts - y.ts; - }); - - var reasons = thread.tempBlockedReasons || []; - delete thread.tempBlockedReasons; - reasons.sort(function(x, y) { - return x.ts - y.ts; - }); - - // Walk the slice list and put slices between each original slice to - // show when the thread isn't running. - var slices = []; - - if (origSlices.length) { - var slice = origSlices[0]; - - if (wakeups.length && wakeups[0].ts < slice.start) { - var wakeup = wakeups.shift(); - var wakeupDuration = slice.start - wakeup.ts; - var args = {'wakeup from tid': wakeup.fromTid}; - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.RUNNABLE, '', - wakeup.ts, args, wakeupDuration)); - } - - var runningSlice = new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.RUNNING, '', - slice.start, {}, slice.duration); - runningSlice.cpuOnWhichThreadWasRunning = slice.cpu; - slices.push(runningSlice); - } - - var wakeup = undefined; - for (var i = 1; i < origSlices.length; i++) { - var prevSlice = origSlices[i - 1]; - var nextSlice = origSlices[i]; - var midDuration = nextSlice.start - prevSlice.end; - while (wakeups.length && wakeups[0].ts < nextSlice.start) { - var w = wakeups.shift(); - if (wakeup === undefined && w.ts > prevSlice.end) { - wakeup = w; - } - } - var blocked_reason = undefined; - while (reasons.length && reasons[0].ts < prevSlice.end) { - var r = reasons.shift(); - } - if (wakeup !== undefined && - reasons.length && - reasons[0].ts < wakeup.ts) { - blocked_reason = reasons.shift(); - } - - // Push a sleep slice onto the slices list, interrupting it with a - // wakeup if appropriate. - var pushSleep = function(state) { - if (wakeup !== undefined) { - midDuration = wakeup.ts - prevSlice.end; - } - - if (blocked_reason !== undefined) { - var args = { - 'kernel callsite when blocked:' : blocked_reason.caller - }; - if (blocked_reason.iowait) { - switch (state) { - case SCHEDULING_STATE.UNINTR_SLEEP: - state = SCHEDULING_STATE.UNINTR_SLEEP_IO; - break; - case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL: - state = SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO; - break; - case SCHEDULING_STATE.UNINTR_SLEEP_WAKING: - state = SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO; - break; - default: - } - } - slices.push(new tr.model.ThreadTimeSlice( - thread, - state, '', prevSlice.end, args, midDuration)); - } else { - slices.push(new tr.model.ThreadTimeSlice( - thread, - state, '', prevSlice.end, {}, midDuration)); - } - if (wakeup !== undefined) { - var wakeupDuration = nextSlice.start - wakeup.ts; - var args = {'wakeup from tid': wakeup.fromTid}; - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.RUNNABLE, '', - wakeup.ts, args, wakeupDuration)); - wakeup = undefined; - } - }; - - if (prevSlice.args.stateWhenDescheduled == 'S') { - pushSleep(SCHEDULING_STATE.SLEEPING); - } else if (prevSlice.args.stateWhenDescheduled == 'R' || - prevSlice.args.stateWhenDescheduled == 'R+') { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.RUNNABLE, '', - prevSlice.end, {}, midDuration)); - } else if (prevSlice.args.stateWhenDescheduled == 'D') { - pushSleep(SCHEDULING_STATE.UNINTR_SLEEP); - } else if (prevSlice.args.stateWhenDescheduled == 'T') { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.STOPPED, '', - prevSlice.end, {}, midDuration)); - } else if (prevSlice.args.stateWhenDescheduled == 't') { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.DEBUG, '', - prevSlice.end, {}, midDuration)); - } else if (prevSlice.args.stateWhenDescheduled == 'Z') { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.ZOMBIE, '', - prevSlice.end, {}, midDuration)); - } else if (prevSlice.args.stateWhenDescheduled == 'X') { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.EXIT_DEAD, '', - prevSlice.end, {}, midDuration)); - } else if (prevSlice.args.stateWhenDescheduled == 'x') { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.TASK_DEAD, '', - prevSlice.end, {}, midDuration)); - } else if (prevSlice.args.stateWhenDescheduled == 'K') { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.WAKE_KILL, '', - prevSlice.end, {}, midDuration)); - } else if (prevSlice.args.stateWhenDescheduled == 'W') { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.WAKING, '', - prevSlice.end, {}, midDuration)); - } else if (prevSlice.args.stateWhenDescheduled == 'D|K') { - pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL); - } else if (prevSlice.args.stateWhenDescheduled == 'D|W') { - pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING); - } else { - slices.push(new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.UNKNOWN, '', - prevSlice.end, {}, midDuration)); - this.model_.importWarning({ - type: 'parse_error', - message: 'Unrecognized sleep state: ' + - prevSlice.args.stateWhenDescheduled - }); - } - - var runningSlice = new tr.model.ThreadTimeSlice( - thread, SCHEDULING_STATE.RUNNING, '', - nextSlice.start, {}, nextSlice.duration); - runningSlice.cpuOnWhichThreadWasRunning = prevSlice.cpu; - slices.push(runningSlice); - } - thread.timeSlices = slices; - }, this); - }, - - /** - * Creates an instance of each registered linux perf event parser. - * This allows the parsers to register handlers for the events they - * understand. We also register our own special handlers (for the - * timestamp synchronization markers). - */ - createParsers_: function() { - // Instantiate the parsers; this will register handlers for known events - var allTypeInfos = tr.e.importer.linux_perf. - Parser.getAllRegisteredTypeInfos(); - var parsers = allTypeInfos.map( - function(typeInfo) { - return new typeInfo.constructor(this); - }, this); - - return parsers; - }, - - registerDefaultHandlers_: function() { - this.registerEventHandler('tracing_mark_write', - FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this)); - // NB: old-style trace markers; deprecated - this.registerEventHandler('0', - FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this)); - // Register dummy clock sync handlers to avoid warnings in the log. - this.registerEventHandler('tracing_mark_write:trace_event_clock_sync', - function() { return true; }); - this.registerEventHandler('0:trace_event_clock_sync', - function() { return true; }); - }, - - /** - * Processes a trace_event_clock_sync event. - */ - traceClockSyncEvent_: function(eventName, cpuNumber, pid, ts, eventBase) { - // Check to see if we have a normal clock sync marker that contains a - // sync ID and the current time according to the "ftrace global" clock. - var event = /name=(\w+?)\s(.+)/.exec(eventBase.details); - if (event) { - var name = event[1]; - var pieces = event[2].split(' '); - var args = { - perfTs: ts - }; - for (var i = 0; i < pieces.length; i++) { - var parts = pieces[i].split('='); - if (parts.length != 2) - throw new Error('omgbbq'); - args[parts[0]] = parts[1]; - } - - this.model_.clockSyncManager.addClockSyncMarker( - tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL, name, ts); - return true; - } - - // Check to see if we have a special clock sync marker that contains both - // the current "ftrace global" time and the current CLOCK_MONOTONIC time. - event = /parent_ts=(\d+\.?\d*)/.exec(eventBase.details); - if (!event) - return false; - - var monotonicTs = event[1] * 1000; - // A monotonic timestamp of zero is used as a sentinel value to indicate - // that CLOCK_MONOTONIC and the ftrace global clock are identical. - if (monotonicTs === 0) - monotonicTs = ts; - - if (this.haveClockSyncedMonotonicToGlobal_) - // ftrace sometimes includes multiple clock syncs between the monotonic - // and global clocks within a single trace. We protect against this by - // only taking the first one into account. - return true; - - // We have a clock sync event that contains two timestamps: a timestamp - // according to the ftrace 'global' clock, and that same timestamp - // according to clock_gettime(CLOCK_MONOTONIC). - this.model_.clockSyncManager.addClockSyncMarker( - tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL, - MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID, ts); - this.model_.clockSyncManager.addClockSyncMarker( - tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC, - MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID, monotonicTs); - - this.haveClockSyncedMonotonicToGlobal_ = true; - return true; - }, - - /** - * Processes a trace_marking_write event. - */ - traceMarkingWriteEvent_: function(eventName, cpuNumber, pid, ts, eventBase, - threadName) { - - // Some profiles end up with a \n\ on the end of each line. Strip it - // before we do the comparisons. - eventBase.details = eventBase.details.replace(/\\n.*$/, ''); - - var event = /^\s*(\w+):\s*(.*)$/.exec(eventBase.details); - if (!event) { - // Check if the event matches events traced by the Android framework - var tag = eventBase.details.substring(0, 2); - if (tag == 'B|' || tag == 'E' || tag == 'E|' || tag == 'X|' || - tag == 'C|' || tag == 'S|' || tag == 'F|') { - eventBase.subEventName = 'android'; - } else { - return false; - } - } else { - eventBase.subEventName = event[1]; - eventBase.details = event[2]; - } - - var writeEventName = eventName + ':' + eventBase.subEventName; - var handler = this.eventHandlers_[writeEventName]; - if (!handler) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Unknown trace_marking_write event ' + writeEventName - }); - return true; - } - return handler(writeEventName, cpuNumber, pid, ts, eventBase, threadName); - }, - - /** - * Walks the this.events_ structure and creates Cpu objects. - */ - importCpuData_: function(modelTimeTransformer) { - this.forEachLine_(function(text, eventBase, cpuNumber, pid, ts) { - var eventName = eventBase.eventName; - var handler = this.eventHandlers_[eventName]; - if (!handler) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Unknown event ' + eventName + ' (' + text + ')' - }); - return; - } - ts = modelTimeTransformer(ts); - if (!handler(eventName, cpuNumber, pid, ts, eventBase)) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Malformed ' + eventName + ' event (' + text + ')' - }); - } - }.bind(this)); - }, - - /** - * Walks the this.events_ structure and populates this.lines_. - */ - parseLines_: function() { - var lines = []; - var extractResult = FTraceImporter._extractEventsFromSystraceHTML( - this.events_, true); - if (!extractResult.ok) - extractResult = FTraceImporter._extractEventsFromSystraceMultiHTML( - this.events_, true); - var lines = extractResult.ok ? - extractResult.lines : this.events_.split('\n'); - - var lineParser = undefined; - for (var lineNumber = 0; lineNumber < lines.length; ++lineNumber) { - var line = lines[lineNumber].trim(); - if (line.length == 0 || /^#/.test(line)) - continue; - - if (!lineParser) { - lineParser = autoDetectLineParser(line); - if (!lineParser) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Cannot parse line: ' + line - }); - continue; - } - } - - var eventBase = lineParser(line); - if (!eventBase) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Unrecognized line: ' + line - }); - continue; - } - - this.lines_.push([ - line, - eventBase, - parseInt(eventBase.cpuNumber), - parseInt(eventBase.pid), - parseFloat(eventBase.timestamp) * 1000 - ]); - } - }, - - /** - * Calls |handler| for every parsed line. - */ - forEachLine_: function(handler) { - for (var i = 0; i < this.lines_.length; ++i) { - var line = this.lines_[i]; - handler.apply(this, line); - } - }, - - /** - * Initializes the ftrace importer. This initialization can't be done in the - * constructor because all trace event handlers may not have been registered - * by that point. - */ - lazyInit_: function() { - this.parsers_ = this.createParsers_(); - this.registerDefaultHandlers_(); - this.parseLines_(); - } - }; - - tr.importer.Importer.register(FTraceImporter); - - return { - FTraceImporter: FTraceImporter, - _FTraceImporterTestExports: TestExports - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer_test.html deleted file mode 100644 index 244e3e28a13..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer_test.html +++ /dev/null @@ -1,530 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> -<link rel="import" href="/tracing/importer/import.html"> -<link rel="import" href="/tracing/model/clock_sync_manager.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - var ClockDomainId = tr.model.ClockDomainId; - var FTraceImporter = tr.e.importer.linux_perf.FTraceImporter; - var FTraceImporterTestExports = - tr.e.importer.linux_perf._FTraceImporterTestExports; - - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('lineParserWithLegacyFmt', function() { - var p = FTraceImporterTestExports.lineParserWithLegacyFmt; - var x = p(' <idle>-0 [001] 4467.843475: sched_switch: ' + - 'prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> ' + - 'next_comm=SurfaceFlinger next_pid=178 next_prio=112'); - assert.isNotNull(x); - assert.equal(x.threadName, '<idle>'); - assert.equal(x.pid, '0'); - assert.equal(x.cpuNumber, '001'); - assert.equal(x.timestamp, '4467.843475'); - assert.equal(x.eventName, 'sched_switch'); - assert.equal('prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R' + - ' ==> next_comm=SurfaceFlinger next_pid=178 next_prio=112', x.details); - - var x = p('Binder-Thread #-647 [001] 260.464294: sched_switch: ' + - 'prev_comm=Binder Thread # prev_pid=647 prev_prio=120 prev_state=D ' + - ' ==> next_comm=.android.chrome next_pid=1562 next_prio=120'); - assert.isNotNull(x); - assert.equal(x.threadName, 'Binder-Thread #'); - assert.equal(x.pid, '647'); - }); - - test('lineParserWithIRQInfo', function() { - var p = FTraceImporterTestExports.lineParserWithIRQInfo; - var x = p(' systrace.sh-5441 [001] d... 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x.threadName, 'systrace.sh'); - assert.equal(x.pid, '5441'); - assert.equal(x.cpuNumber, '001'); - assert.equal(x.timestamp, '1031.091570'); - assert.equal(x.eventName, 'sched_wakeup'); - assert.equal(x.details, 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); // @suppress longLineCheck - }); - - test('lineParserWithIRQInfoNeedResched', function() { - var p = FTraceImporterTestExports.lineParserWithIRQInfo; - var x = p(' systrace.sh-5441 [001] .N.. 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x.threadName, 'systrace.sh'); - assert.equal(x.pid, '5441'); - assert.equal(x.cpuNumber, '001'); - assert.equal(x.timestamp, '1031.091570'); - assert.equal(x.eventName, 'sched_wakeup'); - assert.equal(x.details, 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); // @suppress longLineCheck - - var x = p(' systrace.sh-5441 [001] .n.. 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x.threadName, 'systrace.sh'); - - var x = p(' systrace.sh-5441 [001] .p.. 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x.threadName, 'systrace.sh'); - }); - - test('lineParserWithTGID', function() { - var p = FTraceImporterTestExports.lineParserWithTGID; - var x = p(' systrace.sh-5441 (54321) [001] d... 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x.threadName, 'systrace.sh'); - assert.equal(x.pid, '5441'); - assert.equal(x.tgid, '54321'); - assert.equal(x.cpuNumber, '001'); - assert.equal(x.timestamp, '1031.091570'); - assert.equal(x.eventName, 'sched_wakeup'); - assert.equal(x.details, 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); // @suppress longLineCheck - - var x = p(' systrace.sh-5441 ( 321) [001] d... 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x.tgid, '321'); - - var x = p(' systrace.sh-5441 (-----) [001] d... 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.isUndefined(x.tgid); - }); - - test('lineParserWithTGIDNeedResched', function() { - var p = FTraceImporterTestExports.lineParserWithTGID; - var x = p(' systrace.sh-5441 (54321) [001] .N.. 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x.threadName, 'systrace.sh'); - assert.equal(x.pid, '5441'); - assert.equal(x.tgid, '54321'); - assert.equal(x.cpuNumber, '001'); - assert.equal(x.timestamp, '1031.091570'); - assert.equal(x.eventName, 'sched_wakeup'); - assert.equal(x.details, 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); // @suppress longLineCheck - - var x = p(' systrace.sh-5441 ( 321) [001] .n.. 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x.tgid, '321'); - - var x = p(' systrace.sh-5441 (-----) [001] .p.. 1031.091570: ' + - 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.isUndefined(x.tgid); - }); - - test('autodetectLineCornerCases', function() { - var detectParser = FTraceImporterTestExports.autoDetectLineParser; - var lineParserWithLegacyFmt = - FTraceImporterTestExports.lineParserWithLegacyFmt; - var lineParserWithIRQInfo = FTraceImporterTestExports.lineParserWithIRQInfo; - var lineParserWithTGID = FTraceImporterTestExports.lineParserWithTGID; - - var lineWithLegacyFmt = - 'systrace.sh-8170 [001] 15180.978813: sched_switch: ' + - 'prev_comm=systrace.sh prev_pid=8170 prev_prio=120 ' + - 'prev_state=x ==> next_comm=kworker/1:0 next_pid=7873 ' + - 'next_prio=120'; - var detected = detectParser(lineWithLegacyFmt); - assert.equal(lineParserWithLegacyFmt, detected); - - var lineWithIRQInfo = - 'systrace.sh-8170 [001] d... 15180.978813: sched_switch: ' + - 'prev_comm=systrace.sh prev_pid=8170 prev_prio=120 ' + - 'prev_state=x ==> next_comm=kworker/1:0 next_pid=7873 ' + - 'next_prio=120'; - var detected = detectParser(lineWithIRQInfo); - assert.equal(lineParserWithIRQInfo, detected); - - var lineWithTGID = - 'systrace.sh-8170 (54321) [001] d... 15180.978813: sched_switch: ' + - 'prev_comm=systrace.sh prev_pid=8170 prev_prio=120 ' + - 'prev_state=x ==> next_comm=kworker/1:0 next_pid=7873 ' + - 'next_prio=120'; - var detected = detectParser(lineWithTGID); - assert.equal(lineParserWithTGID, detected); - }); - - test('traceEventClockSyncRE', function() { - var re = FTraceImporterTestExports.traceEventClockSyncRE; - var x = re.exec('trace_event_clock_sync: parent_ts=19581477508'); - assert.isNotNull(x); - assert.equal(x[1], '19581477508'); - - var x = re.exec('trace_event_clock_sync: parent_ts=123.456'); - assert.isNotNull(x); - assert.equal(x[1], '123.456'); - }); - - test('genericClockSync', function() { - var lines = [ - '# tracer: nop', - '#', - '# TASK-PID CPU# TIMESTAMP FUNCTION', - '# | | | | |', - 'sh-26121 [000] ...1 15.050: tracing_mark_write: trace_event_clock_sync: name=battor regulator=8941_smbb_boost' // @suppress longLineCheck - ]; - - var io = new tr.importer.ImportOptions(); - var m = new tr.Model(); - var i = new tr.importer.Import(m, io); - - m.clockSyncManager.addClockSyncMarker(ClockDomainId.BATTOR, 'battor', 50); - - i.importTraces([lines.join('\n')]); - - assert.isFalse(m.hasImportWarnings); - // The clock sync happened at 15050 in the ftrace global domain and at 50 - // in the BattOr domain. This means the ftrace global timestamps need 15000 - // subtracted from them in order to be on the BattOr timeline. - assert.strictEqual( - m.clockSyncManager.getModelTimeTransformer(ClockDomainId.BATTOR)(3), - 3); - assert.strictEqual( - m.clockSyncManager.getModelTimeTransformer( - ClockDomainId.LINUX_FTRACE_GLOBAL)(15003), - 3); - }); - - test('canImport', function() { - var lines = [ - '# tracer: nop', - '#', - '# TASK-PID CPU# TIMESTAMP FUNCTION', - '# | | | | |', - ' <idle>-0 [001] 4467.843475: sched_switch: ' + - 'prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> ' + - 'next_comm=SurfaceFlinger next_pid=178 next_prio=112', - - ' SurfaceFlinger-178 [001] 4467.843536: sched_switch: ' + - 'prev_comm=SurfaceFlinger prev_pid=178 prev_prio=112 prev_state=S ' + - '==> next_comm=kworker/u:2 next_pid=2844 next_prio=120', - - ' kworker/u:2-2844 [001] 4467.843567: sched_switch: ' + - 'prev_comm=kworker/u:2 prev_pid=2844 prev_prio=120 prev_state=S ' + - '==> next_comm=swapper next_pid=0 next_prio=120', - - ' <idle>-0 [001] 4467.844208: sched_switch: ' + - 'prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> ' + - 'next_comm=kworker/u:2 next_pid=2844 next_prio=120' - ]; - assert.isTrue(FTraceImporter.canImport(lines.join('\n'))); - - var lines = [ - ' <idle>-0 [001] 4467.843475: sched_switch: ' + - 'prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> ' + - 'next_comm=SurfaceFlinger next_pid=178 next_prio=112' - ]; - assert.isTrue(FTraceImporter.canImport(lines.join('\n'))); - - var lines = [ - ' <idle>-0 [001] 4467.843475: sched_switch: ' + - 'prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> ' + - 'next_comm=SurfaceFlinger next_pid=178 next_prio=112', - - ' SurfaceFlinger-178 [001] 4467.843536: sched_switch: ' + - 'prev_comm=SurfaceFlinger prev_pid=178 prev_prio=112 ' + - 'prev_state=S ==> next_comm=kworker/u:2 next_pid=2844 ' + - 'next_prio=120' - ]; - assert.isTrue(FTraceImporter.canImport(lines.join('\n'))); - - var lines = [ - 'SomeRandomText', - 'More random text' - ]; - assert.isFalse(FTraceImporter.canImport(lines.join('\n'))); - }); - - test('canImport34AndLater', function() { - var lines = [ - '# tracer: nop', - '#', - '# entries-in-buffer/entries-written: 55191/55191 #P:2', - '#', - '# _-----=> irqs-off', - '# / _----=> need-resched', - '# | / _---=> hardirq/softirq', - '# || / _--=> preempt-depth', - '# ||| / delay', - '# TASK-PID CPU# |||| TIMESTAMP FUNCTION', - '# | | | |||| | |', - ' systrace.sh-5441 [001] d... 1031.091570: sched_wakeup: ' + - 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000', - ' systrace.sh-5441 [001] d... 1031.091584: sched_switch: ' + - 'prev_comm=systrace.sh prev_pid=5441 prev_prio=120 prev_state=x ' + - '==> next_comm=chrome next_pid=5418 next_prio=120' - ]; - assert.isTrue(FTraceImporter.canImport(lines.join('\n'))); - - var lines = [ - ' systrace.sh-5441 [001] d... 1031.091570: sched_wakeup: ' + - 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000', - ' systrace.sh-5441 [001] d... 1031.091584: sched_switch: ' + - 'prev_comm=systrace.sh prev_pid=5441 prev_prio=120 prev_state=x ' + - '==> next_comm=chrome next_pid=5418 next_prio=120' - ]; - assert.isTrue(FTraceImporter.canImport(lines.join('\n'))); - }); - - test('importOneSequence', function() { - var lines = [ - ' <idle>-0 [001] 4467.843475: sched_switch: ' + - 'prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> ' + - 'next_comm=SurfaceFlinger next_pid=178 next_prio=112', - - ' SurfaceFlinger-178 [001] 4467.843536: sched_switch: ' + - 'prev_comm=SurfaceFlinger prev_pid=178 prev_prio=112 ' + - 'prev_state=S ==> next_comm=kworker/u:2 next_pid=2844 ' + - 'next_prio=120', - - ' kworker/u:2-2844 [001] 4467.843567: sched_switch: ' + - 'prev_comm=kworker/u:2 prev_pid=2844 prev_prio=120 ' + - 'prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c = m.kernel.cpus[1]; - assert.equal(c.slices.length, 2); - - assert.equal(c.slices[0].title, 'SurfaceFlinger'); - assert.equal(c.slices[0].start, 4467843.475); - assert.closeTo(.536 - .475, c.slices[0].duration, 1e-5); - }); - - test('importOneSequenceWithSpacyThreadName', function() { - var lines = [ - ' <idle>-0 [001] 4467.843475: sched_switch: ' + - 'prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> ' + - 'next_comm=Surface Flinger next_pid=178 next_prio=112', - - 'Surface Flinger -178 [001] 4467.843536: sched_switch: ' + - 'prev_comm=Surface Flinger prev_pid=178 prev_prio=112 ' + - 'prev_state=S ==> next_comm=kworker/u:2 next_pid=2844 ' + - 'next_prio=120', - - ' kworker/u:2-2844 [001] 4467.843567: sched_switch: ' + - 'prev_comm=kworker/u:2 prev_pid=2844 prev_prio=120 ' + - 'prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c = m.kernel.cpus[1]; - assert.equal(c.slices.length, 2); - - assert.equal(c.slices[0].title, 'Surface Flinger '); - assert.equal(c.slices[0].start, 4467843.475); - assert.closeTo(.536 - .475, c.slices[0].duration, 1e-5); - }); - - test('importWithNewline', function() { - var lines = [ - '' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - }); - - test('importSystraceHtml', function() { - var p = tr.b.getAsync( - '/test_data/trivial_systrace.html'); - return p.then(function(data) { - var m = newModel(data); - assert.isFalse(m.hasImportWarnings); - - assert.isDefined(m.processes[124]); - assert.isDefined(m.processes[360]); - - assert.isDefined(m.processes[124].counters['android.StatusBar']); - assert.equal(m.processes[124].counters['android.StatusBar'].numSamples, - 1); - assert.isDefined(m.processes[124].counters['android.VSYNC']); - assert.equal(2, m.processes[124].counters['android.VSYNC'].numSamples); - assert.isDefined(m.processes[360].counters['android.iq']); - assert.equal(1, m.processes[360].counters['android.iq'].numSamples); - }, function(err) { - throw err; - }); - }); - - test('importMultiTraceHtml', function() { - var lines = [ - '<!DoCTYPE hTml>', // check must be case insensitive - '<body>', - ' <div class="view">', - ' <\/div>', - ' <script class="trace-data" type="application/text">', - 'test1', - 'test2', - ' <\/script>', - ' <script class="trace-data" type="application/text">', - '# tracer: nop', - '#', - '# TASK-PID CPU# TIMESTAMP FUNCTION', - '# | | | | |', - ' hwc_eventmon-336 [000] 50260.929925: 0: C|124|VSYNC|1', - ' Binder_1-340 [000] 50260.935656: 0: C|124|StatusBar|1', - ' hwc_eventmon-336 [000] 50260.946573: 0: C|124|VSYNC|0', - ' InputReader-419 [000] 50262.538578: 0: C|360|iq|1', - ' <\/script>', - '<\/body>', - '<\/html>' - ]; - - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - assert.isDefined(m.processes[124]); - assert.isDefined(m.processes[360]); - - assert.isDefined(m.processes[124].counters['android.StatusBar']); - assert.equal(m.processes[124].counters['android.StatusBar'].numSamples, - 1); - assert.isDefined(m.processes[124].counters['android.VSYNC']); - assert.equal(2, m.processes[124].counters['android.VSYNC'].numSamples); - assert.isDefined(m.processes[360].counters['android.iq']); - assert.equal(1, m.processes[360].counters['android.iq'].numSamples); - }); - - test('clockSync', function() { - var lines = [ - ' <idle>-0 [001] 4467.843475: sched_switch: ' + - 'prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ' + - '==> next_comm=SurfaceFlinger next_pid=178 next_prio=112', - ' SurfaceFlinger-178 [001] 4467.843536: sched_switch: ' + - 'prev_comm=SurfaceFlinger prev_pid=178 prev_prio=112 ' + - 'prev_state=S ==> next_comm=kworker/u:2 next_pid=2844 ' + - 'next_prio=120', - ' kworker/u:2-2844 [001] 4467.843567: sched_switch: ' + - 'prev_comm=kworker/u:2 prev_pid=2844 prev_prio=120 ' + - 'prev_state=S ==> next_comm=swapper next_pid=0 ' + - 'next_prio=120', - ' kworker/u:2-2844 [001] 4467.843000: 0: ' + - 'trace_event_clock_sync: parent_ts=0.1' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c = m.kernel.cpus[1]; - assert.equal(c.slices.length, 2); - - assert.closeTo( - (467.843475 - (467.843 - 0.1)) * 1000, - c.slices[0].start, - 1e-5); - }); - - test('clockSyncMarkWrite', function() { - var lines = [ - 'systrace.sh-8170 [001] 15180.978813: sched_switch: ' + - 'prev_comm=systrace.sh prev_pid=8170 prev_prio=120 ' + - 'prev_state=x ==> next_comm=kworker/1:0 next_pid=7873 ' + - 'next_prio=120', - ' kworker/1:0-7873 [001] 15180.978836: sched_switch: ' + - 'prev_comm=kworker/1:0 prev_pid=7873 prev_prio=120 ' + - 'prev_state=S ==> next_comm=debugd next_pid=4404 next_prio=120', - ' debugd-4404 [001] 15180.979010: sched_switch: prev_comm=debugd ' + - 'prev_pid=4404 prev_prio=120 prev_state=S ==> ' + - 'next_comm=dbus-daemon next_pid=510 next_prio=120', - 'systrace.sh-8182 [000] 15186.203900: tracing_mark_write: ' + - 'trace_event_clock_sync: parent_ts=0' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c = m.kernel.cpus[1]; - assert.equal(c.slices.length, 2); - - assert.closeTo((15180.978813 - 0) * 1000, c.slices[0].start, 1e-5); - - assert.strictEqual( - m.clockSyncManager.getModelTimeTransformer( - tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL)(100), - 100); - assert.strictEqual( - m.clockSyncManager.getModelTimeTransformer( - tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC)(100), - 100); - }); - - test('clockSyncMarkWriteSecondIgnored', function() { - var lines = [ - 'systrace.sh-8182 [000] 15186.203900: tracing_mark_write: ' + - 'trace_event_clock_sync: parent_ts=0', - 'systrace.sh-8182 [000] 15187.203900: tracing_mark_write: ' + - 'trace_event_clock_sync: parent_ts=0' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - assert.strictEqual( - m.clockSyncManager.getModelTimeTransformer( - tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL)(100), - 100); - assert.strictEqual( - m.clockSyncManager.getModelTimeTransformer( - tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC)(100), - 100); - }); - - test('tracingMarkWriteEOLCleanup', function() { - var lines = [ - 'systrace.sh-8182 [001] ...1 2068001.677892: tracing_mark_write: ' + - 'B|9304|test\\n\\', - 'systrace.sh-8182 [002] ...1 2068991.686415: tracing_mark_write: E\\n\\' - ]; - - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c = m.processes[9304].threads[8182].sliceGroup; - assert.equal(c.slices.length, 1); - - assert.closeTo((2068001.677892 - 0) * 1000, c.slices[0].start, 1e-5); - assert.closeTo( - (2068991.686415 - 2068001.677892) * 1000, - c.slices[0].duration, - 1e-5); - }); - - test('cpuCount', function() { - var lines = [ - 'systrace.sh-8170 [001] 15180.978813: sched_switch: ' + - 'prev_comm=systrace.sh prev_pid=8170 prev_prio=120 ' + - 'prev_state=x ==> next_comm=kworker/1:0 next_pid=7873 ' + - 'next_prio=120', - ' kworker/1:0-7873 [001] 15180.978836: sched_switch: ' + - 'prev_comm=kworker/1:0 prev_pid=7873 prev_prio=120 ' + - 'prev_state=S ==> next_comm=debugd next_pid=4404 next_prio=120', - ' debugd-4404 [000] 15180.979010: sched_switch: prev_comm=debugd ' + - 'prev_pid=4404 prev_prio=120 prev_state=S ==> ' + - 'next_comm=dbus-daemon next_pid=510 next_prio=120' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - assert.equal(tr.b.dictionaryLength(m.kernel.cpus), 2); - assert.equal(m.kernel.bestGuessAtCpuCount, 2); - }); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/gesture_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/gesture_parser.html deleted file mode 100644 index f2c3924867b..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/gesture_parser.html +++ /dev/null @@ -1,144 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses gesture events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses trace events generated by gesture library for touchpad. - * @constructor - */ - function GestureParser(importer) { - Parser.call(this, importer); - importer.registerEventHandler('tracing_mark_write:log', - GestureParser.prototype.logEvent.bind(this)); - importer.registerEventHandler('tracing_mark_write:SyncInterpret', - GestureParser.prototype.syncEvent.bind(this)); - importer.registerEventHandler('tracing_mark_write:HandleTimer', - GestureParser.prototype.timerEvent.bind(this)); - } - - GestureParser.prototype = { - __proto__: Parser.prototype, - - /** - * Parse events generate by gesture library. - * gestureOpenSlice and gestureCloseSlice are two common - * functions to store the begin time and end time for all - * events in gesture library - */ - gestureOpenSlice: function(title, ts, opt_args) { - var thread = this.importer.getOrCreatePseudoThread('gesture').thread; - thread.sliceGroup.beginSlice( - 'touchpad_gesture', title, ts, opt_args); - }, - - gestureCloseSlice: function(title, ts) { - var thread = this.importer.getOrCreatePseudoThread('gesture').thread; - if (thread.sliceGroup.openSliceCount) { - var slice = thread.sliceGroup.mostRecentlyOpenedPartialSlice; - if (slice.title != title) { - this.importer.model.importWarning({ - type: 'title_match_error', - message: 'Titles do not match. Title is ' + - slice.title + ' in openSlice, and is ' + - title + ' in endSlice' - }); - } else { - thread.sliceGroup.endSlice(ts); - } - } - }, - - /** - * For log events, events will come in pairs with a tag log: - * like this: - * tracing_mark_write: log: start: TimerLogOutputs - * tracing_mark_write: log: end: TimerLogOutputs - * which represent the start and the end time of certain log behavior - * Take these logs above for example, they are the start and end time - * of logging Output for HandleTimer function - */ - logEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var innerEvent = - /^\s*(\w+):\s*(\w+)$/.exec(eventBase.details); - switch (innerEvent[1]) { - case 'start': - this.gestureOpenSlice('GestureLog', ts, {name: innerEvent[2]}); - break; - case 'end': - this.gestureCloseSlice('GestureLog', ts); - } - return true; - }, - - /** - * For SyncInterpret events, events will come in pairs with - * a tag SyncInterpret: - * like this: - * tracing_mark_write: SyncInterpret: start: ClickWiggleFilterInterpreter - * tracing_mark_write: SyncInterpret: end: ClickWiggleFilterInterpreter - * which represent the start and the end time of SyncInterpret function - * inside the certain interpreter in the gesture library. - * Take the logs above for example, they are the start and end time - * of the SyncInterpret function inside ClickWiggleFilterInterpreter - */ - syncEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var innerEvent = /^\s*(\w+):\s*(\w+)$/.exec(eventBase.details); - switch (innerEvent[1]) { - case 'start': - this.gestureOpenSlice('SyncInterpret', ts, - {interpreter: innerEvent[2]}); - break; - case 'end': - this.gestureCloseSlice('SyncInterpret', ts); - } - return true; - }, - - /** - * For HandleTimer events, events will come in pairs with - * a tag HandleTimer: - * like this: - * tracing_mark_write: HandleTimer: start: LookaheadFilterInterpreter - * tracing_mark_write: HandleTimer: end: LookaheadFilterInterpreter - * which represent the start and the end time of HandleTimer function - * inside the certain interpreter in the gesture library. - * Take the logs above for example, they are the start and end time - * of the HandleTimer function inside LookaheadFilterInterpreter - */ - timerEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var innerEvent = /^\s*(\w+):\s*(\w+)$/.exec(eventBase.details); - switch (innerEvent[1]) { - case 'start': - this.gestureOpenSlice('HandleTimer', ts, - {interpreter: innerEvent[2]}); - break; - case 'end': - this.gestureCloseSlice('HandleTimer', ts); - } - return true; - } - }; - - Parser.register(GestureParser); - - return { - GestureParser: GestureParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/gesture_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/gesture_parser_test.html deleted file mode 100644 index 002844dcd2e..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/gesture_parser_test.html +++ /dev/null @@ -1,213 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('gestureImport', function() { - var lines = [ - '<...>-1837 [000] ...1 875292.741648: tracing_mark_write: ' + - 'log: start: TimerLogOutputs', // 0 - '<...>-1837 [000] ...1 875292.741651: tracing_mark_write: ' + - 'log: end: TimerLogOutputs', - '<...>-1837 [000] ...1 875292.742796: tracing_mark_write: ' + - 'log: start: LogTimerCallback', - '<...>-1837 [000] ...1 875292.742802: tracing_mark_write: ' + - 'log: end: LogTimerCallback', - '<...>-1837 [000] ...1 875292.742805: tracing_mark_write: ' + - 'HandleTimer: start: LoggingFilterInterpreter', // 2 - '<...>-1837 [000] ...1 875292.742809: tracing_mark_write: ' + - 'HandleTimer: start: AppleTrackpadFilterInterpreter', - '<...>-1837 [000] ...1 875292.742814: tracing_mark_write: ' + - 'HandleTimer: start: Cr48ProfileSensorFilterInterpreter', - '<...>-1837 [000] ...1 875292.742818: tracing_mark_write: ' + - 'HandleTimer: start: T5R2CorrectingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742822: tracing_mark_write: ' + - 'HandleTimer: start: StuckButtonInhibitorFilterInterpreter', - '<...>-1837 [000] ...1 875292.742825: tracing_mark_write: ' + - 'HandleTimer: start: IntegralGestureFilterInterpreter', - '<...>-1837 [000] ...1 875292.742829: tracing_mark_write: ' + - 'HandleTimer: start: ScalingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742833: tracing_mark_write: ' + - 'HandleTimer: start: SplitCorrectingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742836: tracing_mark_write: ' + - 'HandleTimer: start: AccelFilterInterpreter', - '<...>-1837 [000] ...1 875292.742840: tracing_mark_write: ' + - 'HandleTimer: start: SensorJumpFilterInterpreter', - '<...>-1837 [000] ...1 875292.742843: tracing_mark_write: ' + - 'HandleTimer: start: BoxFilterInterpreter', - '<...>-1837 [000] ...1 875292.742846: tracing_mark_write: ' + - 'HandleTimer: start: LookaheadFilterInterpreter', - '<...>-1837 [000] ...1 875292.742853: tracing_mark_write: ' + - 'SyncInterpret: start: IirFilterInterpreter', // 14 - '<...>-1837 [000] ...1 875292.742861: tracing_mark_write: ' + - 'SyncInterpret: start: PalmClassifyingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742872: tracing_mark_write: ' + - 'SyncInterpret: start: ClickWiggleFilterInterpreter', - '<...>-1837 [000] ...1 875292.742881: tracing_mark_write: ' + - 'SyncInterpret: start: FlingStopFilterInterpreter', - '<...>-1837 [000] ...1 875292.742887: tracing_mark_write: ' + - 'SyncInterpret: start: ImmediateInterpreter', - '<...>-1837 [000] ...1 875292.742906: tracing_mark_write: ' + - 'SyncInterpret: end: ImmediateInterpreter', - '<...>-1837 [000] ...1 875292.742910: tracing_mark_write: ' + - 'SyncInterpret: end: FlingStopFilterInterpreter', - '<...>-1837 [000] ...1 875292.742914: tracing_mark_write: ' + - 'SyncInterpret: end: ClickWiggleFilterInterpreter', - '<...>-1837 [000] ...1 875292.742917: tracing_mark_write: ' + - 'SyncInterpret: end: PalmClassifyingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742921: tracing_mark_write: ' + - 'SyncInterpret: end: IirFilterInterpreter', - '<...>-1837 [000] ...1 875292.742926: tracing_mark_write: ' + - 'HandleTimer: end: LookaheadFilterInterpreter', - '<...>-1837 [000] ...1 875292.742929: tracing_mark_write: ' + - 'HandleTimer: end: BoxFilterInterpreter', - '<...>-1837 [000] ...1 875292.742932: tracing_mark_write: ' + - 'HandleTimer: end: SensorJumpFilterInterpreter', - '<...>-1837 [000] ...1 875292.742937: tracing_mark_write: ' + - 'HandleTimer: end: AccelFilterInterpreter', - '<...>-1837 [000] ...1 875292.742940: tracing_mark_write: ' + - 'HandleTimer: end: SplitCorrectingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742944: tracing_mark_write: ' + - 'HandleTimer: end: ScalingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742949: tracing_mark_write: ' + - 'HandleTimer: end: IntegralGestureFilterInterpreter', - '<...>-1837 [000] ...1 875292.742952: tracing_mark_write: ' + - 'HandleTimer: end: StuckButtonInhibitorFilterInterpreter', - '<...>-1837 [000] ...1 875292.742956: tracing_mark_write: ' + - 'HandleTimer: end: T5R2CorrectingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742959: tracing_mark_write: ' + - 'HandleTimer: end: Cr48ProfileSensorFilterInterpreter', - '<...>-1837 [000] ...1 875292.742962: tracing_mark_write: ' + - 'HandleTimer: end: AppleTrackpadFilterInterpreter', - '<...>-1837 [000] ...1 875292.742966: tracing_mark_write: ' + - 'HandleTimer: end: LoggingFilterInterpreter', - '<...>-1837 [000] ...1 875292.742969: tracing_mark_write: ' + - 'log: start: TimerLogOutputs', - '<...>-1837 [000] ...1 875292.742973: tracing_mark_write: ' + - 'log: end: TimerLogOutputs', - '<...>-1837 [000] ...1 875292.795219: tracing_mark_write: ' + - 'log: start: LogHardwareState', - '<...>-1837 [000] ...1 875292.795231: tracing_mark_write: ' + - 'log: end: LogHardwareState' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var gestureThread = threads[0]; - assert.equal(gestureThread.name, 'gesture'); - assert.equal(gestureThread.sliceGroup.length, 21); - assert.equal('touchpad_gesture', - gestureThread.sliceGroup.slices[0].category); - assert.equal('GestureLog', - gestureThread.sliceGroup.slices[0].title); - assert.equal('touchpad_gesture', - gestureThread.sliceGroup.slices[2].category); - assert.equal('HandleTimer', - gestureThread.sliceGroup.slices[2].title); - assert.equal('touchpad_gesture', - gestureThread.sliceGroup.slices[14].category); - assert.equal('SyncInterpret', - gestureThread.sliceGroup.slices[14].title); - }); - - test('unusualStart', function() { - var lines = [ - 'X-30368 [000] ...1 1819362.481867: tracing_mark_write: ' + - 'SyncInterpret: start: IirFilterInterpreter', - 'X-30368 [000] ...1 1819362.481881: tracing_mark_write: ' + - 'SyncInterpret: start: PalmClassifyingFilterInterpreter', - 'X-30368 [000] ...1 1819362.481894: tracing_mark_write: ' + - 'SyncInterpret: start: ClickWiggleFilterInterpreter', - 'X-30368 [000] ...1 1819362.481905: tracing_mark_write: ' + - 'SyncInterpret: start: FlingStopFilterInterpreter', - 'X-30368 [000] ...1 1819362.481912: tracing_mark_write: ' + - 'SyncInterpret: start: ImmediateInterpreter', - 'X-30368 [000] ...1 1819362.481933: tracing_mark_write: ' + - 'SyncInterpret: end: ImmediateInterpreter', - 'X-30368 [000] ...1 1819362.481938: tracing_mark_write: ' + - 'SyncInterpret: end: FlingStopFilterInterpreter', - 'X-30368 [000] ...1 1819362.481943: tracing_mark_write: ' + - 'SyncInterpret: end: ClickWiggleFilterInterpreter', - 'X-30368 [000] ...1 1819362.481947: tracing_mark_write: ' + - 'SyncInterpret: end: PalmClassifyingFilterInterpreter', - 'X-30368 [000] ...1 1819362.481952: tracing_mark_write: ' + - 'SyncInterpret: end: IirFilterInterpreter', - 'X-30368 [000] ...1 1819362.481958: tracing_mark_write: ' + - 'HandleTimer: end: LookaheadFilterInterpreter', - 'X-30368 [000] ...1 1819362.481962: tracing_mark_write: ' + - 'HandleTimer: end: BoxFilterInterpreter', - 'X-30368 [000] ...1 1819362.481967: tracing_mark_write: ' + - 'HandleTimer: end: SensorJumpFilterInterpreter', - 'X-30368 [000] ...1 1819362.481973: tracing_mark_write: ' + - 'HandleTimer: end: AccelFilterInterpreter', - 'X-30368 [000] ...1 1819362.481977: tracing_mark_write: ' + - 'HandleTimer: end: SplitCorrectingFilterInterpreter', - 'X-30368 [000] ...1 1819362.481982: tracing_mark_write: ' + - 'HandleTimer: end: ScalingFilterInterpreter', - 'X-30368 [000] ...1 1819362.481988: tracing_mark_write: ' + - 'HandleTimer: end: IntegralGestureFilterInterpreter', - 'X-30368 [000] ...1 1819362.481993: tracing_mark_write: ' + - 'HandleTimer: end: StuckButtonInhibitorFilterInterpreter', - 'X-30368 [000] ...1 1819362.481998: tracing_mark_write: ' + - 'HandleTimer: end: T5R2CorrectingFilterInterpreter', - 'X-30368 [000] ...1 1819362.482033: tracing_mark_write: ' + - 'HandleTimer: end: Cr48ProfileSensorFilterInterpreter', - 'X-30368 [000] ...1 1819362.482038: tracing_mark_write: ' + - 'HandleTimer: end: AppleTrackpadFilterInterpreter', - 'X-30368 [000] ...1 1819362.482043: tracing_mark_write: ' + - 'HandleTimer: end: LoggingFilterInterpreter', - 'X-30368 [000] ...1 1819362.482047: tracing_mark_write: ' + - 'log: start: TimerLogOutputs', - 'X-30368 [000] ...1 1819362.482053: tracing_mark_write: ' + - 'log: end: TimerLogOutputs' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - }); - - test('importError', function() { - var lines = [ - 'X-30368 [000] ...1 1819362.481912: tracing_mark_write: ' + - 'SyncInterpret: start: ImmediateInterpreter', - 'X-30368 [000] ...1 1819362.481958: tracing_mark_write: ' + - 'HandleTimer: end: LookaheadFilterInterpreter', - 'X-30368 [000] ...1 1819362.481962: tracing_mark_write: ' + - 'HandleTimer: end: BoxFilterInterpreter', - 'X-30368 [000] ...1 1819362.481967: tracing_mark_write: ' + - 'HandleTimer: end: SensorJumpFilterInterpreter', - 'X-30368 [000] ...1 1819362.481973: tracing_mark_write: ' + - 'HandleTimer: end: AccelFilterInterpreter', - 'X-30368 [000] ...1 1819362.481977: tracing_mark_write: ' + - 'HandleTimer: end: SplitCorrectingFilterInterpreter', - 'X-30368 [000] ...1 1819362.481982: tracing_mark_write: ' + - 'HandleTimer: end: ScalingFilterInterpreter', - 'X-30368 [000] ...1 1819362.481988: tracing_mark_write: ' + - 'HandleTimer: end: IntegralGestureFilterInterpreter' - ]; - var m = newModel(lines.join('\n')); - - assert.isTrue(m.hasImportWarnings); - assert.equal(m.importWarnings.length, 7); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/i915_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/i915_parser.html deleted file mode 100644 index 91c733a0e11..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/i915_parser.html +++ /dev/null @@ -1,371 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses i915 driver events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux i915 trace events. - * @constructor - */ - function I915Parser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('i915_gem_object_create', - I915Parser.prototype.gemObjectCreateEvent.bind(this)); - importer.registerEventHandler('i915_gem_object_bind', - I915Parser.prototype.gemObjectBindEvent.bind(this)); - importer.registerEventHandler('i915_gem_object_unbind', - I915Parser.prototype.gemObjectBindEvent.bind(this)); - importer.registerEventHandler('i915_gem_object_change_domain', - I915Parser.prototype.gemObjectChangeDomainEvent.bind(this)); - importer.registerEventHandler('i915_gem_object_pread', - I915Parser.prototype.gemObjectPreadWriteEvent.bind(this)); - importer.registerEventHandler('i915_gem_object_pwrite', - I915Parser.prototype.gemObjectPreadWriteEvent.bind(this)); - importer.registerEventHandler('i915_gem_object_fault', - I915Parser.prototype.gemObjectFaultEvent.bind(this)); - importer.registerEventHandler('i915_gem_object_clflush', - // NB: reuse destroy handler - I915Parser.prototype.gemObjectDestroyEvent.bind(this)); - importer.registerEventHandler('i915_gem_object_destroy', - I915Parser.prototype.gemObjectDestroyEvent.bind(this)); - importer.registerEventHandler('i915_gem_ring_dispatch', - I915Parser.prototype.gemRingDispatchEvent.bind(this)); - importer.registerEventHandler('i915_gem_ring_flush', - I915Parser.prototype.gemRingFlushEvent.bind(this)); - importer.registerEventHandler('i915_gem_request', - I915Parser.prototype.gemRequestEvent.bind(this)); - importer.registerEventHandler('i915_gem_request_add', - I915Parser.prototype.gemRequestEvent.bind(this)); - importer.registerEventHandler('i915_gem_request_complete', - I915Parser.prototype.gemRequestEvent.bind(this)); - importer.registerEventHandler('i915_gem_request_retire', - I915Parser.prototype.gemRequestEvent.bind(this)); - importer.registerEventHandler('i915_gem_request_wait_begin', - I915Parser.prototype.gemRequestEvent.bind(this)); - importer.registerEventHandler('i915_gem_request_wait_end', - I915Parser.prototype.gemRequestEvent.bind(this)); - importer.registerEventHandler('i915_gem_ring_wait_begin', - I915Parser.prototype.gemRingWaitEvent.bind(this)); - importer.registerEventHandler('i915_gem_ring_wait_end', - I915Parser.prototype.gemRingWaitEvent.bind(this)); - importer.registerEventHandler('i915_reg_rw', - I915Parser.prototype.regRWEvent.bind(this)); - importer.registerEventHandler('i915_flip_request', - I915Parser.prototype.flipEvent.bind(this)); - importer.registerEventHandler('i915_flip_complete', - I915Parser.prototype.flipEvent.bind(this)); - importer.registerEventHandler('intel_gpu_freq_change', - I915Parser.prototype.gpuFrequency.bind(this)); - } - - I915Parser.prototype = { - __proto__: Parser.prototype, - - i915FlipOpenSlice: function(ts, obj, plane) { - // use i915_flip_obj_plane? - var kthread = this.importer.getOrCreatePseudoThread('i915_flip'); - kthread.openSliceTS = ts; - kthread.openSlice = 'flip:' + obj + '/' + plane; - }, - - i915FlipCloseSlice: function(ts, args) { - var kthread = this.importer.getOrCreatePseudoThread('i915_flip'); - if (kthread.openSlice) { - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - kthread.openSliceTS, - args, - ts - kthread.openSliceTS); - - kthread.thread.sliceGroup.pushSlice(slice); - } - kthread.openSlice = undefined; - }, - - i915GemObjectSlice: function(ts, eventName, obj, args) { - var kthread = this.importer.getOrCreatePseudoThread('i915_gem'); - kthread.openSlice = eventName + ':' + obj; - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - ts, args, 0); - - kthread.thread.sliceGroup.pushSlice(slice); - }, - - i915GemRingSlice: function(ts, eventName, dev, ring, args) { - var kthread = this.importer.getOrCreatePseudoThread('i915_gem_ring'); - kthread.openSlice = eventName + ':' + dev + '.' + ring; - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - ts, args, 0); - - kthread.thread.sliceGroup.pushSlice(slice); - }, - - i915RegSlice: function(ts, eventName, reg, args) { - var kthread = this.importer.getOrCreatePseudoThread('i915_reg'); - kthread.openSlice = eventName + ':' + reg; - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - ts, args, 0); - - kthread.thread.sliceGroup.pushSlice(slice); - }, - - i915FreqChangeSlice: function(ts, eventName, args) { - var kthread = this.importer.getOrCreatePseudoThread('i915_gpu_freq'); - kthread.openSlice = eventName; - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - ts, args, 0); - - kthread.thread.sliceGroup.pushSlice(slice); - }, - - /** - * Parses i915 driver events and sets up state in the importer. - */ - gemObjectCreateEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /obj=(\w+), size=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var obj = event[1]; - var size = parseInt(event[2]); - this.i915GemObjectSlice(ts, eventName, obj, - { - obj: obj, - size: size - }); - return true; - }, - - gemObjectBindEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - // TODO(sleffler) mappable - var event = /obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var obj = event[1]; - var offset = event[2]; - var size = parseInt(event[3]); - this.i915ObjectGemSlice(ts, eventName + ':' + obj, - { - obj: obj, - offset: offset, - size: size - }); - return true; - }, - - gemObjectChangeDomainEvent: function(eventName, cpuNumber, pid, ts, - eventBase) { - var event = /obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/ - .exec(eventBase.details); - if (!event) - return false; - - var obj = event[1]; - var read = event[2]; - var write = event[3]; - this.i915GemObjectSlice(ts, eventName, obj, - { - obj: obj, - read: read, - write: write - }); - return true; - }, - - gemObjectPreadWriteEvent: function(eventName, cpuNumber, pid, ts, - eventBase) { - var event = /obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var obj = event[1]; - var offset = parseInt(event[2]); - var len = parseInt(event[3]); - this.i915GemObjectSlice(ts, eventName, obj, - { - obj: obj, - offset: offset, - len: len - }); - return true; - }, - - gemObjectFaultEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - // TODO(sleffler) writable - var event = /obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var obj = event[1]; - var type = event[2]; - var index = parseInt(event[3]); - this.i915GemObjectSlice(ts, eventName, obj, - { - obj: obj, - type: type, - index: index - }); - return true; - }, - - gemObjectDestroyEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /obj=(\w+)/.exec(eventBase.details); - if (!event) - return false; - - var obj = event[1]; - this.i915GemObjectSlice(ts, eventName, obj, - { - obj: obj - }); - return true; - }, - - gemRingDispatchEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var dev = parseInt(event[1]); - var ring = parseInt(event[2]); - var seqno = parseInt(event[3]); - this.i915GemRingSlice(ts, eventName, dev, ring, - { - dev: dev, - ring: ring, - seqno: seqno - }); - return true; - }, - - gemRingFlushEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/ - .exec(eventBase.details); - if (!event) - return false; - - var dev = parseInt(event[1]); - var ring = parseInt(event[2]); - var invalidate = event[3]; - var flush = event[4]; - this.i915GemRingSlice(ts, eventName, dev, ring, - { - dev: dev, - ring: ring, - invalidate: invalidate, - flush: flush - }); - return true; - }, - - gemRequestEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var dev = parseInt(event[1]); - var ring = parseInt(event[2]); - var seqno = parseInt(event[3]); - this.i915GemRingSlice(ts, eventName, dev, ring, - { - dev: dev, - ring: ring, - seqno: seqno - }); - return true; - }, - - gemRingWaitEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /dev=(\d+), ring=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var dev = parseInt(event[1]); - var ring = parseInt(event[2]); - this.i915GemRingSlice(ts, eventName, dev, ring, - { - dev: dev, - ring: ring - }); - return true; - }, - - regRWEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/ - .exec(eventBase.details); - if (!event) - return false; - - var rw = event[1]; - var reg = event[2]; - var len = event[3]; - var data = event[3]; - this.i915RegSlice(ts, rw, reg, - { - rw: rw, - reg: reg, - len: len, - data: data - }); - return true; - }, - - flipEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /plane=(\d+), obj=(\w+)/.exec(eventBase.details); - if (!event) - return false; - - var plane = parseInt(event[1]); - var obj = event[2]; - if (eventName == 'i915_flip_request') - this.i915FlipOpenSlice(ts, obj, plane); - else - this.i915FlipCloseSlice(ts, - { - obj: obj, - plane: plane - }); - return true; - }, - - gpuFrequency: function(eventName, cpuNumver, pid, ts, eventBase) { - var event = /new_freq=(\d+)/.exec(eventBase.details); - if (!event) - return false; - var freq = parseInt(event[1]); - - this.i915FreqChangeSlice(ts, eventName, { - freq: freq - }); - return true; - } - }; - - Parser.register(I915Parser); - - return { - I915Parser: I915Parser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/i915_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/i915_parser_test.html deleted file mode 100644 index cc62910919f..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/i915_parser_test.html +++ /dev/null @@ -1,105 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('i915Import', function() { - var lines = [ - // NB: spliced from different traces; mismatched timestamps don't matter - ' chrome-1223 [000] 2784.773556: i915_gem_object_pwrite: ' + - 'obj=ffff88013f13fc00, offset=0, len=2984', - ' chrome-1539 [000] 18420.677750: ' + - 'i915_gem_object_change_domain: ' + - 'obj=ffff8800a88d1400, read=44=>40, write=00=>40', - ' chrome-1539 [000] 18420.677759: i915_gem_object_fault: ' + - 'obj=ffff8800a88d1400, GTT index=0 , writable', - ' X-964 [000] 2784.774864: i915_flip_request: ' + - 'plane=0, obj=ffff88013f0b9a00', - ' <idle>-0 [000] 2784.788644: i915_flip_complete: ' + - 'plane=0, obj=ffff88013f0b9a00', - ' chrome-1539 [001] 18420.681687: i915_gem_request_retire: ' + - 'dev=0, ring=1, seqno=1178152', - ' chrome-1539 [000] 18422.955688: i915_gem_request_add: ' + - 'dev=0, ring=1, seqno=1178364', - ' cat-21833 [000] 18422.956832: i915_gem_request_complete: ' + - 'dev=0, ring=1, seqno=1178364', - ' X-1012 [001] 18420.682511: i915_gem_request_wait_begin: ' + - 'dev=0, ring=4, seqno=1178156', - ' X-1012 [000] 18422.765707: i915_gem_request_wait_end: ' + - 'dev=0, ring=4, seqno=1178359', - ' chrome-1539 [000] 18422.955655: i915_gem_ring_flush: ' + - 'dev=0, ring=1, invalidate=001e, flush=0040', - ' chrome-1539 [000] 18422.955660: i915_gem_ring_dispatch: ' + - 'dev=0, ring=1, seqno=1178364', - ' chrome-1539 [000] 18420.677772: i915_reg_rw: ' + - 'write reg=0x100030, len=8, val=(0xfca9001, 0xfce8007)', - ' kworker/u16:2-13998 [005] 1577664.436065: ' + - 'intel_gpu_freq_change: new_freq=350' - - ]; - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var i915GemThread = undefined; - var i915FlipThread = undefined; - var i915GemRingThread = undefined; - var i915RegThread = undefined; - var i915GpuFreqThread = undefined; - m.getAllThreads().forEach(function(t) { - switch (t.name) { - case 'i915_gem': - i915GemThread = t; - break; - case 'i915_flip': - i915FlipThread = t; - break; - case 'i915_gem_ring': - i915GemRingThread = t; - break; - case 'i915_reg': - i915RegThread = t; - break; - case 'i915_gpu_freq': - i915GpuFreqThread = t; - break; - default: - throw new unittest.TestError('Unexpected thread named ' + t.name); - } - }); - assert.isDefined(i915GemThread); - assert.isDefined(i915FlipThread); - assert.isDefined(i915GemRingThread); - assert.isDefined(i915RegThread); - assert.isDefined(i915GpuFreqThread); - - assert.equal(i915GemThread.sliceGroup.length, 3); - - assert.equal(i915FlipThread.sliceGroup.length, 1); - - assert.closeTo( - 2784.774864 * 1000.0, - i915FlipThread.sliceGroup.slices[0].start, - 1e-5); - assert.closeTo( - (2784.788644 - 2784.774864) * 1000.0, - i915FlipThread.sliceGroup.slices[0].duration, - 1e-5); - - assert.equal(i915GemRingThread.sliceGroup.length, 7); - assert.equal(i915RegThread.sliceGroup.length, 1); - assert.equal(i915GpuFreqThread.sliceGroup.length, 1); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/irq_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/irq_parser.html deleted file mode 100644 index 24903ae3133..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/irq_parser.html +++ /dev/null @@ -1,184 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses drm driver events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux irq trace events. - * @constructor - */ - function IrqParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('irq_handler_entry', - IrqParser.prototype.irqHandlerEntryEvent.bind(this)); - importer.registerEventHandler('irq_handler_exit', - IrqParser.prototype.irqHandlerExitEvent.bind(this)); - importer.registerEventHandler('softirq_raise', - IrqParser.prototype.softirqRaiseEvent.bind(this)); - importer.registerEventHandler('softirq_entry', - IrqParser.prototype.softirqEntryEvent.bind(this)); - importer.registerEventHandler('softirq_exit', - IrqParser.prototype.softirqExitEvent.bind(this)); - importer.registerEventHandler('ipi_entry', - IrqParser.prototype.ipiEntryEvent.bind(this)); - importer.registerEventHandler('ipi_exit', - IrqParser.prototype.ipiExitEvent.bind(this)); - } - - // Matches the irq_handler_entry record - var irqHandlerEntryRE = /irq=(\d+) name=(.+)/; - - // Matches the irq_handler_exit record - var irqHandlerExitRE = /irq=(\d+) ret=(.+)/; - - // Matches the softirq_raise record - var softirqRE = /vec=(\d+) \[action=(.+)\]/; - - // Matches the ipi_exit_ - var ipiHandlerExitRE = /\((.+)\)/; - - IrqParser.prototype = { - __proto__: Parser.prototype, - - /** - * Parses irq events and sets up state in the mporter. - */ - irqHandlerEntryEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = irqHandlerEntryRE.exec(eventBase.details); - if (!event) - return false; - - var irq = parseInt(event[1]); - var name = event[2]; - - var thread = this.importer.getOrCreatePseudoThread( - 'irqs cpu ' + cpuNumber); - thread.lastEntryTs = ts; - thread.irqName = name; - - return true; - }, - - irqHandlerExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = irqHandlerExitRE.exec(eventBase.details); - if (!event) - return false; - - var irq = parseInt(event[1]); - var ret = event[2]; - var thread = this.importer.getOrCreatePseudoThread( - 'irqs cpu ' + cpuNumber); - - if (thread.lastEntryTs !== undefined) { - var duration = ts - thread.lastEntryTs; - var slice = new tr.model.Slice( - '', - 'IRQ (' + thread.irqName + ')', - ColorScheme.getColorIdForGeneralPurposeString(event[1]), - thread.lastEntryTs, { ret: ret }, - duration); - thread.thread.sliceGroup.pushSlice(slice); - } - thread.lastEntryTs = undefined; - thread.irqName = undefined; - return true; - }, - - softirqRaiseEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - return true; - }, - - softirqEntryEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = softirqRE.exec(eventBase.details); - if (!event) - return false; - - var action = event[2]; - var thread = this.importer.getOrCreatePseudoThread( - 'softirq cpu ' + cpuNumber); - thread.lastEntryTs = ts; - - return true; - }, - - softirqExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = softirqRE.exec(eventBase.details); - if (!event) - return false; - - var vec = parseInt(event[1]); - var action = event[2]; - var thread = this.importer.getOrCreatePseudoThread( - 'softirq cpu ' + cpuNumber); - - if (thread.lastEntryTs !== undefined) { - var duration = ts - thread.lastEntryTs; - var slice = new tr.model.Slice( - '', action, - ColorScheme.getColorIdForGeneralPurposeString(event[1]), - thread.lastEntryTs, { vec: vec }, - duration); - thread.thread.sliceGroup.pushSlice(slice); - } - thread.lastEntryTs = undefined; - return true; - }, - /** - * Parses ipi events and sets up state in the mporter. - */ - ipiEntryEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var thread = this.importer.getOrCreatePseudoThread( - 'irqs cpu ' + cpuNumber); - thread.lastEntryTs = ts; - - return true; - }, - - ipiExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = ipiHandlerExitRE.exec(eventBase.details); - if (!event) - return false; - - var ipiName = event[1]; - var thread = this.importer.getOrCreatePseudoThread( - 'irqs cpu ' + cpuNumber); - - if (thread.lastEntryTs !== undefined) { - var duration = ts - thread.lastEntryTs; - var slice = new tr.model.Slice( - '', - 'IPI (' + ipiName + ')', - ColorScheme.getColorIdForGeneralPurposeString(ipiName), - thread.lastEntryTs, - {}, - duration); - thread.thread.sliceGroup.pushSlice(slice); - } - thread.lastEntryTs = undefined; - return true; - } - }; - - Parser.register(IrqParser); - - return { - IrqParser: IrqParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/irq_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/irq_parser_test.html deleted file mode 100644 index 647bd821e73..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/irq_parser_test.html +++ /dev/null @@ -1,51 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('irqImport', function() { - var lines = [ - ' kworker/u4:1-31907 (31907) [001] d.h3 14063.748288: ' + - 'irq_handler_entry: irq=27 name=arch_timer', - ' kworker/u4:1-31907 (31907) [001] dNh3 14063.748384: ' + - 'irq_handler_exit: irq=27 ret=handled', - ' kworker/u4:2-31908 (31908) [000] ..s3 14063.477231: ' + - 'softirq_entry: vec=9 [action=RCU]', - ' kworker/u4:2-31908 (31908) [000] ..s3 14063.477246: ' + - 'softirq_exit: vec=9 [action=RCU]', - ' RenderThread-2978 ( 2794) [002] dN.1 62828.421805: ' + - 'ipi_entry: (Rescheduling interrupts)', - ' RenderThread-2978 ( 2794) [002] dN.1 62828.421809: ' + - 'ipi_exit: (Rescheduling interrupts)' - ]; - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 3); - - var threads = m.findAllThreadsNamed('irqs cpu 1'); - assert.equal(threads.length, 1); - assert.equal(threads[0].sliceGroup.length, 1); - - var threads = m.findAllThreadsNamed('softirq cpu 0'); - assert.equal(threads.length, 1); - assert.equal(threads[0].sliceGroup.length, 1); - - var threads = m.findAllThreadsNamed('irqs cpu 2'); - assert.equal(threads.length, 1); - assert.equal(threads[0].sliceGroup.length, 1); - }); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/kfunc_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/kfunc_parser.html deleted file mode 100644 index 72dbc71e512..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/kfunc_parser.html +++ /dev/null @@ -1,113 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses graph_ent and graph_ret events that were inserted by - * the Linux kernel's function graph trace. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var LinuxPerfParser = tr.e.importer.linux_perf.Parser; - - /** - * Parses graph_ent and graph_ret events that were inserted by the Linux - * kernel's function graph trace. - * @constructor - */ - function KernelFuncParser(importer) { - LinuxPerfParser.call(this, importer); - - importer.registerEventHandler('graph_ent', - KernelFuncParser.prototype.traceKernelFuncEnterEvent. - bind(this)); - importer.registerEventHandler('graph_ret', - KernelFuncParser.prototype.traceKernelFuncReturnEvent. - bind(this)); - - this.model_ = importer.model_; - this.ppids_ = {}; - } - - var TestExports = {}; - - var funcEnterRE = new RegExp('func=(.+)'); - TestExports.funcEnterRE = funcEnterRE; - - KernelFuncParser.prototype = { - __proto__: LinuxPerfParser.prototype, - - traceKernelFuncEnterEvent: function(eventName, cpuNumber, pid, ts, - eventBase) { - var eventData = funcEnterRE.exec(eventBase.details); - if (!eventData) - return false; - - if (eventBase.tgid === undefined) { - return false; - } - - var tgid = parseInt(eventBase.tgid); - var name = eventData[1]; - var thread = this.model_.getOrCreateProcess(tgid) - .getOrCreateThread(pid); - thread.name = eventBase.threadName; - - var slices = thread.kernelSliceGroup; - if (!slices.isTimestampValidForBeginOrEnd(ts)) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Timestamps are moving backward.' - }); - return false; - } - - var slice = slices.beginSlice(null, name, ts, {}); - - return true; - }, - - traceKernelFuncReturnEvent: function(eventName, cpuNumber, pid, ts, - eventBase) { - if (eventBase.tgid === undefined) { - return false; - } - - var tgid = parseInt(eventBase.tgid); - var thread = this.model_.getOrCreateProcess(tgid) - .getOrCreateThread(pid); - thread.name = eventBase.threadName; - - var slices = thread.kernelSliceGroup; - if (!slices.isTimestampValidForBeginOrEnd(ts)) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Timestamps are moving backward.' - }); - return false; - } - - if (slices.openSliceCount > 0) { - slices.endSlice(ts); - } - - return true; - } - }; - - LinuxPerfParser.register(KernelFuncParser); - - return { - KernelFuncParser: KernelFuncParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/kfunc_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/kfunc_parser_test.html deleted file mode 100644 index 5d7dfd67526..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/kfunc_parser_test.html +++ /dev/null @@ -1,60 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('kernelFunctionParser', function() { - var lines = [ - 'Binder_2-127 ( 127) [001] .... 3431.906759: graph_ent: func=sys_write', - 'Binder_2-127 ( 127) [001] .... 3431.906769: graph_ret: func=sys_write', - 'Binder_2-127 ( 127) [001] .... 3431.906785: graph_ent: func=sys_write', - 'Binder_2-127 ( 127) [001] ...1 3431.906798: tracing_mark_write: B|' + - '127|dequeueBuffer', - 'Binder_2-127 ( 127) [001] .... 3431.906802: graph_ret: func=sys_write', - 'Binder_2-127 ( 127) [001] .... 3431.906842: graph_ent: func=sys_write', - 'Binder_2-127 ( 127) [001] ...1 3431.906849: tracing_mark_write: E', - 'Binder_2-127 ( 127) [001] .... 3431.906853: graph_ret: func=sys_write', - 'Binder_2-127 ( 127) [001] .... 3431.906896: graph_ent: func=sys_write', - 'Binder_2-127 ( 127) [001] .... 3431.906906: graph_ret: func=sys_write' - ]; - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var process = m.processes[127]; - assert.isDefined(process); - - var thread = process.threads[127]; - assert.isDefined(thread); - - var slices = thread.sliceGroup.slices; - assert.equal(thread.sliceGroup.length, 7); - - // Slice 0 is an un-split sys_write - assert.equal(slices[0].title, 'sys_write'); - - // Slices 1 & 3 are a split sys_write - assert.equal(slices[1].title, 'sys_write'); - assert.equal(slices[2].title, 'dequeueBuffer'); - assert.equal(slices[3].title, 'sys_write (cont.)'); - - // Slices 4 & 5 are a split sys_write with the dequeueBuffer in between - assert.equal(slices[4].title, 'sys_write'); - assert.equal(slices[5].title, 'sys_write (cont.)'); - - // Slice 6 is another un-split sys_write - assert.equal(slices[6].title, 'sys_write'); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/mali_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/mali_parser.html deleted file mode 100644 index 0516805f740..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/mali_parser.html +++ /dev/null @@ -1,568 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses Mali DDK/kernel events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses Mali DDK/kernel trace events. - * @constructor - */ - function MaliParser(importer) { - Parser.call(this, importer); - - // kernel DVFS events - importer.registerEventHandler('mali_dvfs_event', - MaliParser.prototype.dvfsEventEvent.bind(this)); - importer.registerEventHandler('mali_dvfs_set_clock', - MaliParser.prototype.dvfsSetClockEvent.bind(this)); - importer.registerEventHandler('mali_dvfs_set_voltage', - MaliParser.prototype.dvfsSetVoltageEvent.bind(this)); - - // kernel Mali hw counter events - this.addJMCounter('mali_hwc_MESSAGES_SENT', 'Messages Sent'); - this.addJMCounter('mali_hwc_MESSAGES_RECEIVED', 'Messages Received'); - this.addJMCycles('mali_hwc_GPU_ACTIVE', 'GPU Active'); - this.addJMCycles('mali_hwc_IRQ_ACTIVE', 'IRQ Active'); - - for (var i = 0; i < 7; i++) { - var jobStr = 'JS' + i; - var jobHWCStr = 'mali_hwc_' + jobStr; - this.addJMCounter(jobHWCStr + '_JOBS', jobStr + ' Jobs'); - this.addJMCounter(jobHWCStr + '_TASKS', jobStr + ' Tasks'); - this.addJMCycles(jobHWCStr + '_ACTIVE', jobStr + ' Active'); - this.addJMCycles(jobHWCStr + '_WAIT_READ', jobStr + ' Wait Read'); - this.addJMCycles(jobHWCStr + '_WAIT_ISSUE', jobStr + ' Wait Issue'); - this.addJMCycles(jobHWCStr + '_WAIT_DEPEND', jobStr + ' Wait Depend'); - this.addJMCycles(jobHWCStr + '_WAIT_FINISH', jobStr + ' Wait Finish'); - } - - this.addTilerCounter('mali_hwc_TRIANGLES', 'Triangles'); - this.addTilerCounter('mali_hwc_QUADS', 'Quads'); - this.addTilerCounter('mali_hwc_POLYGONS', 'Polygons'); - this.addTilerCounter('mali_hwc_POINTS', 'Points'); - this.addTilerCounter('mali_hwc_LINES', 'Lines'); - this.addTilerCounter('mali_hwc_VCACHE_HIT', 'VCache Hit'); - this.addTilerCounter('mali_hwc_VCACHE_MISS', 'VCache Miss'); - this.addTilerCounter('mali_hwc_FRONT_FACING', 'Front Facing'); - this.addTilerCounter('mali_hwc_BACK_FACING', 'Back Facing'); - this.addTilerCounter('mali_hwc_PRIM_VISIBLE', 'Prim Visible'); - this.addTilerCounter('mali_hwc_PRIM_CULLED', 'Prim Culled'); - this.addTilerCounter('mali_hwc_PRIM_CLIPPED', 'Prim Clipped'); - - this.addTilerCounter('mali_hwc_WRBUF_HIT', 'Wrbuf Hit'); - this.addTilerCounter('mali_hwc_WRBUF_MISS', 'Wrbuf Miss'); - this.addTilerCounter('mali_hwc_WRBUF_LINE', 'Wrbuf Line'); - this.addTilerCounter('mali_hwc_WRBUF_PARTIAL', 'Wrbuf Partial'); - this.addTilerCounter('mali_hwc_WRBUF_STALL', 'Wrbuf Stall'); - - this.addTilerCycles('mali_hwc_ACTIVE', 'Tiler Active'); - this.addTilerCycles('mali_hwc_INDEX_WAIT', 'Index Wait'); - this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT', 'Index Range Wait'); - this.addTilerCycles('mali_hwc_VERTEX_WAIT', 'Vertex Wait'); - this.addTilerCycles('mali_hwc_PCACHE_WAIT', 'Pcache Wait'); - this.addTilerCycles('mali_hwc_WRBUF_WAIT', 'Wrbuf Wait'); - this.addTilerCycles('mali_hwc_BUS_READ', 'Bus Read'); - this.addTilerCycles('mali_hwc_BUS_WRITE', 'Bus Write'); - - this.addTilerCycles('mali_hwc_TILER_UTLB_STALL', 'Tiler UTLB Stall'); - this.addTilerCycles('mali_hwc_TILER_UTLB_HIT', 'Tiler UTLB Hit'); - - this.addFragCycles('mali_hwc_FRAG_ACTIVE', 'Active'); - /* NB: don't propagate spelling mistakes to labels */ - this.addFragCounter('mali_hwc_FRAG_PRIMATIVES', 'Primitives'); - this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED', - 'Primitives Dropped'); - this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC', 'Descriptor Processing'); - this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR', 'PLR Processing??'); - this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT', 'Vertex Processing'); - this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP', 'Triangle Setup'); - this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST', 'Rasterization???'); - this.addFragCounter('mali_hwc_FRAG_THREADS', 'Threads'); - this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS', 'Dummy Threads'); - this.addFragCounter('mali_hwc_FRAG_QUADS_RAST', 'Quads Rast'); - this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST', 'Quads EZS Test'); - this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED', 'Quads EZS Killed'); - this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST', 'Quads LZS Test'); - this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED', 'Quads LZS Killed'); - this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE', 'No Tiles'); - this.addFragCounter('mali_hwc_FRAG_NUM_TILES', 'Tiles'); - this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM', 'Transactions Eliminated'); - - this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE', 'Active'); - this.addComputeCounter('mali_hwc_COMPUTE_TASKS', 'Tasks'); - this.addComputeCounter('mali_hwc_COMPUTE_THREADS', 'Threads Started'); - this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC', - 'Waiting for Descriptors'); - - this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE', 'Active'); - - this.addArithCounter('mali_hwc_ARITH_WORDS', 'Instructions (/Pipes)'); - this.addArithCycles('mali_hwc_ARITH_CYCLES_REG', - 'Reg scheduling stalls (/Pipes)'); - this.addArithCycles('mali_hwc_ARITH_CYCLES_L0', - 'L0 cache miss stalls (/Pipes)'); - this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND', - 'Frag dep check failures (/Pipes)'); - - this.addLSCounter('mali_hwc_LS_WORDS', 'Instruction Words Completed'); - this.addLSCounter('mali_hwc_LS_ISSUES', 'Full Pipeline Issues'); - this.addLSCounter('mali_hwc_LS_RESTARTS', 'Restarts (unpairable insts)'); - this.addLSCounter('mali_hwc_LS_REISSUES_MISS', - 'Pipeline reissue (cache miss/uTLB)'); - this.addLSCounter('mali_hwc_LS_REISSUES_VD', - 'Pipeline reissue (varying data)'); - /* TODO(sleffler) fix kernel event typo */ - this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS', - 'Pipeline reissue (attribute cache miss)'); - this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB', 'Writeback not used'); - - this.addTexCounter('mali_hwc_TEX_WORDS', 'Words'); - this.addTexCounter('mali_hwc_TEX_BUBBLES', 'Bubbles'); - this.addTexCounter('mali_hwc_TEX_WORDS_L0', 'Words L0'); - this.addTexCounter('mali_hwc_TEX_WORDS_DESC', 'Words Desc'); - this.addTexCounter('mali_hwc_TEX_THREADS', 'Threads'); - this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS', 'Recirc due to Full Miss'); - this.addTexCounter('mali_hwc_TEX_RECIRC_DESC', 'Recirc due to Desc Miss'); - this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI', 'Recirc due to Multipass'); - this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS', - 'Recirc due to Partial Cache Miss'); - this.addTexCounter('mali_hwc_TEX_RECIRC_CONF', - 'Recirc due to Cache Conflict'); - - this.addLSCCounter('mali_hwc_LSC_READ_HITS', 'Read Hits'); - this.addLSCCounter('mali_hwc_LSC_READ_MISSES', 'Read Misses'); - this.addLSCCounter('mali_hwc_LSC_WRITE_HITS', 'Write Hits'); - this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES', 'Write Misses'); - this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS', 'Atomic Hits'); - this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES', 'Atomic Misses'); - this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES', 'Line Fetches'); - this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE', 'Dirty Lines'); - this.addLSCCounter('mali_hwc_LSC_SNOOPS', 'Snoops'); - - this.addAXICounter('mali_hwc_AXI_TLB_STALL', 'Address channel stall'); - this.addAXICounter('mali_hwc_AXI_TLB_MISS', 'Cache Miss'); - this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION', 'Transactions'); - this.addAXICounter('mali_hwc_LS_TLB_MISS', 'LS Cache Miss'); - this.addAXICounter('mali_hwc_LS_TLB_HIT', 'LS Cache Hit'); - this.addAXICounter('mali_hwc_AXI_BEATS_READ', 'Read Beats'); - this.addAXICounter('mali_hwc_AXI_BEATS_WRITE', 'Write Beats'); - - this.addMMUCounter('mali_hwc_MMU_TABLE_WALK', 'Page Table Walks'); - this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS', - 'Cache Miss from Replay Buffer'); - this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL', 'Replay Buffer Full'); - this.addMMUCounter('mali_hwc_MMU_NEW_MISS', 'Cache Miss on New Request'); - this.addMMUCounter('mali_hwc_MMU_HIT', 'Cache Hit'); - - this.addMMUCycles('mali_hwc_UTLB_STALL', 'UTLB Stalled'); - this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS', 'UTLB Replay Miss'); - this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL', 'UTLB Replay Full'); - this.addMMUCycles('mali_hwc_UTLB_NEW_MISS', 'UTLB New Miss'); - this.addMMUCycles('mali_hwc_UTLB_HIT', 'UTLB Hit'); - - this.addL2Counter('mali_hwc_L2_READ_BEATS', 'Read Beats'); - this.addL2Counter('mali_hwc_L2_WRITE_BEATS', 'Write Beats'); - this.addL2Counter('mali_hwc_L2_ANY_LOOKUP', 'Any Lookup'); - this.addL2Counter('mali_hwc_L2_READ_LOOKUP', 'Read Lookup'); - this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP', 'Shareable Read Lookup'); - this.addL2Counter('mali_hwc_L2_READ_REPLAY', 'Read Replayed'); - this.addL2Counter('mali_hwc_L2_READ_SNOOP', 'Read Snoop'); - this.addL2Counter('mali_hwc_L2_READ_HIT', 'Read Cache Hit'); - this.addL2Counter('mali_hwc_L2_CLEAN_MISS', 'CleanUnique Miss'); - this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP', 'Write Lookup'); - this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP', 'Shareable Write Lookup'); - this.addL2Counter('mali_hwc_L2_WRITE_REPLAY', 'Write Replayed'); - this.addL2Counter('mali_hwc_L2_WRITE_SNOOP', 'Write Snoop'); - this.addL2Counter('mali_hwc_L2_WRITE_HIT', 'Write Cache Hit'); - this.addL2Counter('mali_hwc_L2_EXT_READ_FULL', 'ExtRD with BIU Full'); - this.addL2Counter('mali_hwc_L2_EXT_READ_HALF', 'ExtRD with BIU >1/2 Full'); - this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL', 'ExtWR with BIU Full'); - this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF', 'ExtWR with BIU >1/2 Full'); - - this.addL2Counter('mali_hwc_L2_EXT_READ', 'External Read (ExtRD)'); - this.addL2Counter('mali_hwc_L2_EXT_READ_LINE', 'ExtRD (linefill)'); - this.addL2Counter('mali_hwc_L2_EXT_WRITE', 'External Write (ExtWR)'); - this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE', 'ExtWR (linefill)'); - this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL', 'ExtWR (burst size <64B)'); - this.addL2Counter('mali_hwc_L2_EXT_BARRIER', 'External Barrier'); - this.addL2Counter('mali_hwc_L2_EXT_AR_STALL', 'Address Read stalls'); - this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL', - 'Response Buffer full stalls'); - this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL', - 'Read Data Buffer full stalls'); - this.addL2Counter('mali_hwc_L2_EXT_R_RAW', 'RAW hazard stalls'); - this.addL2Counter('mali_hwc_L2_EXT_W_STALL', 'Write Data stalls'); - this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL', 'Write Data Buffer full'); - this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD', 'WAW or WAR hazard stalls'); - this.addL2Counter('mali_hwc_L2_TAG_HAZARD', 'Tag hazard replays'); - this.addL2Cycles('mali_hwc_L2_SNOOP_FULL', 'Snoop buffer full'); - this.addL2Cycles('mali_hwc_L2_REPLAY_FULL', 'Replay buffer full'); - - // DDK events (from X server) - importer.registerEventHandler('tracing_mark_write:mali_driver', - MaliParser.prototype.maliDDKEvent.bind(this)); - - this.model_ = importer.model_; - } - - MaliParser.prototype = { - __proto__: Parser.prototype, - - maliDDKOpenSlice: function(pid, tid, ts, func, blockinfo) { - var thread = this.importer.model_.getOrCreateProcess(pid) - .getOrCreateThread(tid); - var funcArgs = /^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func); - thread.sliceGroup.beginSlice('gpu-driver', funcArgs[1], ts, - { 'args': funcArgs[2], - 'blockinfo': blockinfo }); - }, - - maliDDKCloseSlice: function(pid, tid, ts, args, blockinfo) { - var thread = this.importer.model_.getOrCreateProcess(pid) - .getOrCreateThread(tid); - if (!thread.sliceGroup.openSliceCount) { - // Discard unmatched ends. - return; - } - thread.sliceGroup.endSlice(ts); - }, - - /** - * Deduce the format of Mali perf events. - * - * @return {RegExp} the regular expression for parsing data when the format - * is recognized; otherwise null. - */ - autoDetectLineRE: function(line) { - // Matches Mali perf events with thread info - var lineREWithThread = - /^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/; - if (lineREWithThread.test(line)) - return lineREWithThread; - - // Matches old-style Mali perf events - var lineRENoThread = /^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/; - if (lineRENoThread.test(line)) - return lineRENoThread; - return null; - }, - - lineRE: null, - - /** - * Parses maliDDK events and sets up state in the importer. - * events will come in pairs with a cros_trace_print_enter - * like this (line broken here for formatting): - * - * tracing_mark_write: mali_driver: (mali-012345) cros_trace_print_enter: \ - * gles/src/texture/mali_gles_texture_slave.c@1505: gles2_texturep_upload - * - * and a cros_trace_print_exit like this: - * - * tracing_mark_write: mali_driver: (mali-012345) cros_trace_print_exit: \ - * gles/src/texture/mali_gles_texture_slave.c@1505: - */ - maliDDKEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - if (this.lineRE == null) { - this.lineRE = this.autoDetectLineRE(eventBase.details); - if (this.lineRE == null) - return false; - } - var maliEvent = this.lineRE.exec(eventBase.details); - // Old-style Mali perf events have no thread id, so make one. - var tid = (maliEvent[1] === '' ? 'mali' : maliEvent[1]); - switch (maliEvent[2]) { - case 'cros_trace_print_enter': - this.maliDDKOpenSlice(pid, tid, ts, maliEvent[4], - maliEvent[3]); - break; - case 'cros_trace_print_exit': - this.maliDDKCloseSlice(pid, tid, ts, [], maliEvent[3]); - } - return true; - }, - - /* - * Kernel event support. - */ - - dvfsSample: function(counterName, seriesName, ts, s) { - var value = parseInt(s); - var counter = this.model_.kernel. - getOrCreateCounter('DVFS', counterName); - if (counter.numSeries === 0) { - counter.addSeries(new tr.model.CounterSeries(seriesName, - ColorScheme.getColorIdForGeneralPurposeString(counter.name))); - } - counter.series.forEach(function(series) { - series.addCounterSample(ts, value); - }); - }, - - dvfsEventEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /utilization=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - this.dvfsSample('DVFS Utilization', 'utilization', ts, event[1]); - return true; - }, - - dvfsSetClockEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /frequency=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - this.dvfsSample('DVFS Frequency', 'frequency', ts, event[1]); - return true; - }, - - dvfsSetVoltageEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /voltage=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - this.dvfsSample('DVFS Voltage', 'voltage', ts, event[1]); - return true; - }, - - hwcSample: function(cat, counterName, seriesName, ts, eventBase) { - var event = /val=(\d+)/.exec(eventBase.details); - if (!event) - return false; - var value = parseInt(event[1]); - - var counter = this.model_.kernel. - getOrCreateCounter(cat, counterName); - if (counter.numSeries === 0) { - counter.addSeries(new tr.model.CounterSeries(seriesName, - ColorScheme.getColorIdForGeneralPurposeString(counter.name))); - } - counter.series.forEach(function(series) { - series.addCounterSample(ts, value); - }); - return true; - }, - - /* - * Job Manager block counters. - */ - jmSample: function(ctrName, seriesName, ts, eventBase) { - return this.hwcSample('mali:jm', 'JM: ' + ctrName, seriesName, ts, - eventBase); - }, - addJMCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.jmSample(hwcTitle, 'count', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - addJMCycles: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.jmSample(hwcTitle, 'cycles', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * Tiler block counters. - */ - tilerSample: function(ctrName, seriesName, ts, eventBase) { - return this.hwcSample('mali:tiler', 'Tiler: ' + ctrName, seriesName, - ts, eventBase); - }, - addTilerCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.tilerSample(hwcTitle, 'count', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - addTilerCycles: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.tilerSample(hwcTitle, 'cycles', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * Fragment counters. - */ - fragSample: function(ctrName, seriesName, ts, eventBase) { - return this.hwcSample('mali:fragment', 'Fragment: ' + ctrName, - seriesName, ts, eventBase); - }, - addFragCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.fragSample(hwcTitle, 'count', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - addFragCycles: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.fragSample(hwcTitle, 'cycles', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * Compute counters. - */ - computeSample: function(ctrName, seriesName, ts, eventBase) { - return this.hwcSample('mali:compute', 'Compute: ' + ctrName, - seriesName, ts, eventBase); - }, - addComputeCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.computeSample(hwcTitle, 'count', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - addComputeCycles: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.computeSample(hwcTitle, 'cycles', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * Tripipe counters. - */ - addTripipeCycles: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.hwcSample('mali:shader', 'Tripipe: ' + hwcTitle, 'cycles', - ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * Arith counters. - */ - arithSample: function(ctrName, seriesName, ts, eventBase) { - return this.hwcSample('mali:arith', 'Arith: ' + ctrName, seriesName, ts, - eventBase); - }, - addArithCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.arithSample(hwcTitle, 'count', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - addArithCycles: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.arithSample(hwcTitle, 'cycles', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * Load/Store counters. - */ - addLSCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.hwcSample('mali:ls', 'LS: ' + hwcTitle, 'count', ts, - eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * Texture counters. - */ - textureSample: function(ctrName, seriesName, ts, eventBase) { - return this.hwcSample('mali:texture', 'Texture: ' + ctrName, - seriesName, ts, eventBase); - }, - addTexCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.textureSample(hwcTitle, 'count', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * LSC counters. - */ - addLSCCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.hwcSample('mali:lsc', 'LSC: ' + hwcTitle, 'count', ts, - eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * TLB counters. - */ - addAXICounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.hwcSample('mali:axi', 'AXI: ' + hwcTitle, 'count', ts, - eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * MMU counters. - */ - mmuSample: function(ctrName, seriesName, ts, eventBase) { - return this.hwcSample('mali:mmu', 'MMU: ' + ctrName, seriesName, ts, - eventBase); - }, - addMMUCounter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.mmuSample(hwcTitle, 'count', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - addMMUCycles: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.mmuSample(hwcTitle, 'cycles', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - - /* - * L2 counters. - */ - l2Sample: function(ctrName, seriesName, ts, eventBase) { - return this.hwcSample('mali:l2', 'L2: ' + ctrName, seriesName, ts, - eventBase); - }, - addL2Counter: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.l2Sample(hwcTitle, 'count', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - }, - addL2Cycles: function(hwcEventName, hwcTitle) { - function handler(eventName, cpuNumber, pid, ts, eventBase) { - return this.l2Sample(hwcTitle, 'cycles', ts, eventBase); - } - this.importer.registerEventHandler(hwcEventName, handler.bind(this)); - } - }; - - Parser.register(MaliParser); - - return { - MaliParser: MaliParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/mali_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/mali_parser_test.html deleted file mode 100644 index be19c73896f..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/mali_parser_test.html +++ /dev/null @@ -1,485 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('maliDDKImport', function() { - var linesNoThread = [ - // Row 1 open - ' chrome-1780 [001] ...1 28.562633: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'gles/src/dispatch/mali_gles_dispatch_entrypoints.c992: ' + - 'glTexSubImage2D', - // Row 2 open - ' chrome-1780 [001] ...1 28.562655: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'gles/src/texture/mali_gles_texture_api.c996: ' + - 'gles_texture_tex_sub_image_2d', - // Row 3 open - ' chrome-1780 [001] ...1 28.562671: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'gles/src/texture/mali_gles_texture_slave.c295: ' + - 'gles_texturep_slave_map_master', - // Row 3 close - ' chrome-1780 [001] ...1 28.562684: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'gles/src/texture/mali_gles_texture_slave.c295: ', - // Row 3 open - ' chrome-1780 [001] ...1 28.562700: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'gles/src/texture/mali_gles_texture_slave.c1505: ' + - 'gles2_texturep_upload_2d', - // Row 4 open - ' chrome-1780 [001] ...1 28.562726: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'gles/src/texture/mali_gles_texture_slave.c1612: ' + - 'gles2_texturep_upload_2d: pixel array: wait for dependencies', - // Row 5 open - ' chrome-1780 [001] ...1 28.562742: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'cobj/src/mali_cobj_surface_operations.c1693: ' + - 'cobj_convert_pixels_to_surface', - // Row 6 open - ' chrome-1780 [001] ...1 28.562776: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'cobj/src/mali_cobj_surface_operations.c1461: ' + - 'cobj_convert_pixels', - // Row 7 open - ' chrome-1780 [001] ...1 28.562791: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'cobj/src/mali_cobj_surface_operations.c1505: ' + - 'cobj_convert_pixels: fast-path linear copy', - // Row 8 open - ' chrome-1780 [001] ...1 28.562808: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_enter: ' + - 'cobj/src/mali_cobj_surface_operations.c1511: ' + - 'cobj_convert_pixels: reorder-only', - // Row 8 close - ' chrome-1780 [001] ...1 28.563383: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'cobj/src/mali_cobj_surface_operations.c1511', - // Row 7 close - ' chrome-1780 [001] ...1 28.563397: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'cobj/src/mali_cobj_surface_operations.c1505', - // Row 6 close - ' chrome-1780 [001] ...1 28.563409: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'cobj/src/mali_cobj_surface_operations.c1461', - // Row 5 close - ' chrome-1780 [001] ...1 28.563438: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'cobj/src/mali_cobj_surface_operations.c1693', - // Row 4 close - ' chrome-1780 [001] ...1 28.563451: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'gles/src/texture/mali_gles_texture_slave.c1612', - // Row 3 close - ' chrome-1780 [001] ...1 28.563462: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'gles/src/texture/mali_gles_texture_slave.c1505', - // Row 2 close - ' chrome-1780 [001] ...1 28.563475: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'gles/src/texture/mali_gles_texture_api.c996', - // Row 1 close - ' chrome-1780 [001] ...1 28.563486: tracing_mark_write: ' + - 'mali_driver: cros_trace_print_exit: ' + - 'gles/src/dispatch/mali_gles_dispatch_entrypoints.c992' - ]; - - var linesWithThread = [ - // Row 1 open - ' chrome-1780 [001] ...1 28.562633: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'gles/src/dispatch/mali_gles_dispatch_entrypoints.c@992: ' + - 'glTexSubImage2D', - // Row 2 open - ' chrome-1780 [001] ...1 28.562655: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'gles/src/texture/mali_gles_texture_api.c@996: ' + - 'gles_texture_tex_sub_image_2d', - // Row 3 open - ' chrome-1780 [001] ...1 28.562671: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'gles/src/texture/mali_gles_texture_slave.c@295: ' + - 'gles_texturep_slave_map_master', - // Row 3 close - ' chrome-1780 [001] ...1 28.562684: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'gles/src/texture/mali_gles_texture_slave.c@295: ', - // Row 3 open - ' chrome-1780 [001] ...1 28.562700: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'gles/src/texture/mali_gles_texture_slave.c@1505: ' + - 'gles2_texturep_upload_2d', - // Row 4 open - ' chrome-1780 [001] ...1 28.562726: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'gles/src/texture/mali_gles_texture_slave.c@1612: ' + - 'gles2_texturep_upload_2d: pixel array: wait for dependencies', - // Row 5 open - ' chrome-1780 [001] ...1 28.562742: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'cobj/src/mali_cobj_surface_operations.c@1693: ' + - 'cobj_convert_pixels_to_surface', - // Row 6 open - ' chrome-1780 [001] ...1 28.562776: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'cobj/src/mali_cobj_surface_operations.c@1461: ' + - 'cobj_convert_pixels', - // Row 7 open - ' chrome-1780 [001] ...1 28.562791: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'cobj/src/mali_cobj_surface_operations.c@1505: ' + - 'cobj_convert_pixels: fast-path linear copy', - // Row 8 open - ' chrome-1780 [001] ...1 28.562808: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_enter: ' + - 'cobj/src/mali_cobj_surface_operations.c@1511: ' + - 'cobj_convert_pixels: reorder-only', - // Row 8 close - ' chrome-1780 [001] ...1 28.563383: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'cobj/src/mali_cobj_surface_operations.c@1511', - // Row 7 close - ' chrome-1780 [001] ...1 28.563397: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'cobj/src/mali_cobj_surface_operations.c@1505', - // Row 6 close - ' chrome-1780 [001] ...1 28.563409: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'cobj/src/mali_cobj_surface_operations.c@1461', - // Row 5 close - ' chrome-1780 [001] ...1 28.563438: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'cobj/src/mali_cobj_surface_operations.c@1693', - // Row 4 close - ' chrome-1780 [001] ...1 28.563451: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'gles/src/texture/mali_gles_texture_slave.c@1612', - // Row 3 close - ' chrome-1780 [001] ...1 28.563462: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'gles/src/texture/mali_gles_texture_slave.c@1505', - // Row 2 close - ' chrome-1780 [001] ...1 28.563475: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'gles/src/texture/mali_gles_texture_api.c@996', - // Row 1 close - ' chrome-1780 [001] ...1 28.563486: tracing_mark_write: ' + - 'mali_driver: (mali-1878934320) cros_trace_print_exit: ' + - 'gles/src/dispatch/mali_gles_dispatch_entrypoints.c@992' - ]; - var traceNoThread = newModel(linesNoThread.join('\n')); - var traceWithThread = newModel(linesWithThread.join('\n')); - assert.isFalse(traceNoThread.hasImportWarnings); - assert.isFalse(traceWithThread.hasImportWarnings); - - var threadsNoThread = traceNoThread.getAllThreads(); - var threadsWithThread = traceWithThread.getAllThreads(); - assert.equal(threadsNoThread.length, 1); - assert.equal(threadsWithThread.length, 1); - - var maliThreadNoThread = threadsNoThread[0]; - var maliThreadWithThread = threadsWithThread[0]; - assert.equal(maliThreadNoThread.tid, 'mali'); - assert.equal(maliThreadWithThread.tid, 'mali-1878934320'); - assert.equal(maliThreadNoThread.sliceGroup.length, 9); - assert.equal(maliThreadWithThread.sliceGroup.length, 9); - }); - - test('DVFSFrequencyImport', function() { - var lines = [ - ' kworker/u:0-5 [001] .... 1174.839552: mali_dvfs_set_clock: ' + - 'frequency=266', - ' kworker/u:0-5 [000] .... 1183.840486: mali_dvfs_set_clock: ' + - 'frequency=400' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var counters = m.getAllCounters(); - assert.equal(counters.length, 1); - - var c0 = counters[0]; - assert.equal(c0.name, 'DVFS Frequency'); - assert.equal(c0.series[0].samples.length, 2); - }); - - test('DVFSVoltageImport', function() { - var lines = [ - ' kworker/u:0-5 [001] .... 1174.839562: mali_dvfs_set_voltage: ' + - 'voltage=937500', - ' kworker/u:0-5 [000] .... 1183.840009: mali_dvfs_set_voltage: ' + - 'voltage=1100000' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var counters = m.getAllCounters(); - assert.equal(counters.length, 1); - - var c0 = counters[0]; - assert.equal(c0.name, 'DVFS Voltage'); - assert.equal(c0.series[0].samples.length, 2); - }); - - test('DVFSUtilizationImport', function() { - var lines = [ - ' kworker/u:0-5 [001] .... 1174.839552: mali_dvfs_event: ' + - 'utilization=7', - ' kworker/u:0-5 [000] .... 1183.840486: mali_dvfs_event: ' + - 'utilization=37' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var counters = m.getAllCounters(); - assert.equal(counters.length, 1); - - var c0 = counters[0]; - assert.equal(c0.name, 'DVFS Utilization'); - assert.equal(c0.series[0].samples.length, 2); - }); - - test('maliHWCImport', function() { - var lines = [ - ' kworker/u:0-5 [000] .... 78.896588: ' + - 'mali_hwc_ACTIVE: val=238', - ' kworker/u:0-5 [000] .... 79.046889: ' + - 'mali_hwc_ARITH_CYCLES_L0: val=1967', - ' kworker/u:0-5 [000] .... 79.046888: ' + - 'mali_hwc_ARITH_CYCLES_REG: val=136', - ' kworker/u:0-5 [000] .... 79.046890: ' + - 'mali_hwc_ARITH_FRAG_DEPEND: val=19676', - ' kworker/u:0-5 [000] .... 79.046886: ' + - 'mali_hwc_ARITH_WORDS: val=255543', - ' kworker/u:0-5 [000] .... 79.046920: ' + - 'mali_hwc_AXI_BEATS_READ: val=257053', - ' kworker/u:0-5 [000] .... 78.896594: ' + - 'mali_hwc_AXI_TLB_STALL: val=1', - ' kworker/u:0-5 [000] .... 78.946646: ' + - 'mali_hwc_AXI_TLB_TRANSACTION: val=4', - ' kworker/u:0-5 [000] .... 79.046853: ' + - 'mali_hwc_BACK_FACING: val=104', - ' kworker/u:0-5 [000] .... 79.046880: ' + - 'mali_hwc_COMPUTE_ACTIVE: val=17462', - ' kworker/u:0-5 [000] .... 79.046884: ' + - 'mali_hwc_COMPUTE_CYCLES_DESC: val=3933', - ' kworker/u:0-5 [000] .... 79.046881: ' + - 'mali_hwc_COMPUTE_TASKS: val=15', - ' kworker/u:0-5 [000] .... 79.046883: ' + - 'mali_hwc_COMPUTE_THREADS: val=60', - ' kworker/u:0-5 [000] .... 79.046860: ' + - 'mali_hwc_FRAG_ACTIVE: val=690986', - ' kworker/u:0-5 [000] .... 79.046864: ' + - 'mali_hwc_FRAG_CYCLE_DESC: val=13980', - ' kworker/u:0-5 [000] .... 79.046876: ' + - 'mali_hwc_FRAG_CYCLE_NO_TILE: val=3539', - ' kworker/u:0-5 [000] .... 79.046865: ' + - 'mali_hwc_FRAG_CYCLES_PLR: val=1499', - ' kworker/u:0-5 [000] .... 79.046869: ' + - 'mali_hwc_FRAG_CYCLES_RAST: val=1999', - ' kworker/u:0-5 [000] .... 79.046868: ' + - 'mali_hwc_FRAG_CYCLES_TRISETUP: val=22353', - ' kworker/u:0-5 [000] .... 79.046867: ' + - 'mali_hwc_FRAG_CYCLES_VERT: val=20763', - ' kworker/u:0-5 [000] .... 79.046872: ' + - 'mali_hwc_FRAG_DUMMY_THREADS: val=1968', - ' kworker/u:0-5 [000] .... 79.046877: ' + - 'mali_hwc_FRAG_NUM_TILES: val=1840', - ' kworker/u:0-5 [000] .... 79.046862: ' + - 'mali_hwc_FRAG_PRIMATIVES: val=3752', - ' kworker/u:0-5 [000] .... 79.046863: ' + - 'mali_hwc_FRAG_PRIMATIVES_DROPPED: val=18', - ' kworker/u:0-5 [000] .... 79.046874: ' + - 'mali_hwc_FRAG_QUADS_EZS_TEST: val=117925', - ' kworker/u:0-5 [000] .... 79.046873: ' + - 'mali_hwc_FRAG_QUADS_RAST: val=117889', - ' kworker/u:0-5 [000] .... 79.046870: ' + - 'mali_hwc_FRAG_THREADS: val=471507', - ' kworker/u:0-5 [000] .... 79.046879: ' + - 'mali_hwc_FRAG_TRANS_ELIM: val=687', - ' kworker/u:0-5 [000] .... 80.315162: ' + - 'mali_hwc_FRONT_FACING: val=56', - ' kworker/u:0-5 [000] .... 78.896582: ' + - 'mali_hwc_GPU_ACTIVE: val=1316', - ' kworker/u:0-5 [000] .... 78.896584: ' + - 'mali_hwc_IRQ_ACTIVE: val=17', - ' kworker/u:0-5 [000] .... 79.046834: ' + - 'mali_hwc_JS0_ACTIVE: val=709444', - ' kworker/u:0-5 [000] .... 79.046831: ' + - 'mali_hwc_JS0_JOBS: val=2', - ' kworker/u:0-5 [000] .... 79.046832: ' + - 'mali_hwc_JS0_TASKS: val=7263', - ' kworker/u:0-5 [000] .... 79.046836: ' + - 'mali_hwc_JS0_WAIT_DEPEND: val=665876', - ' kworker/u:0-5 [000] .... 79.046835: ' + - 'mali_hwc_JS0_WAIT_ISSUE: val=910', - ' kworker/u:0-5 [000] .... 79.046840: ' + - 'mali_hwc_JS1_ACTIVE: val=153980', - ' kworker/u:0-5 [000] .... 79.046838: ' + - 'mali_hwc_JS1_JOBS: val=133', - ' kworker/u:0-5 [000] .... 79.046839: ' + - 'mali_hwc_JS1_TASKS: val=128', - ' kworker/u:0-5 [000] .... 79.046843: ' + - 'mali_hwc_JS1_WAIT_FINISH: val=74404', - ' kworker/u:0-5 [000] .... 79.046842: ' + - 'mali_hwc_JS1_WAIT_ISSUE: val=10146', - ' kworker/u:0-5 [000] .... 78.896603: ' + - 'mali_hwc_L2_ANY_LOOKUP: val=22', - ' kworker/u:0-5 [000] .... 79.046942: ' + - 'mali_hwc_L2_CLEAN_MISS: val=116', - ' kworker/u:0-5 [000] .... 79.063515: ' + - 'mali_hwc_L2_EXT_AR_STALL: val=9', - ' kworker/u:0-5 [000] .... 78.963384: ' + - 'mali_hwc_L2_EXT_BARRIER: val=1', - ' kworker/u:0-5 [000] .... 79.063516: ' + - 'mali_hwc_L2_EXT_R_BUF_FULL: val=43', - ' kworker/u:0-5 [000] .... 78.896611: ' + - 'mali_hwc_L2_EXT_READ: val=4', - ' kworker/u:0-5 [000] .... 78.896612: ' + - 'mali_hwc_L2_EXT_READ_LINE: val=4', - ' kworker/u:0-5 [000] .... 79.046956: ' + - 'mali_hwc_L2_EXT_R_RAW: val=1', - ' kworker/u:0-5 [000] .... 79.063518: ' + - 'mali_hwc_L2_EXT_R_W_HAZARD: val=15', - ' kworker/u:0-5 [000] .... 78.963381: ' + - 'mali_hwc_L2_EXT_WRITE: val=25', - ' kworker/u:0-5 [000] .... 79.046952: ' + - 'mali_hwc_L2_EXT_WRITE_LINE: val=63278', - ' kworker/u:0-5 [000] .... 78.963382: ' + - 'mali_hwc_L2_EXT_WRITE_SMALL: val=1', - ' kworker/u:0-5 [000] .... 79.814532: ' + - 'mali_hwc_L2_EXT_W_STALL: val=9', - ' kworker/u:0-5 [000] .... 78.896602: ' + - 'mali_hwc_L2_READ_BEATS: val=16', - ' kworker/u:0-5 [000] .... 78.896607: ' + - 'mali_hwc_L2_READ_HIT: val=11', - ' kworker/u:0-5 [000] .... 78.896604: ' + - 'mali_hwc_L2_READ_LOOKUP: val=19', - ' kworker/u:0-5 [000] .... 78.896606: ' + - 'mali_hwc_L2_READ_REPLAY: val=2', - ' kworker/u:0-5 [000] .... 79.046940: ' + - 'mali_hwc_L2_READ_SNOOP: val=24', - ' kworker/u:0-5 [000] .... 79.046959: ' + - 'mali_hwc_L2_REPLAY_FULL: val=6629', - ' kworker/u:0-5 [000] .N.. 80.565684: ' + - 'mali_hwc_L2_SNOOP_FULL: val=5', - ' kworker/u:0-5 [000] .... 79.046937: ' + - 'mali_hwc_L2_SREAD_LOOKUP: val=241', - ' kworker/u:0-5 [000] .... 79.046944: ' + - 'mali_hwc_L2_SWRITE_LOOKUP: val=133', - ' kworker/u:0-5 [000] .... 78.896614: ' + - 'mali_hwc_L2_TAG_HAZARD: val=4', - ' kworker/u:0-5 [000] .... 78.963368: ' + - 'mali_hwc_L2_WRITE_BEATS: val=96', - ' kworker/u:0-5 [000] .... 79.046947: ' + - 'mali_hwc_L2_WRITE_HIT: val=78265', - ' kworker/u:0-5 [000] .... 78.896608: ' + - 'mali_hwc_L2_WRITE_LOOKUP: val=3', - ' kworker/u:0-5 [000] .... 79.046946: ' + - 'mali_hwc_L2_WRITE_REPLAY: val=15879', - ' kworker/u:0-5 [000] .... 79.046912: ' + - 'mali_hwc_LSC_LINE_FETCHES: val=15', - ' kworker/u:0-5 [000] .... 79.046909: ' + - 'mali_hwc_LSC_READ_HITS: val=2961', - ' kworker/u:0-5 [000] .... 79.046911: ' + - 'mali_hwc_LSC_READ_MISSES: val=22', - ' kworker/u:0-5 [000] .... 79.046914: ' + - 'mali_hwc_LSC_SNOOPS: val=10', - ' kworker/u:0-5 [000] .... 79.046893: ' + - 'mali_hwc_LS_ISSUES: val=524219', - ' kworker/u:0-5 [000] .... 79.046894: ' + - 'mali_hwc_LS_REISSUES_MISS: val=439', - ' kworker/u:0-5 [000] .... 79.046895: ' + - 'mali_hwc_LS_REISSUES_VD: val=52007', - ' kworker/u:0-5 [000] .... 79.046919: ' + - 'mali_hwc_LS_TLB_HIT: val=3043', - ' kworker/u:0-5 [000] .... 79.046918: ' + - 'mali_hwc_LS_TLB_MISS: val=5', - ' kworker/u:0-5 [000] .... 79.046891: ' + - 'mali_hwc_LS_WORDS: val=471514', - ' kworker/u:0-5 [000] .... 79.046925: ' + - 'mali_hwc_MMU_HIT: val=771', - ' kworker/u:0-5 [000] .... 79.046924: ' + - 'mali_hwc_MMU_NEW_MISS: val=494', - ' kworker/u:0-5 [000] .... 79.046922: ' + - 'mali_hwc_MMU_REPLAY_MISS: val=841', - ' kworker/u:0-5 [000] .... 79.046921: ' + - 'mali_hwc_MMU_TABLE_WALK: val=3119', - ' kworker/u:0-5 [000] .... 79.046848: ' + - 'mali_hwc_POINTS: val=5', - ' kworker/u:0-5 [000] .... 79.046856: ' + - 'mali_hwc_PRIM_CLIPPED: val=70', - ' kworker/u:0-5 [000] .... 79.046855: ' + - 'mali_hwc_PRIM_CULLED: val=26', - ' kworker/u:0-5 [000] .... 79.046854: ' + - 'mali_hwc_PRIM_VISIBLE: val=109', - ' kworker/u:0-5 [000] .... 79.046898: ' + - 'mali_hwc_TEX_BUBBLES: val=24874', - ' kworker/u:0-5 [000] .... 79.046905: ' + - 'mali_hwc_TEX_RECIRC_DESC: val=5937', - ' kworker/u:0-5 [000] .... 79.046904: ' + - 'mali_hwc_TEX_RECIRC_FMISS: val=209450', - ' kworker/u:0-5 [000] .... 78.896592: ' + - 'mali_hwc_TEX_RECIRC_MULTI: val=238', - ' kworker/u:0-5 [000] .... 79.046908: ' + - 'mali_hwc_TEX_RECIRC_PMISS: val=9672', - ' kworker/u:0-5 [000] .... 79.046903: ' + - 'mali_hwc_TEX_THREADS: val=660900', - ' kworker/u:0-5 [000] .... 79.046897: ' + - 'mali_hwc_TEX_WORDS: val=471193', - ' kworker/u:0-5 [000] .... 79.046901: ' + - 'mali_hwc_TEX_WORDS_DESC: val=707', - ' kworker/u:0-5 [000] .... 79.046900: ' + - 'mali_hwc_TEX_WORDS_L0: val=32', - ' kworker/u:0-5 [000] .... 79.046846: ' + - 'mali_hwc_TRIANGLES: val=130', - ' kworker/u:0-5 [000] .... 79.046885: ' + - 'mali_hwc_TRIPIPE_ACTIVE: val=691001', - ' kworker/u:0-5 [000] .... 78.896600: ' + - 'mali_hwc_UTLB_NEW_MISS: val=6', - ' kworker/u:0-5 [000] .... 78.896599: ' + - 'mali_hwc_UTLB_REPLAY_FULL: val=248', - ' kworker/u:0-5 [000] .... 78.896597: ' + - 'mali_hwc_UTLB_REPLAY_MISS: val=1', - ' kworker/u:0-5 [000] .... 78.896596: ' + - 'mali_hwc_UTLB_STALL: val=1', - ' kworker/u:0-5 [000] .... 79.046850: ' + - 'mali_hwc_VCACHE_HIT: val=311', - ' kworker/u:0-5 [000] .... 79.046851: ' + - 'mali_hwc_VCACHE_MISS: val=70' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var counters = m.getAllCounters(); - assert.equal(counters.length, 103); - - // all counters should have 1 sample - for (var tI = 0; tI < counters.length; tI++) { - var counter = counters[tI]; - assert.equal(counter.series[0].samples.length, 1); - } - // TODO(sleffler) verify counter names? (not sure if it's worth the effort) - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/memreclaim_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/memreclaim_parser.html deleted file mode 100644 index c4b7f57f844..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/memreclaim_parser.html +++ /dev/null @@ -1,155 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses drm driver events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux vmscan trace events. - * @constructor - */ - function MemReclaimParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('mm_vmscan_kswapd_wake', - MemReclaimParser.prototype.kswapdWake.bind(this)); - importer.registerEventHandler('mm_vmscan_kswapd_sleep', - MemReclaimParser.prototype.kswapdSleep.bind(this)); - importer.registerEventHandler('mm_vmscan_direct_reclaim_begin', - MemReclaimParser.prototype.reclaimBegin.bind(this)); - importer.registerEventHandler('mm_vmscan_direct_reclaim_end', - MemReclaimParser.prototype.reclaimEnd.bind(this)); - } - - // Matches the mm_vmscan_kswapd_wake record - // mm_vmscan_kswapd_wake: nid=%d order=%d - var kswapdWakeRE = /nid=(\d+) order=(\d+)/; - - // Matches the mm_vmscan_kswapd_sleep record - // mm_vmscan_kswapd_sleep: order=%d - var kswapdSleepRE = /nid=(\d+)/; - - // Matches the mm_vmscan_direct_reclaim_begin record - // mm_vmscan_direct_reclaim_begin: order=%d may_writepage=%d gfp_flags=%s - var reclaimBeginRE = /order=(\d+) may_writepage=\d+ gfp_flags=(.+)/; - - // Matches the mm_vmscan_direct_reclaim_end record - // mm_vmscan_direct_reclaim_end: nr_reclaimed=%lu - var reclaimEndRE = /nr_reclaimed=(\d+)/; - - MemReclaimParser.prototype = { - __proto__: Parser.prototype, - - /** - * Parses memreclaim events and sets up state in the importer. - */ - kswapdWake: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = kswapdWakeRE.exec(eventBase.details); - if (!event) - return false; - - var tgid = parseInt(eventBase.tgid); - - var nid = parseInt(event[1]); - var order = parseInt(event[2]); - - var kthread = this.importer.getOrCreateKernelThread( - eventBase.threadName, tgid, pid); - - if (kthread.openSliceTS) { - if (order > kthread.order) { - kthread.order = order; - } - } else { - kthread.openSliceTS = ts; - kthread.order = order; - } - return true; - }, - - kswapdSleep: function(eventName, cpuNumber, pid, ts, eventBase) { - var tgid = parseInt(eventBase.tgid); - - var kthread = this.importer.getOrCreateKernelThread( - eventBase.threadName, tgid, pid); - - if (kthread.openSliceTS) { - - kthread.thread.sliceGroup.pushCompleteSlice( - 'memreclaim', eventBase.threadName, kthread.openSliceTS, - ts - kthread.openSliceTS, 0, 0, - { - order: kthread.order - }); - } - kthread.openSliceTS = undefined; - kthread.order = undefined; - return true; - }, - - reclaimBegin: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = reclaimBeginRE.exec(eventBase.details); - if (!event) - return false; - - var order = parseInt(event[1]); - var gfp = event[2]; - var tgid = parseInt(eventBase.tgid); - - var kthread = this.importer.getOrCreateKernelThread( - eventBase.threadName, tgid, pid); - - kthread.openSliceTS = ts; - kthread.order = order; - kthread.gfp = gfp; - return true; - }, - - reclaimEnd: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = reclaimEndRE.exec(eventBase.details); - if (!event) - return false; - - var nr_reclaimed = parseInt(event[1]); - var tgid = parseInt(eventBase.tgid); - - var kthread = this.importer.getOrCreateKernelThread( - eventBase.threadName, tgid, pid); - - if (kthread.openSliceTS !== undefined) { - kthread.thread.sliceGroup.pushCompleteSlice('memreclaim', - 'direct reclaim', kthread.openSliceTS, ts - kthread.openSliceTS, - 0, 0, - { - order: kthread.order, - gfp: kthread.gfp, - nr_reclaimed: nr_reclaimed - }); - } - kthread.openSliceTS = undefined; - kthread.order = undefined; - kthread.gfp = undefined; - return true; - } - - }; - - Parser.register(MemReclaimParser); - - return { - MemReclaimParser: MemReclaimParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/memreclaim_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/memreclaim_parser_test.html deleted file mode 100644 index f6a10ecf47e..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/memreclaim_parser_test.html +++ /dev/null @@ -1,170 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('memreclaimImport', function() { - var lines = [ - ' surfaceflinger-1155 ( 1155) [001] ...1 12839.528756: mm_vmscan_direct_reclaim_begin: order=0 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|GFP_ZERO|0x2', // @suppress longLineCheck - ' surfaceflinger-1155 ( 1155) [001] ...1 12839.531950: mm_vmscan_direct_reclaim_end: nr_reclaimed=66', // @suppress longLineCheck - ' kswapd0-33 ( 33) [001] ...1 12838.491407: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - ' kswapd0-33 ( 33) [001] ...1 12838.529770: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - ' kswapd0-33 ( 33) [001] ...1 12840.545737: mm_vmscan_kswapd_sleep: nid=0'// @suppress longLineCheck - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - assert.equal(m.processes['1155'].threads['1155'].sliceGroup.length, 1); - assert.equal(m.processes['33'].threads['33'].sliceGroup.length, 1); - }); - - test('memreclaimDirectReclaim', function() { - var lines = [ - 'RenderThread-9844 ( 9786) [001] ...1 1734.106078: mm_vmscan_direct_reclaim_begin: order=5 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|0x2', // @suppress longLineCheck - 'RenderThread-9844 ( 9786) [001] ...1 1734.107619: mm_vmscan_direct_reclaim_end: nr_reclaimed=72', // @suppress longLineCheck - 'RenderThread-9844 ( 9786) [001] ...1 1734.107738: mm_vmscan_direct_reclaim_begin: order=4 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|0x2', // @suppress longLineCheck - 'RenderThread-9844 ( 9786) [001] ...1 1734.107844: mm_vmscan_direct_reclaim_end: nr_reclaimed=35', // @suppress longLineCheck - 'RenderThread-9844 ( 9786) [001] ...1 1734.107891: mm_vmscan_direct_reclaim_begin: order=4 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|0x2', // @suppress longLineCheck - 'RenderThread-9844 ( 9786) [001] ...1 1734.107945: mm_vmscan_direct_reclaim_end: nr_reclaimed=35', // @suppress longLineCheck - 'RenderThread-9844 ( 9786) [001] ...1 1734.107990: mm_vmscan_direct_reclaim_begin: order=4 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|0x2', // @suppress longLineCheck - 'RenderThread-9844 ( 9786) [001] ...1 1734.108062: mm_vmscan_direct_reclaim_end: nr_reclaimed=34', // @suppress longLineCheck - 'Binder_8-1735 ( 1022) [001] ...1 1735.472240: mm_vmscan_direct_reclaim_begin: order=3 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|0x2', // @suppress longLineCheck - 'Binder_8-1735 ( 1022) [001] ...1 1735.472849: mm_vmscan_direct_reclaim_end: nr_reclaimed=47', // @suppress longLineCheck - 'Binder_8-1735 ( 1022) [001] ...1 1735.473002: mm_vmscan_direct_reclaim_begin: order=3 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|0x2', // @suppress longLineCheck - 'Binder_8-1735 ( 1022) [001] ...1 1735.474859: mm_vmscan_direct_reclaim_end: nr_reclaimed=48', // @suppress longLineCheck - 'touch_fusion-88 ( 88) [000] ...1 1736.510656: mm_vmscan_direct_reclaim_begin: order=2 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|GFP_COMP|GFP_NOMEMALLOC|GFP_KMEMCG', // @suppress longLineCheck - 'touch_fusion-88 ( 88) [000] ...1 1736.517616: mm_vmscan_direct_reclaim_end: nr_reclaimed=34', // @suppress longLineCheck - 'touch_fusion-88 ( 88) [000] ...1 1736.527061: mm_vmscan_direct_reclaim_begin: order=2 may_writepage=1 gfp_flags=GFP_KERNEL|GFP_NOWARN|GFP_COMP|GFP_NOMEMALLOC|GFP_KMEMCG', // @suppress longLineCheck - 'touch_fusion-88 ( 88) [000] ...1 1736.530857: mm_vmscan_direct_reclaim_end: nr_reclaimed=39'// @suppress longLineCheck - ]; - - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - - assert.equal(threads.length, 3); - - var Binder_8 = threads[0]; - var touch_fusion = threads[1]; - var RenderThread = threads[2]; - - /* make sure there are the expected amount of slices per thread */ - assert.equal(Binder_8.sliceGroup.length, 2); - assert.equal(touch_fusion.sliceGroup.length, 2); - assert.equal(RenderThread.sliceGroup.length, 4); - - /* make sure the slices have information to display to the - * user when selected - */ - - var iterate_me = [Binder_8, touch_fusion, RenderThread]; - iterate_me.forEach(function(thread) { - for (var i = 0; i < thread.sliceGroup.length; i++) { - assert.equal(thread.sliceGroup.slices[i].args !== undefined, true); - } - }); - }); - - test('memreclaimKswapd', function() { - var lines = [ - 'kswapd0-48 ( 48) [001] ...1 1734.210437: mm_vmscan_kswapd_wake: nid=0 order=5', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.227291: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.237585: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.258698: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.269642: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.319484: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.344839: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.428425: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.429593: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.599419: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1734.696606: mm_vmscan_kswapd_sleep: nid=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1735.465745: mm_vmscan_kswapd_wake: nid=0 order=3', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1735.563917: mm_vmscan_kswapd_wake: nid=0 order=5', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1735.570555: mm_vmscan_kswapd_wake: nid=0 order=4', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1735.666658: mm_vmscan_kswapd_sleep: nid=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1736.508069: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1736.529293: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1736.696725: mm_vmscan_kswapd_sleep: nid=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1737.945426: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1737.988642: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.057237: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.144630: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.207546: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.221963: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.316889: mm_vmscan_kswapd_sleep: nid=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.712804: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.751103: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.773175: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.785068: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.789545: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1738.873675: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1738.899117: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1738.939214: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1738.990366: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1739.028269: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1739.036765: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1739.077631: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.094731: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.096757: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.160536: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.256638: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.264972: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1739.360137: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.368759: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.387082: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.455657: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.489058: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.507561: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.570247: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [001] ...1 1739.582975: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.678148: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.762025: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.799245: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.821950: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.894130: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1739.919775: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.026933: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.126608: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.150819: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.156101: mm_vmscan_kswapd_wake: nid=0 order=1', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.246626: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.357055: mm_vmscan_kswapd_sleep: nid=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.762705: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.772367: mm_vmscan_kswapd_wake: nid=0 order=2', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.783509: mm_vmscan_kswapd_wake: nid=0 order=0', // @suppress longLineCheck - 'kswapd0-48 ( 48) [000] ...1 1740.876601: mm_vmscan_kswapd_sleep: nid=0'// @suppress longLineCheck - ]; - - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 1); - - var thread = threads[0]; - - assert.equal(thread.sliceGroup.length, 6); - - thread.sliceGroup.slices.forEach(function(slice) { - assert.equal(slice.args !== undefined, true); - }); - }); - -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/parser.html deleted file mode 100644 index dd64d06b69d..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/parser.html +++ /dev/null @@ -1,90 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/base/base.html"> -<link rel="import" href="/tracing/base/extension_registry.html"> -<script> -'use strict'; - -/** - * @fileoverview Base class for linux perf event parsers. - * - * The linux perf trace event importer depends on subclasses of - * Parser to parse event data. Each subclass corresponds - * to a group of trace events; e.g. SchedParser implements - * parsing of sched:* kernel trace events. Parser subclasses must - * call Parser.register to arrange to be instantiated - * and their constructor must register their event handlers with the - * importer. For example, - * - * var Parser = tr.e.importer.linux_perf.Parser; - * - * function WorkqueueParser(importer) { - * Parser.call(this, importer); - * - * importer.registerEventHandler('workqueue_execute_start', - * WorkqueueParser.prototype.executeStartEvent.bind(this)); - * importer.registerEventHandler('workqueue_execute_end', - * WorkqueueParser.prototype.executeEndEvent.bind(this)); - * } - * - * Parser.register(WorkqueueParser); - * - * When a registered event name is found in the data stream the associated - * event handler is invoked: - * - * executeStartEvent: function(eventName, cpuNumber, ts, eventBase) - * - * If the routine returns false the caller will generate an import error - * saying there was a problem parsing it. Handlers can also emit import - * messages using this.importer.model.importWarning. If this is done in lieu of - * the generic import error it may be desirable for the handler to return - * true. - * - * Trace events generated by writing to the trace_marker file are expected - * to have a leading text marker followed by a ':'; e.g. the trace clock - * synchronization event is: - * - * tracing_mark_write: trace_event_clock_sync: parent_ts=0 - * - * To register an event handler for these events, prepend the marker with - * 'tracing_mark_write:'; e.g. - * - * this.registerEventHandler('tracing_mark_write:trace_event_clock_sync', - * - * All subclasses should depend on importer.linux_perf.parser, e.g. - * - * tr.defineModule('importer.linux_perf.workqueue_parser') - * .dependsOn('importer.linux_perf.parser') - * .exportsTo('tracing', function() - * - * and be listed in the dependsOn of FTraceImporter. Beware that after adding a - * new subclass you must run build/generate_about_tracing_contents.py to - * regenerate tr.ui.e.about_tracing.*. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - /** - * Parses linux perf events. - * @constructor - */ - function Parser(importer) { - this.importer = importer; - this.model = importer.model; - } - - Parser.prototype = { - __proto__: Object.prototype - }; - - var options = new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE); - options.mandatoryBaseClass = Parser; - tr.b.decorateExtensionRegistry(Parser, options); - - return { - Parser: Parser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/power_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/power_parser.html deleted file mode 100644 index c6d01a26d05..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/power_parser.html +++ /dev/null @@ -1,183 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> -<link rel="import" href="/tracing/model/counter_series.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses power events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux power trace events. - * @constructor - */ - function PowerParser(importer) { - Parser.call(this, importer); - - // NB: old-style power events, deprecated - importer.registerEventHandler('power_start', - PowerParser.prototype.powerStartEvent.bind(this)); - importer.registerEventHandler('power_frequency', - PowerParser.prototype.powerFrequencyEvent.bind(this)); - - importer.registerEventHandler('cpu_frequency', - PowerParser.prototype.cpuFrequencyEvent.bind(this)); - importer.registerEventHandler('cpu_frequency_limits', - PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this)); - importer.registerEventHandler('cpu_idle', - PowerParser.prototype.cpuIdleEvent.bind(this)); - } - - PowerParser.prototype = { - __proto__: Parser.prototype, - - cpuStateSlice: function(ts, targetCpuNumber, eventType, cpuState) { - var targetCpu = this.importer.getOrCreateCpu(targetCpuNumber); - var powerCounter; - if (eventType != '1') { - this.importer.model.importWarning({ - type: 'parse_error', - message: 'Don\'t understand power_start events of ' + - 'type ' + eventType - }); - return; - } - powerCounter = targetCpu.getOrCreateCounter('', 'C-State'); - if (powerCounter.numSeries === 0) { - powerCounter.addSeries(new tr.model.CounterSeries('state', - ColorScheme.getColorIdForGeneralPurposeString( - powerCounter.name + '.' + 'state'))); - } - powerCounter.series.forEach(function(series) { - series.addCounterSample(ts, cpuState); - }); - }, - - cpuIdleSlice: function(ts, targetCpuNumber, cpuState) { - var targetCpu = this.importer.getOrCreateCpu(targetCpuNumber); - var powerCounter = targetCpu.getOrCreateCounter('', 'C-State'); - if (powerCounter.numSeries === 0) { - powerCounter.addSeries(new tr.model.CounterSeries('state', - ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name))); - } - // NB: 4294967295/-1 means an exit from the current state - var val = (cpuState != 4294967295 ? cpuState + 1 : 0); - powerCounter.series.forEach(function(series) { - series.addCounterSample(ts, val); - }); - }, - - cpuFrequencySlice: function(ts, targetCpuNumber, powerState) { - var targetCpu = this.importer.getOrCreateCpu(targetCpuNumber); - var powerCounter = - targetCpu.getOrCreateCounter('', 'Clock Frequency'); - if (powerCounter.numSeries === 0) { - powerCounter.addSeries(new tr.model.CounterSeries('state', - ColorScheme.getColorIdForGeneralPurposeString( - powerCounter.name + '.' + 'state'))); - } - powerCounter.series.forEach(function(series) { - series.addCounterSample(ts, powerState); - }); - }, - - cpuFrequencyLimitsSlice: function(ts, targetCpuNumber, minFreq, maxFreq) { - var targetCpu = this.importer.getOrCreateCpu(targetCpuNumber); - var powerCounter = - targetCpu.getOrCreateCounter('', 'Clock Frequency Limits'); - if (powerCounter.numSeries === 0) { - powerCounter.addSeries(new tr.model.CounterSeries('Min Frequency', - ColorScheme.getColorIdForGeneralPurposeString( - powerCounter.name + '.' + 'Min Frequency'))); - powerCounter.addSeries(new tr.model.CounterSeries('Max Frequency', - ColorScheme.getColorIdForGeneralPurposeString( - powerCounter.name + '.' + 'Max Frequency'))); - } - powerCounter.series.forEach(function(series) { - if (series.name == 'Min Frequency') - series.addCounterSample(ts, minFreq); - if (series.name == 'Max Frequency') - series.addCounterSample(ts, maxFreq); - }); - }, - - /** - * Parses power events and sets up state in the importer. - */ - powerStartEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /type=(\d+) state=(\d) cpu_id=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var targetCpuNumber = parseInt(event[3]); - var cpuState = parseInt(event[2]); - this.cpuStateSlice(ts, targetCpuNumber, event[1], cpuState); - return true; - }, - - powerFrequencyEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /type=(\d+) state=(\d+) cpu_id=(\d+)/ - .exec(eventBase.details); - if (!event) - return false; - - var targetCpuNumber = parseInt(event[3]); - var powerState = parseInt(event[2]); - this.cpuFrequencySlice(ts, targetCpuNumber, powerState); - return true; - }, - - cpuFrequencyEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /state=(\d+) cpu_id=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var targetCpuNumber = parseInt(event[2]); - var powerState = parseInt(event[1]); - this.cpuFrequencySlice(ts, targetCpuNumber, powerState); - return true; - }, - - cpuFrequencyLimitsEvent: function(eventName, cpu, pid, ts, eventBase) { - var event = /min=(\d+) max=(\d+) cpu_id=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var targetCpuNumber = parseInt(event[3]); - var minFreq = parseInt(event[1]); - var maxFreq = parseInt(event[2]); - this.cpuFrequencyLimitsSlice(ts, targetCpuNumber, minFreq, maxFreq); - return true; - }, - - cpuIdleEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /state=(\d+) cpu_id=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var targetCpuNumber = parseInt(event[2]); - var cpuState = parseInt(event[1]); - this.cpuIdleSlice(ts, targetCpuNumber, cpuState); - return true; - } - }; - - Parser.register(PowerParser); - - return { - PowerParser: PowerParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/power_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/power_parser_test.html deleted file mode 100644 index 9dae21dcc9d..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/power_parser_test.html +++ /dev/null @@ -1,93 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('powerFrequencyImport', function() { - var lines = [ - ' kworker/0:3-6880 [000] 2784.783015: power_frequency: ' + - 'type=2 state=1000000 cpu_id=0', - ' kworker/1:2-7269 [001] 2784.788993: power_frequency: ' + - 'type=2 state=800000 cpu_id=1', - ' kworker/1:2-7269 [001] 2784.993120: power_frequency: ' + - 'type=2 state=1300000 cpu_id=1' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c0 = m.kernel.cpus[0]; - assert.equal(c0.slices.length, 0); - assert.equal(c0.counters['.Clock Frequency'].series[0].samples.length, 1); - - var c1 = m.kernel.cpus[1]; - assert.equal(c1.slices.length, 0); - assert.equal(c1.counters['.Clock Frequency'].series[0].samples.length, 2); - }); - - test('cpuFrequencyImport', function() { - var lines = [ - ' kworker/1:0-9665 [001] 15051.007301: cpu_frequency: ' + - 'state=800000 cpu_id=1', - ' kworker/1:0-9665 [001] 15051.010278: cpu_frequency: ' + - 'state=1300000 cpu_id=1', - ' kworker/0:2-7972 [000] 15051.010278: cpu_frequency: ' + - 'state=1000000 cpu_id=0', - ' kworker/0:2-7972 [000] 15051.020304: cpu_frequency: ' + - 'state=800000 cpu_id=0' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c0 = m.kernel.cpus[0]; - assert.equal(c0.slices.length, 0); - assert.equal(c0.counters['.Clock Frequency'].series[0].samples.length, 2); - - var c1 = m.kernel.cpus[1]; - assert.equal(c1.slices.length, 0); - assert.equal(c1.counters['.Clock Frequency'].series[0].samples.length, 2); - }); - - test('cpuIdleImport', function() { - var lines = [ - ' <idle>-0 [000] 15050.992883: cpu_idle: ' + - 'state=1 cpu_id=0', - ' <idle>-0 [000] 15050.993027: cpu_idle: ' + - 'state=4294967295 cpu_id=0', - ' <idle>-0 [001] 15050.993132: cpu_idle: ' + - 'state=1 cpu_id=1', - ' <idle>-0 [001] 15050.993276: cpu_idle: ' + - 'state=4294967295 cpu_id=1', - ' <idle>-0 [001] 15050.993279: cpu_idle: ' + - 'state=3 cpu_id=1', - ' <idle>-0 [001] 15050.993457: cpu_idle: ' + - 'state=4294967295 cpu_id=1' - ]; - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var c0 = m.kernel.cpus[0]; - assert.equal(c0.slices.length, 0); - assert.equal(c0.counters['.C-State'].series[0].samples.length, 2); - - var c1 = m.kernel.cpus[1]; - assert.equal(c1.slices.length, 0); - assert.equal(c1.counters['.C-State'].series[0].samples.length, 4); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/regulator_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/regulator_parser.html deleted file mode 100644 index 0c56720f51c..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/regulator_parser.html +++ /dev/null @@ -1,143 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses regulator events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux regulator trace events. - * @constructor - */ - function RegulatorParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('regulator_enable', - RegulatorParser.prototype.regulatorEnableEvent.bind(this)); - importer.registerEventHandler('regulator_enable_delay', - RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this)); - importer.registerEventHandler('regulator_enable_complete', - RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this)); - importer.registerEventHandler('regulator_disable', - RegulatorParser.prototype.regulatorDisableEvent.bind(this)); - importer.registerEventHandler('regulator_disable_complete', - RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this)); - importer.registerEventHandler('regulator_set_voltage', - RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this)); - importer.registerEventHandler('regulator_set_voltage_complete', - RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this)); - - this.model_ = importer.model_; - } - - // Matches the regulator_enable record - var regulatorEnableRE = /name=(.+)/; - - // Matches the regulator_disable record - var regulatorDisableRE = /name=(.+)/; - - // Matches the regulator_set_voltage_complete record - var regulatorSetVoltageCompleteRE = /name=(\S+), val=(\d+)/; - - RegulatorParser.prototype = { - __proto__: Parser.prototype, - - /** - * Get or create a counter with one series. - */ - getCtr_: function(ctrName, valueName) { - var ctr = this.model_.kernel - .getOrCreateCounter(null, 'vreg ' + ctrName + ' ' + valueName); - // Initialize the counter's series fields if needed. - if (ctr.series[0] === undefined) { - ctr.addSeries(new tr.model.CounterSeries(valueName, - ColorScheme.getColorIdForGeneralPurposeString( - ctrName + '.' + valueName))); - } - return ctr; - }, - - /** - * Parses regulator events and sets up state in the importer. - */ - regulatorEnableEvent: function(eventName, cpuNum, pid, ts, eventBase) { - var event = regulatorEnableRE.exec(eventBase.details); - if (!event) - return false; - - var name = event[1]; - - var ctr = this.getCtr_(name, 'enabled'); - ctr.series[0].addCounterSample(ts, 1); - - return true; - }, - - regulatorEnableDelayEvent: function(eventName, cpuNum, pid, ts, eventBase) { - return true; - }, - - regulatorEnableCompleteEvent: function(eventName, cpuNum, pid, ts, - eventBase) { - return true; - }, - - regulatorDisableEvent: function(eventName, cpuNum, pid, ts, eventBase) { - var event = regulatorDisableRE.exec(eventBase.details); - if (!event) - return false; - - var name = event[1]; - - var ctr = this.getCtr_(name, 'enabled'); - ctr.series[0].addCounterSample(ts, 0); - - return true; - }, - - regulatorDisableCompleteEvent: function(eventName, cpuNum, pid, ts, - eventBase) { - return true; - }, - - regulatorSetVoltageEvent: function(eventName, cpuNum, pid, ts, eventBase) { - return true; - }, - - regulatorSetVoltageCompleteEvent: function(eventName, cpuNum, pid, ts, - eventBase) { - var event = regulatorSetVoltageCompleteRE.exec(eventBase.details); - if (!event) - return false; - - var name = event[1]; - var voltage = parseInt(event[2]); - - var ctr = this.getCtr_(name, 'voltage'); - ctr.series[0].addCounterSample(ts, voltage); - - return true; - } - - }; - - Parser.register(RegulatorParser); - - return { - RegulatorParser: RegulatorParser - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/regulator_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/regulator_parser_test.html deleted file mode 100644 index 328bf7c3161..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/regulator_parser_test.html +++ /dev/null @@ -1,45 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2015 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('regulatorImport', function() { - var lines = [ - ' kworker/0:2H-14312 [000] ...1 143713.787749: ' + - 'regulator_set_voltage: name=krait0 (810000-1100000)', - ' kworker/0:2H-14312 [000] ...1 143713.787778: ' + - 'regulator_set_voltage_complete: name=krait0, val=810000', - ' kworker/0:2H-14312 [000] ...1 143714.037871: ' + - 'regulator_set_voltage: name=krait0 (800000-1100000)', - ' kworker/0:2H-14312 [000] ...1 143714.037895: ' + - 'regulator_set_voltage_complete: name=krait0, val=800000', - 'kworker/0:1-30321 [000] ...1 144568.624596: ' + - 'regulator_enable: name=8941_smbb_boost', - 'kworker/0:1-30321 [000] ...1 144568.624715: ' + - 'regulator_enable_delay: name=8941_smbb_boost', - 'kworker/0:1-30321 [000] ...1 144568.624723: ' + - 'regulator_enable_complete: name=8941_smbb_boost', - 'kworker/0:1-30321 [000] ...1 144568.653546: ' + - 'regulator_disable: name=8941_smbb_boost', - 'kworker/0:1-30321 [000] ...1 144568.654785: ' + - 'regulator_disable_complete: name=8941_smbb_boost' - ]; - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - assert.property(m.kernel.counters, 'null.vreg krait0 voltage'); - assert.property(m.kernel.counters, 'null.vreg 8941_smbb_boost enabled'); - }); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sched_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sched_parser.html deleted file mode 100644 index 08ad46aed4b..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sched_parser.html +++ /dev/null @@ -1,150 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> -<link rel="import" href="/tracing/model/counter.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses scheduler events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux sched trace events. - * @constructor - */ - function SchedParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('sched_switch', - SchedParser.prototype.schedSwitchEvent.bind(this)); - importer.registerEventHandler('sched_wakeup', - SchedParser.prototype.schedWakeupEvent.bind(this)); - importer.registerEventHandler('sched_blocked_reason', - SchedParser.prototype.schedBlockedEvent.bind(this)); - importer.registerEventHandler('sched_cpu_hotplug', - SchedParser.prototype.schedCpuHotplugEvent.bind(this)); - } - - var TestExports = {}; - - // Matches the sched_switch record - var schedSwitchRE = new RegExp( - 'prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) ' + - 'prev_state=(\\S\\+?|\\S\\|\\S) ==> ' + - 'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)'); - - // Matches sched_blocked_reason record - var schedBlockedRE = new RegExp('pid=(\\d+) iowait=(\\d) caller=(.+)'); - TestExports.schedSwitchRE = schedSwitchRE; - - // Matches the sched_wakeup record - var schedWakeupRE = - /comm=(.+) pid=(\d+) prio=(\d+) success=(\d+) target_cpu=(\d+)/; - TestExports.schedWakeupRE = schedWakeupRE; - - SchedParser.prototype = { - __proto__: Parser.prototype, - - /** - * Parses scheduler events and sets up state in the CPUs of the importer. - */ - schedSwitchEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = schedSwitchRE.exec(eventBase.details); - if (!event) - return false; - - var prevState = event[4]; - var nextComm = event[5]; - var nextPid = parseInt(event[6]); - var nextPrio = parseInt(event[7]); - - var nextThread = this.importer.threadsByLinuxPid[nextPid]; - var nextName; - if (nextThread) - nextName = nextThread.userFriendlyName; - else - nextName = nextComm; - - var cpu = this.importer.getOrCreateCpu(cpuNumber); - cpu.switchActiveThread( - ts, - {stateWhenDescheduled: prevState}, - nextPid, - nextName, - { - comm: nextComm, - tid: nextPid, - prio: nextPrio - }); - - return true; - }, - - schedWakeupEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = schedWakeupRE.exec(eventBase.details); - if (!event) - return false; - - var fromPid = pid; - var comm = event[1]; - var pid = parseInt(event[2]); - var prio = parseInt(event[3]); - this.importer.markPidRunnable(ts, pid, comm, prio, fromPid); - return true; - }, - - schedCpuHotplugEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = /cpu (\d+) (.+) error=(\d+)/.exec(eventBase.details); - if (!event) - return false; - - var cpuNumber = event[1]; - var state = event[2]; - var targetCpu = this.importer.getOrCreateCpu(cpuNumber); - - var powerCounter = targetCpu.getOrCreateCounter('', 'Cpu Hotplug'); - if (powerCounter.numSeries === 0) { - powerCounter.addSeries(new tr.model.CounterSeries('State', - tr.b.ColorScheme.getColorIdForGeneralPurposeString( - powerCounter.name + '.' + 'State'))); - } - powerCounter.series.forEach(function(series) { - if (series.name == 'State') - series.addCounterSample(ts, state.localeCompare('offline') ? 0 : 1); - }); - return true; - }, - - schedBlockedEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = schedBlockedRE.exec(eventBase.details); - if (!event) - return false; - - var pid = parseInt(event[1]); - var iowait = parseInt(event[2]); - var caller = event[3]; - - this.importer.addPidBlockedReason(ts, pid, iowait, caller); - return true; - } - }; - - Parser.register(SchedParser); - - return { - SchedParser: SchedParser, - _SchedParserTestExports: TestExports - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sched_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sched_parser_test.html deleted file mode 100644 index 435463e5b43..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sched_parser_test.html +++ /dev/null @@ -1,222 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('schedSwitchRE', function() { - var re = tr.e.importer.linux_perf._SchedParserTestExports.schedSwitchRE; - var x = re.exec('prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ' + - '==> next_comm=SurfaceFlinger next_pid=178 next_prio=112'); - assert.isNotNull(x); - assert.equal(x[1], 'swapper'); - assert.equal(x[2], '0'); - assert.equal(x[3], '120'); - assert.equal(x[4], 'R'); - assert.equal(x[5], 'SurfaceFlinger'); - assert.equal(x[6], '178'); - assert.equal(x[7], '112'); - - var x = re.exec('prev_comm=.android.chrome prev_pid=1562 prev_prio=120 prev_state=R ==> next_comm=Binder Thread # next_pid=195 next_prio=120'); // @suppress longLineCheck - assert.isNotNull(x); - assert.equal(x[1], '.android.chrome'); - assert.equal(x[5], 'Binder Thread #'); - - var x = re.exec('prev_comm=Binder Thread # prev_pid=1562 prev_prio=120 prev_state=R ==> next_comm=.android.chrome next_pid=195 next_prio=120'); // @suppress longLineCheck - assert.isNotNull(x); - assert.equal(x[1], 'Binder Thread #'); - assert.equal(x[5], '.android.chrome'); - - // explicit test for prev_state of D|W - var x = re.exec('prev_comm=.android.chrome prev_pid=1562 prev_prio=120 ' + - 'prev_state=D|W ==> next_comm=Binder Thread # next_pid=195 ' + - 'next_prio=120'); - assert.isNotNull(x); - assert.equal(x[4], 'D|W'); - }); - - test('schedWakeupRE', function() { - var re = tr.e.importer.linux_perf._SchedParserTestExports.schedWakeupRE; - var x = re.exec( - 'comm=SensorService pid=207 prio=112 success=1 target_cpu=000'); - assert.isNotNull(x); - assert.equal(x[1], 'SensorService'); - assert.equal(x[2], '207'); - assert.equal(x[3], '112'); - assert.equal(x[4], '1'); - assert.equal(x[5], '000'); - }); - - test('importOneSequenceWithSchedWakeUp', function() { - var SCHEDULING_STATE = tr.model.SCHEDULING_STATE; - var lines = [ - 'ndroid.launcher-584 [001] d..3 12622.506890: sched_switch: prev_comm=ndroid.launcher prev_pid=584 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=217 next_prio=120', // @suppress longLineCheck - ' Binder_1-217 [001] d..3 12622.506918: sched_switch: prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=D ==> next_comm=ndroid.launcher next_pid=584 next_prio=120', // @suppress longLineCheck - 'ndroid.launcher-584 [001] d..4 12622.506936: sched_wakeup: comm=Binder_1 pid=217 prio=120 success=1 target_cpu=001', // @suppress longLineCheck - 'ndroid.launcher-584 [001] d..3 12622.506950: sched_switch: prev_comm=ndroid.launcher prev_pid=584 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=217 next_prio=120', // @suppress longLineCheck - ' Binder_1-217 [001] ...1 12622.507057: tracing_mark_write: B|128|queueBuffer', // @suppress longLineCheck - ' Binder_1-217 [001] ...1 12622.507175: tracing_mark_write: E', - ' Binder_1-217 [001] d..3 12622.507253: sched_switch: prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=S ==> next_comm=ndroid.launcher next_pid=584 next_prio=120' // @suppress longLineCheck - ]; - - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var thread = m.findAllThreadsNamed('Binder_1')[0]; - var timeSlices = thread.timeSlices; - assert.equal(timeSlices.length, 4); - - var runningSlice = timeSlices[0]; - assert.equal(runningSlice.schedulingState, SCHEDULING_STATE.RUNNING); - assert.closeTo(12622506.890, runningSlice.start, 1e-5); - assert.closeTo(.918 - .890, runningSlice.duration, 1e-5); - - var sleepSlice = timeSlices[1]; - assert.equal(sleepSlice.schedulingState, SCHEDULING_STATE.UNINTR_SLEEP); - assert.closeTo(12622506.918, sleepSlice.start, 1e-5); - assert.closeTo(.936 - .918, sleepSlice.duration, 1e-5); - - var wakeupSlice = timeSlices[2]; - assert.equal(wakeupSlice.schedulingState, SCHEDULING_STATE.RUNNABLE); - assert.closeTo(12622506.936, wakeupSlice.start, 1e-5); - assert.closeTo(.950 - .936, wakeupSlice.duration, 1e-5); - assert.equal(wakeupSlice.args['wakeup from tid'], 584); - - var runningSlice2 = timeSlices[3]; - assert.equal(runningSlice2.schedulingState, SCHEDULING_STATE.RUNNING); - assert.closeTo(12622506.950, runningSlice2.start, 1e-5); - assert.closeTo(7.253 - 6.950, runningSlice2.duration, 1e-5); - }); - - test('importWithUnknownSleepState', function() { - var SCHEDULING_STATE = tr.model.SCHEDULING_STATE; - var lines = [ - 'ndroid.launcher-584 [001] d..3 12622.506890: sched_switch: prev_comm=ndroid.launcher prev_pid=584 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=217 next_prio=120', // @suppress longLineCheck - ' Binder_1-217 [001] d..3 12622.506918: sched_switch: prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=F|O ==> next_comm=ndroid.launcher next_pid=584 next_prio=120', // @suppress longLineCheck - 'ndroid.launcher-584 [001] d..4 12622.506936: sched_wakeup: comm=Binder_1 pid=217 prio=120 success=1 target_cpu=001', // @suppress longLineCheck - 'ndroid.launcher-584 [001] d..3 12622.506950: sched_switch: prev_comm=ndroid.launcher prev_pid=584 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=217 next_prio=120', // @suppress longLineCheck - ' Binder_1-217 [001] ...1 12622.507057: tracing_mark_write: B|128|queueBuffer', // @suppress longLineCheck - ' Binder_1-217 [001] ...1 12622.507175: tracing_mark_write: E', - ' Binder_1-217 [001] d..3 12622.507253: sched_switch: prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=F|O ==> next_comm=ndroid.launcher next_pid=584 next_prio=120' // @suppress longLineCheck - ]; - - var m; - assert.doesNotThrow(function() { - m = newModel(lines.join('\n')); - }); - assert.isTrue(m.hasImportWarnings); - assert.equal(m.importWarnings[0].message, 'Unrecognized sleep state: F|O'); - - var thread = m.findAllThreadsNamed('Binder_1')[0]; - var timeSlices = thread.timeSlices; - - assert.equal(timeSlices[1].schedulingState, SCHEDULING_STATE.UNKNOWN); - }); - - test('importWithUninterruptibleSleep', function() { - var SCHEDULING_STATE = tr.model.SCHEDULING_STATE; - var lines = [ - 'ndroid.launcher-584 [001] d..3 12622.506890: sched_switch: ' + - 'prev_comm=ndroid.launcher prev_pid=584 ' + - 'prev_prio=120 prev_state=R+ ' + - '==> next_comm=Binder_1 next_pid=217 next_prio=120', - - ' Binder_1-217 [001] d..3 12622.506918: sched_switch: ' + - 'prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=D|K ' + - '==> next_comm=ndroid.launcher next_pid=584 next_prio=120', - - 'ndroid.launcher-584 [001] d..4 12622.506936: sched_wakeup: ' + - 'comm=Binder_1 pid=217 prio=120 success=1 target_cpu=001', - - 'ndroid.launcher-584 [001] d..3 12622.506950: sched_switch: ' + - 'prev_comm=ndroid.launcher prev_pid=584 ' + - 'prev_prio=120 prev_state=R+ ' + - '==> next_comm=Binder_1 next_pid=217 next_prio=120', - - ' Binder_1-217 [001] ...1 12622.507057: tracing_mark_write: ' + - 'B|128|queueBuffer', - - ' Binder_1-217 [001] ...1 12622.507175: tracing_mark_write: E', - - ' Binder_1-217 [001] d..3 12622.507253: sched_switch: ' + - 'prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=S ' + - '==> next_comm=ndroid.launcher next_pid=584 next_prio=120' - ]; - - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var thread = m.findAllThreadsNamed('Binder_1')[0]; - var timeSlices = thread.timeSlices; - assert.equal(timeSlices.length, 4); - - var wakeKillSlice = timeSlices[1]; - assert.equal(wakeKillSlice.schedulingState, - SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL); - assert.closeTo(12622506.918, wakeKillSlice.start, 1e-5); - assert.closeTo(.936 - .918, wakeKillSlice.duration, 1e-5); - }); - - test('importWithUninterruptibleSleepAndBlockedReason', function() { - var SCHEDULING_STATE = tr.model.SCHEDULING_STATE; - var lines = [ - 'ndroid.launcher-584 [001] d..3 12622.506890: sched_switch: ' + - 'prev_comm=ndroid.launcher prev_pid=584 ' + - 'prev_prio=120 prev_state=R+ ' + - '==> next_comm=Binder_1 next_pid=217 next_prio=120', - - ' Binder_1-217 [001] d..3 12622.506918: sched_switch: ' + - 'prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=D|K ' + - '==> next_comm=ndroid.launcher next_pid=584 next_prio=120', - - ' Binder_1-217 [001] d..3 12622.506930: sched_blocked_reason: ' + - 'pid=217 iowait=1 caller=sleep_on_page_killable+0x10/0x4c', - - 'ndroid.launcher-584 [001] d..4 12622.506936: sched_wakeup: ' + - 'comm=Binder_1 pid=217 prio=120 success=1 target_cpu=001', - - 'ndroid.launcher-584 [001] d..3 12622.506950: sched_switch: ' + - 'prev_comm=ndroid.launcher prev_pid=584 ' + - 'prev_prio=120 prev_state=R+ ' + - '==> next_comm=Binder_1 next_pid=217 next_prio=120', - - ' Binder_1-217 [001] ...1 12622.507057: tracing_mark_write: ' + - 'B|128|queueBuffer', - - ' Binder_1-217 [001] ...1 12622.507175: tracing_mark_write: E', - - ' Binder_1-217 [001] d..3 12622.507253: sched_switch: ' + - 'prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=S ' + - '==> next_comm=ndroid.launcher next_pid=584 next_prio=120' - ]; - - var m = newModel(lines.join('\n')); - assert.isFalse(m.hasImportWarnings); - - var thread = m.findAllThreadsNamed('Binder_1')[0]; - var timeSlices = thread.timeSlices; - assert.equal(timeSlices.length, 4); - - var wakeKillSlice = timeSlices[1]; - assert.equal(wakeKillSlice.schedulingState, - SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO); - assert.closeTo(12622506.918, wakeKillSlice.start, 1e-5); - assert.closeTo(.936 - .918, wakeKillSlice.duration, 1e-5); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sync_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sync_parser.html deleted file mode 100644 index ce6afe7179a..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sync_parser.html +++ /dev/null @@ -1,135 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses sync events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux sync trace events. - * @constructor - */ - function SyncParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler( - 'sync_timeline', - SyncParser.prototype.timelineEvent.bind(this)); - importer.registerEventHandler( - 'sync_wait', - SyncParser.prototype.syncWaitEvent.bind(this)); - importer.registerEventHandler( - 'sync_pt', - SyncParser.prototype.syncPtEvent.bind(this)); - this.model_ = importer.model_; - } - - var syncTimelineRE = /name=(\S+) value=(\S*)/; - var syncWaitRE = /(\S+) name=(\S+) state=(\d+)/; - var syncPtRE = /name=(\S+) value=(\S*)/; - - SyncParser.prototype = { - __proto__: Parser.prototype, - - /** - * Parses sync events and sets up state in the importer. - */ - timelineEvent: function(eventName, cpuNumber, pid, - ts, eventBase) { - var event = syncTimelineRE.exec(eventBase.details); - if (!event) - return false; - - var thread = this.importer.getOrCreatePseudoThread(event[1]); - - if (thread.lastActiveTs !== undefined) { - var duration = ts - thread.lastActiveTs; - var value = thread.lastActiveValue; - if (value == undefined) - value = ' '; - var slice = new tr.model.Slice( - '', value, - ColorScheme.getColorIdForGeneralPurposeString(value), - thread.lastActiveTs, {}, - duration); - thread.thread.sliceGroup.pushSlice(slice); - } - thread.lastActiveTs = ts; - thread.lastActiveValue = event[2]; - return true; - }, - - syncWaitEvent: function(eventName, cpuNumber, pid, ts, - eventBase) { - var event = syncWaitRE.exec(eventBase.details); - if (!event) - return false; - - if (eventBase.tgid === undefined) { - return false; - } - - var tgid = parseInt(eventBase.tgid); - var thread = this.model_.getOrCreateProcess(tgid) - .getOrCreateThread(pid); - thread.name = eventBase.threadName; - var slices = thread.kernelSliceGroup; - if (!slices.isTimestampValidForBeginOrEnd(ts)) { - this.model_.importWarning({ - type: 'parse_error', - message: 'Timestamps are moving backward.' - }); - return false; - } - - var name = 'fence_wait("' + event[2] + '")'; - if (event[1] == 'begin') { - var slice = slices.beginSlice(null, name, ts, { - 'Start state': event[3] - }); - } else if (event[1] == 'end') { - if (slices.openSliceCount > 0) { - slices.endSlice(ts); - } - } else { - return false; - } - - return true; - }, - - syncPtEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = syncPtRE.exec(eventBase.details); - if (!event) - return false; - - return true; - - var thread = this.importer.getOrCreateKernelThread( - eventBase[1]).thread; - thread.syncWaitSyncPts[event[1]] = event[2]; - return true; - } - }; - - Parser.register(SyncParser); - - return { - SyncParser: SyncParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sync_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sync_parser_test.html deleted file mode 100644 index c56e2576f3a..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/sync_parser_test.html +++ /dev/null @@ -1,55 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('syncEventImport', function() { - var lines = [ - 's3c-fb-92 ( 0) [000] ...1 7206.550061: sync_timeline: name=s3c-fb value=7094', // @suppress longLineCheck - 'TimedEventQueue-2700 ( 0) [001] ...1 7206.569027: sync_wait: begin name=SurfaceView:6 state=1', // @suppress longLineCheck - 'TimedEventQueue-2700 ( 0) [001] ...1 7206.569038: sync_pt: name=malitl_124_0x40b6406c value=7289', // @suppress longLineCheck - 'TimedEventQueue-2700 ( 0) [001] ...1 7206.569056: sync_pt: name=exynos-gsc.0-src value=25', // @suppress longLineCheck - 'TimedEventQueue-2700 ( 0) [001] ...1 7206.569068: sync_wait: end name=SurfaceView:6 state=1', // @suppress longLineCheck - 'irq/128-s5p-mfc-62 ( 0) [000] d..3 7206.572402: sync_timeline: name=vb2 value=37', // @suppress longLineCheck - 'irq/128-s5p-mfc-62 ( 0) [000] d..3 7206.572475: sync_timeline: name=vb2 value=33', // @suppress longLineCheck - 'SurfaceFlinger-225 ( 0) [001] ...1 7206.584769: sync_timeline: name=malitl_124_0x40b6406c value=7290', // @suppress longLineCheck - 'kworker/u:5-2269 ( 0) [000] ...1 7206.586745: sync_wait: begin name=display state=1', // @suppress longLineCheck - 'kworker/u:5-2269 ( 0) [000] ...1 7206.586750: sync_pt: name=s3c-fb value=7093', // @suppress longLineCheck - 'kworker/u:5-2269 ( 0) [000] ...1 7206.586760: sync_wait: end name=display state=1', // @suppress longLineCheck - 's3c-fb-92 ( 0) [000] ...1 7206.587193: sync_wait: begin name=vb2 state=0', // @suppress longLineCheck - 's3c-fb-92 ( 0) [000] ...1 7206.587198: sync_pt: name=exynos-gsc.0-dst value=27', // @suppress longLineCheck - '<idle>-0 ( 0) [000] d.h4 7206.591133: sync_timeline: name=exynos-gsc.0-src value=27', // @suppress longLineCheck - '<idle>-0 ( 0) [000] d.h4 7206.591152: sync_timeline: name=exynos-gsc.0-dst value=27', // @suppress longLineCheck - 's3c-fb-92 ( 0) [000] ...1 7206.591244: sync_wait: end name=vb2 state=1' // @suppress longLineCheck - ]; - - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - var threads = m.getAllThreads(); - assert.equal(threads.length, 4); - - var threads = m.findAllThreadsNamed('s3c-fb'); - assert.equal(threads.length, 1); - assert.equal(threads[0].sliceGroup.length, 1); - - var threads = m.findAllThreadsNamed('kworker/u:5'); - assert.equal(threads.length, 1); - assert.equal(threads[0].sliceGroup.length, 1); - assert.equal('fence_wait("display")', - threads[0].sliceGroup.slices[0].title); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/workqueue_parser.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/workqueue_parser.html deleted file mode 100644 index ab71565b6b4..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/workqueue_parser.html +++ /dev/null @@ -1,103 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/linux_perf/parser.html"> - -<script> -'use strict'; - -/** - * @fileoverview Parses workqueue events in the Linux event trace format. - */ -tr.exportTo('tr.e.importer.linux_perf', function() { - - var ColorScheme = tr.b.ColorScheme; - var Parser = tr.e.importer.linux_perf.Parser; - - /** - * Parses linux workqueue trace events. - * @constructor - */ - function WorkqueueParser(importer) { - Parser.call(this, importer); - - importer.registerEventHandler('workqueue_execute_start', - WorkqueueParser.prototype.executeStartEvent.bind(this)); - importer.registerEventHandler('workqueue_execute_end', - WorkqueueParser.prototype.executeEndEvent.bind(this)); - importer.registerEventHandler('workqueue_queue_work', - WorkqueueParser.prototype.executeQueueWork.bind(this)); - importer.registerEventHandler('workqueue_activate_work', - WorkqueueParser.prototype.executeActivateWork.bind(this)); - } - - // Matches the workqueue_execute_start record - // workqueue_execute_start: work struct c7a8a89c: function MISRWrapper - var workqueueExecuteStartRE = /work struct (.+): function (\S+)/; - - // Matches the workqueue_execute_start record - // workqueue_execute_end: work struct c7a8a89c - var workqueueExecuteEndRE = /work struct (.+)/; - - WorkqueueParser.prototype = { - __proto__: Parser.prototype, - - /** - * Parses workqueue events and sets up state in the importer. - */ - executeStartEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = workqueueExecuteStartRE.exec(eventBase.details); - if (!event) - return false; - - var kthread = this.importer.getOrCreateKernelThread(eventBase.threadName, - pid, pid); - kthread.openSliceTS = ts; - kthread.openSlice = event[2]; - return true; - }, - - executeEndEvent: function(eventName, cpuNumber, pid, ts, eventBase) { - var event = workqueueExecuteEndRE.exec(eventBase.details); - if (!event) - return false; - - var kthread = this.importer.getOrCreateKernelThread(eventBase.threadName, - pid, pid); - if (kthread.openSlice) { - var slice = new tr.model.Slice('', kthread.openSlice, - ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice), - kthread.openSliceTS, - {}, - ts - kthread.openSliceTS); - - kthread.thread.sliceGroup.pushSlice(slice); - } - kthread.openSlice = undefined; - return true; - }, - - executeQueueWork: function(eventName, cpuNumber, pid, ts, eventBase) { - // TODO: Do something with this event? - return true; - }, - - executeActivateWork: function(eventName, cpuNumber, pid, ts, eventBase) { - // TODO: Do something with this event? - return true; - } - - }; - - Parser.register(WorkqueueParser); - - return { - WorkqueueParser: WorkqueueParser - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/workqueue_parser_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/workqueue_parser_test.html deleted file mode 100644 index dc3057b6a9b..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/linux_perf/workqueue_parser_test.html +++ /dev/null @@ -1,36 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('workQueueImport', function() { - var lines = [ - ' kworker/0:3-6880 [000] 2784.771958: workqueue_execute_start: ' + - 'work struct ffff8800a5083a20: function intel_unpin_work_fn', - ' kworker/0:3-6880 [000] 2784.771966: workqueue_execute_end: ' + - 'work struct ffff8800a5083a20', - ' kworker/1:2-7269 [001] 2784.805966: workqueue_execute_start: ' + - 'work struct ffff88014fb0f158: function do_dbs_timer', - ' kworker/1:2-7269 [001] 2784.805975: workqueue_execute_end: ' + - 'work struct ffff88014fb0f158' - ]; - var m = tr.c.TestUtils.newModelWithEvents([lines.join('\n')], { - shiftWorldToZero: false - }); - assert.isFalse(m.hasImportWarnings); - - assert.equal(m.processes['6880'].threads['6880'].sliceGroup.length, 1); - assert.equal(m.processes['7269'].threads['7269'].sliceGroup.length, 1); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace2html_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/trace2html_importer.html deleted file mode 100644 index 14854745eb4..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace2html_importer.html +++ /dev/null @@ -1,95 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -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/base/base64.html"> -<link rel="import" href="/tracing/importer/importer.html"> -<link rel="import" href="/tracing/importer/simple_line_reader.html"> -<link rel="import" href="/tracing/model/model.html"> - -<script> -'use strict'; - -tr.exportTo('tr.e.importer', function() { - - function Trace2HTMLImporter(model, events) { - this.importPriority = 0; - } - - Trace2HTMLImporter.subtraces_ = []; - - function _extractEventsFromHTML(text) { - // Clear the array before pushing data to it. - Trace2HTMLImporter.subtraces_ = []; - - var r = new tr.importer.SimpleLineReader(text); - - // Try to find viewer-data... - while (true) { - if (!r.advanceToLineMatching( - new RegExp('^<\s*script id="viewer-data" ' + - 'type="(application\/json|text\/plain)">$'))) - break; - - r.beginSavingLines(); - if (!r.advanceToLineMatching(/^<\/\s*script>$/)) - return; - - var raw_events = r.endSavingLinesAndGetResult(); - - // Drop off first and last event as it contains the end script tag. - raw_events = raw_events.slice(1, raw_events.length - 1); - var data64 = raw_events.join('\n'); - var buffer = new ArrayBuffer( - tr.b.Base64.getDecodedBufferLength(data64)); - var len = tr.b.Base64.DecodeToTypedArray(data64, new DataView(buffer)); - Trace2HTMLImporter.subtraces_.push(buffer.slice(0, len)); - } - } - - function _canImportFromHTML(text) { - if (/^<!DOCTYPE html>/.test(text) === false) - return false; - - // Try to find viewer-data... - _extractEventsFromHTML(text); - if (Trace2HTMLImporter.subtraces_.length === 0) - return false; - return true; - } - - Trace2HTMLImporter.canImport = function(events) { - return _canImportFromHTML(events); - }; - - Trace2HTMLImporter.prototype = { - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'Trace2HTMLImporter'; - }, - - isTraceDataContainer: function() { - return true; - }, - - extractSubtraces: function() { - return Trace2HTMLImporter.subtraces_; - }, - - importEvents: function() { - } - }; - - - tr.importer.Importer.register(Trace2HTMLImporter); - - - return { - Trace2HTMLImporter: Trace2HTMLImporter - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace2html_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/trace2html_importer_test.html deleted file mode 100644 index 8d91c1494a7..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace2html_importer_test.html +++ /dev/null @@ -1,44 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2014 The Chromium Authors. All rights reserved. -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<link rel="improt" href="/tracing/base/base64.html"> -<link rel="import" href="/tracing/extras/importer/trace2html_importer.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - var Base64 = tr.b.Base64; - - test('simple', function() { - var html_lines = [ - '<!DOCTYPE html>', - '<script id="viewer-data" type="application/json">', - Base64.btoa('hello'), - '<\/script>', - '<script id="viewer-data" type="text/plain">', - Base64.btoa('world'), - '<\/script>', - '</html>' - ]; - var html_text = html_lines.join('\n'); - assert.isTrue(tr.e.importer.Trace2HTMLImporter.canImport(html_text)); - - var m = new tr.Model(); - var imp = new tr.e.importer.Trace2HTMLImporter(m, html_text); - var subTracesAsBuffers = imp.extractSubtraces(); - var subTracesAsStrings = subTracesAsBuffers.map(function(buffer) { - var str = ''; - var ary = new Uint8Array(buffer); - for (var i = 0; i < ary.length; i++) - str += String.fromCharCode(ary[i]); - return str; - }); - assert.deepEqual(subTracesAsStrings, ['hello', 'world']); - }); -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_entry.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_entry.html deleted file mode 100644 index 8216b613c16..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_entry.html +++ /dev/null @@ -1,129 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright 2015 The Chromium Authors. All rights reserved. -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/model/source_info/js_source_info.html"> - -<script> -'use strict'; - -/** - * @fileoverview TraceCodeEntry is a wrapper around the V8 CodeEntry that - * extracts extra context information for each item. This includes things like - * the source file, line and if the function is a native method or not. - */ -tr.exportTo('tr.e.importer', function() { - function TraceCodeEntry(address, size, name, scriptId) { - this.id_ = tr.b.GUID.allocateSimple(); - this.address_ = address; - this.size_ = size; - - // Stolen from DevTools TimelineJSProfileProcessor._buildCallFrame - // Code states: - // (empty) -> compiled - // ~ -> optimizable - // * -> optimized - var rePrefix = /^(\w*:)?([*~]?)(.*)$/m; - var tokens = rePrefix.exec(name); - var prefix = tokens[1]; - var state = tokens[2]; - var body = tokens[3]; - - if (state === '*') { - state = tr.model.source_info.JSSourceState.OPTIMIZED; - } else if (state === '~') { - state = tr.model.source_info.JSSourceState.OPTIMIZABLE; - } else if (state === '') { - state = tr.model.source_info.JSSourceState.COMPILED; - } else { - console.warning('Unknown v8 code state ' + state); - state = tr.model.source_info.JSSourceState.UNKNOWN; - } - - var rawName; - var rawUrl; - if (prefix === 'Script:') { - rawName = ''; - rawUrl = body; - } else { - var spacePos = body.lastIndexOf(' '); - rawName = spacePos !== -1 ? body.substr(0, spacePos) : body; - rawUrl = spacePos !== -1 ? body.substr(spacePos + 1) : ''; - } - - function splitLineAndColumn(url) { - var lineColumnRegEx = /(?::(\d+))?(?::(\d+))?$/; - var lineColumnMatch = lineColumnRegEx.exec(url); - var lineNumber; - var columnNumber; - - if (typeof(lineColumnMatch[1]) === 'string') { - lineNumber = parseInt(lineColumnMatch[1], 10); - // Immediately convert line and column to 0-based numbers. - lineNumber = isNaN(lineNumber) ? undefined : lineNumber - 1; - } - if (typeof(lineColumnMatch[2]) === 'string') { - columnNumber = parseInt(lineColumnMatch[2], 10); - columnNumber = isNaN(columnNumber) ? undefined : columnNumber - 1; - } - - return { - url: url.substring(0, url.length - lineColumnMatch[0].length), - lineNumber: lineNumber, - columnNumber: columnNumber - }; - } - - var nativeSuffix = ' native'; - var isNative = rawName.endsWith(nativeSuffix); - this.name_ = - isNative ? rawName.slice(0, -nativeSuffix.length) : rawName; - - var urlData = splitLineAndColumn(rawUrl); - var url = urlData.url || ''; - var line = urlData.lineNumber || 0; - var column = urlData.columnNumber || 0; - - this.sourceInfo_ = new tr.model.source_info.JSSourceInfo( - url, line, column, isNative, scriptId, state); - }; - - TraceCodeEntry.prototype = { - get id() { - return this.id_; - }, - - get sourceInfo() { - return this.sourceInfo_; - }, - - get name() { - return this.name_; - }, - - set address(address) { - this.address_ = address; - }, - - get address() { - return this.address_; - }, - - set size(size) { - this.size_ = size; - }, - - get size() { - return this.size_; - } - }; - - return { - TraceCodeEntry: TraceCodeEntry - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_entry_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_entry_test.html deleted file mode 100644 index 917081c7fb7..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_entry_test.html +++ /dev/null @@ -1,124 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright 2015 The Chromium Authors. All rights reserved. -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/extras/importer/trace_code_entry.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - test('lazy_compile_method', function() { - var tce = new tr.e.importer.TraceCodeEntry( - '0x123', 10, 'Handler:timeStamp', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, 'timeStamp'); - assert.equal(tce.sourceInfo.isNative, false); - assert.equal(tce.sourceInfo.file, ''); - assert.equal(tce.sourceInfo.line, -1); - assert.equal(tce.sourceInfo.scriptId, 12); - }); - - test('non_lazy_compile_method', function() { - var tce = new tr.e.importer.TraceCodeEntry( - '0x123', 10, 'Handler:timeStamp', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, 'timeStamp'); - assert.equal(tce.sourceInfo.state, 'compiled'); - assert.equal(tce.sourceInfo.isNative, false); - assert.equal(tce.sourceInfo.file, ''); - assert.equal(tce.sourceInfo.line, -1); - assert.equal(tce.sourceInfo.scriptId, 12); - }); - - test('native_matching', function() { - var tce = new tr.e.importer.TraceCodeEntry('0x123', 10, - 'LazyCompile:~IsAccessorDescriptor native v8natives.js:183', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, 'IsAccessorDescriptor'); - assert.equal(tce.sourceInfo.isNative, true); - assert.equal(tce.sourceInfo.state, 'optimizable'); - assert.equal(tce.sourceInfo.file, 'v8natives.js'); - assert.equal(tce.sourceInfo.line, 182); - assert.equal(tce.sourceInfo.scriptId, 12); - }); - - test('strips_*_from_name', function() { - var tce = new tr.e.importer.TraceCodeEntry('0x123', 10, - 'LazyCompile:*IsAccessorDescriptor native v8natives.js:183', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, 'IsAccessorDescriptor'); - assert.equal(tce.sourceInfo.isNative, true); - assert.equal(tce.sourceInfo.state, 'optimized'); - assert.equal(tce.sourceInfo.file, 'v8natives.js'); - assert.equal(tce.sourceInfo.line, 182); - assert.equal(tce.sourceInfo.scriptId, 12); - }); - - test('non_native_matching', function() { - var tce = new tr.e.importer.TraceCodeEntry('0x123', 10, - 'LazyCompile:~IsAccessorDescriptor v8natives.js:183', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, 'IsAccessorDescriptor'); - assert.equal(tce.sourceInfo.isNative, false); - assert.equal(tce.sourceInfo.file, 'v8natives.js'); - assert.equal(tce.sourceInfo.line, 182); - assert.equal(tce.sourceInfo.scriptId, 12); - }); - - test('lazy_compile_without_script', function() { - var tce = new tr.e.importer.TraceCodeEntry( - '0x123', 10, 'LazyCompile:~Object', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, 'Object'); - assert.equal(tce.sourceInfo.isNative, false); - assert.equal(tce.sourceInfo.file, ''); - assert.equal(tce.sourceInfo.line, -1); - assert.equal(tce.sourceInfo.scriptId, 12); - }); - - test('line_matching_without_script', function() { - var tce = new tr.e.importer.TraceCodeEntry('0x123', 10, - 'LazyCompile:~Object :220', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, 'Object'); - assert.equal(tce.sourceInfo.isNative, false); - assert.equal(tce.sourceInfo.file, ''); - assert.equal(tce.sourceInfo.line, 219); - assert.equal(tce.sourceInfo.scriptId, 12); - }); - - test('unknown_method_name', function() { - var tce = new tr.e.importer.TraceCodeEntry('0x123', 10, 'LazyCompile:', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, ''); - assert.equal(tce.sourceInfo.isNative, false); - assert.equal(tce.sourceInfo.file, ''); - assert.equal(tce.sourceInfo.line, -1); - assert.equal(tce.sourceInfo.scriptId, 12); - - var tce = new tr.e.importer.TraceCodeEntry( - '0x123', 10, 'LazyCompile:~ :37', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, ''); - assert.equal(tce.sourceInfo.isNative, false); - assert.equal(tce.sourceInfo.file, ''); - assert.equal(tce.sourceInfo.line, 36); - assert.equal(tce.sourceInfo.scriptId, 12); - - var tce = new tr.e.importer.TraceCodeEntry('0x123', 10, - 'LazyCompile:~ native liveedit.js:37:10', 12); - assert.equal(tce.size, 10); - assert.equal(tce.name, ''); - assert.equal(tce.sourceInfo.isNative, true); - assert.equal(tce.sourceInfo.file, 'liveedit.js'); - assert.equal(tce.sourceInfo.line, 36); - assert.equal(tce.sourceInfo.column, 9); - assert.equal(tce.sourceInfo.scriptId, 12); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_map.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_map.html deleted file mode 100644 index dbdfecbd3e4..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_code_map.html +++ /dev/null @@ -1,127 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright 2015 The Chromium Authors. All rights reserved. -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/extras/importer/trace_code_entry.html'> - -<script> -'use strict'; - -tr.exportTo('tr.e.importer', function() { - // This code is a tracification of: - // devtools/front_end/timeline/TimelineJSProfile.js - function TraceCodeMap() { - this.banks_ = new Map(); - } - - TraceCodeMap.prototype = { - addEntry: function(addressHex, size, name, scriptId) { - var entry = new tr.e.importer.TraceCodeEntry( - this.getAddress_(addressHex), size, name, scriptId); - - this.addEntry_(addressHex, entry); - }, - - moveEntry: function(oldAddressHex, newAddressHex, size) { - var entry = this.getBank_(oldAddressHex) - .removeEntry(this.getAddress_(oldAddressHex)); - if (!entry) - return; - - entry.address = this.getAddress_(newAddressHex); - entry.size = size; - this.addEntry_(newAddressHex, entry); - }, - - lookupEntry: function(addressHex) { - return this.getBank_(addressHex) - .lookupEntry(this.getAddress_(addressHex)); - }, - - addEntry_: function(addressHex, entry) { - // FIXME: Handle bank spanning addresses ... - this.getBank_(addressHex).addEntry(entry); - }, - - getAddress_: function(addressHex) { - // 13 hex digits == 52 bits, double mantissa fits 53 bits. - var bankSizeHexDigits = 13; - addressHex = addressHex.slice(2); // cut 0x prefix. - return parseInt(addressHex.slice(-bankSizeHexDigits), 16); - }, - - getBank_: function(addressHex) { - addressHex = addressHex.slice(2); // cut 0x prefix. - - // 13 hex digits == 52 bits, double mantissa fits 53 bits. - var bankSizeHexDigits = 13; - var maxHexDigits = 16; - var bankName = addressHex.slice(-maxHexDigits, -bankSizeHexDigits); - var bank = this.banks_.get(bankName); - if (!bank) { - bank = new TraceCodeBank(); - this.banks_.set(bankName, bank); - } - return bank; - } - }; - - function TraceCodeBank() { - this.entries_ = []; - } - - TraceCodeBank.prototype = { - removeEntry: function(address) { - // findLowIndexInSortedArray returns 1 for empty. Just handle the - // empty list and bail early. - if (this.entries_.length === 0) - return undefined; - - var index = tr.b.findLowIndexInSortedArray( - this.entries_, function(entry) { return entry.address; }, address); - var entry = this.entries_[index]; - if (!entry || entry.address !== address) - return undefined; - - this.entries_.splice(index, 1); - return entry; - }, - - lookupEntry: function(address) { - var index = tr.b.findHighIndexInSortedArray( - this.entries_, function(e) { return address - e.address; }) - 1; - var entry = this.entries_[index]; - return entry && - address < entry.address + entry.size ? entry : undefined; - }, - - addEntry: function(newEntry) { - // findLowIndexInSortedArray returns 1 for empty list. Just push the - // new address as it's the only item. - if (this.entries_.length === 0) - this.entries_.push(newEntry); - - var endAddress = newEntry.address + newEntry.size; - var lastIndex = tr.b.findLowIndexInSortedArray( - this.entries_, function(entry) { return entry.address; }, endAddress); - var index; - for (index = lastIndex - 1; index >= 0; --index) { - var entry = this.entries_[index]; - var entryEndAddress = entry.address + entry.size; - if (entryEndAddress <= newEntry.address) - break; - } - ++index; - this.entries_.splice(index, lastIndex - index, newEntry); - } - }; - - return { - TraceCodeMap: TraceCodeMap - }; -}); - -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer.html deleted file mode 100644 index b7cf2badef2..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer.html +++ /dev/null @@ -1,2989 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/base/base64.html"> -<link rel="import" href="/tracing/base/color_scheme.html"> -<link rel="import" href="/tracing/base/range.html"> -<link rel="import" href="/tracing/base/utils.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"> -<link rel="import" href="/tracing/importer/context_processor.html"> -<link rel="import" href="/tracing/importer/importer.html"> -<link rel="import" href="/tracing/model/comment_box_annotation.html"> -<link rel="import" href="/tracing/model/constants.html"> -<link rel="import" href="/tracing/model/container_memory_dump.html"> -<link rel="import" href="/tracing/model/counter_series.html"> -<link rel="import" href="/tracing/model/flow_event.html"> -<link rel="import" href="/tracing/model/global_memory_dump.html"> -<link rel="import" href="/tracing/model/heap_dump.html"> -<link rel="import" href="/tracing/model/instant_event.html"> -<link rel="import" href="/tracing/model/memory_allocator_dump.html"> -<link rel="import" href="/tracing/model/model.html"> -<link rel="import" href="/tracing/model/process_memory_dump.html"> -<link rel="import" href="/tracing/model/rect_annotation.html"> -<link rel="import" href="/tracing/model/scoped_id.html"> -<link rel="import" href="/tracing/model/slice_group.html"> -<link rel="import" href="/tracing/model/vm_region.html"> -<link rel="import" href="/tracing/model/x_marker_annotation.html"> -<link rel="import" href="/tracing/value/numeric.html"> -<link rel="import" href="/tracing/value/unit.html"> - -<script> -'use strict'; - -/** - * @fileoverview TraceEventImporter imports TraceEvent-formatted data - * into the provided model. - */ -tr.exportTo('tr.e.importer', function() { - var Base64 = tr.b.Base64; - var deepCopy = tr.b.deepCopy; - var ColorScheme = tr.b.ColorScheme; - - function getEventColor(event, opt_customName) { - if (event.cname) - return ColorScheme.getColorIdForReservedName(event.cname); - else if (opt_customName || event.name) { - return ColorScheme.getColorIdForGeneralPurposeString( - opt_customName || event.name); - } - } - - var timestampFromUs = tr.v.Unit.timestampFromUs; - var maybeTimestampFromUs = tr.v.Unit.maybeTimestampFromUs; - - var PRODUCER = 'producer'; - var CONSUMER = 'consumer'; - var STEP = 'step'; - - var LIGHT = tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT; - var DETAILED = tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED; - var MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER = [undefined, LIGHT, DETAILED]; - - var GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX = 'global/'; - - // Map from raw memory dump byte stat names to model byte stat names. See - // //base/trace_event/process_memory_maps.cc in Chromium. - var BYTE_STAT_NAME_MAP = { - 'pc': 'privateCleanResident', - 'pd': 'privateDirtyResident', - 'sc': 'sharedCleanResident', - 'sd': 'sharedDirtyResident', - 'pss': 'proportionalResident', - 'sw': 'swapped' - }; - - // See tr.model.MemoryAllocatorDump 'weak' field and - // base::trace_event::MemoryAllocatorDump::Flags::WEAK in the Chromium - // codebase. - var WEAK_MEMORY_ALLOCATOR_DUMP_FLAG = 1 << 0; - - // Object type name patterns for various compilers. - var OBJECT_TYPE_NAME_PATTERNS = [ - { - // Clang. - prefix: 'const char *WTF::getStringWithTypeName() [T = ', - suffix: ']' - }, - { - // GCC. - prefix: 'const char* WTF::getStringWithTypeName() [with T = ', - suffix: ']' - }, - { - // Microsoft Visual C++ - prefix: 'const char *__cdecl WTF::getStringWithTypeName<', - suffix: '>(void)' - } - ]; - - // The list of fields on the trace that are known to contain subtraces. - var SUBTRACE_FIELDS = new Set([ - 'powerTraceAsString', - 'systemTraceEvents', - ]); - - // The complete list of fields on the trace that should not be treated as - // trace metadata. - var NON_METADATA_FIELDS = new Set([ - 'samples', - 'stackFrames', - 'traceAnnotations', - 'traceEvents' - ]); - // TODO(charliea): Replace this with the spread (...) operator in literal - // above once v8 is updated to a sufficiently recent version (>M45). - for (var subtraceField in SUBTRACE_FIELDS) - NON_METADATA_FIELDS.add(subtraceField); - - function TraceEventImporter(model, eventData) { - this.importPriority = 1; - this.model_ = model; - this.events_ = undefined; - this.sampleEvents_ = undefined; - this.stackFrameEvents_ = undefined; - this.subtraces_ = []; - this.eventsWereFromString_ = false; - this.softwareMeasuredCpuCount_ = undefined; - - this.allAsyncEvents_ = []; - this.allFlowEvents_ = []; - this.allObjectEvents_ = []; - - this.contextProcessorPerThread = {}; - - this.traceEventSampleStackFramesByName_ = {}; - - this.v8ProcessCodeMaps_ = {}; - this.v8ProcessRootStackFrame_ = {}; - this.v8SamplingData_ = []; - - // Dump ID -> PID -> [process memory dump events]. - this.allMemoryDumpEvents_ = {}; - - // PID -> Object type ID -> Object type name. - this.objectTypeNameMap_ = {}; - - // For old Chrome traces with no clock domain metadata, just use a - // placeholder clock domain. - this.clockDomainId_ = tr.model.ClockDomainId.UNKNOWN_CHROME_LEGACY; - - if (typeof(eventData) === 'string' || eventData instanceof String) { - eventData = eventData.trim(); - // If the event data begins with a [, then we know it should end with a ]. - // The reason we check for this is because some tracing implementations - // cannot guarantee that a ']' gets written to the trace file. So, we are - // forgiving and if this is obviously the case, we fix it up before - // throwing the string at JSON.parse. - if (eventData[0] === '[') { - eventData = eventData.replace(/\s*,\s*$/, ''); - if (eventData[eventData.length - 1] !== ']') - eventData = eventData + ']'; - } - - this.events_ = JSON.parse(eventData); - this.eventsWereFromString_ = true; - } else { - 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_; - this.events_ = this.events_.traceEvents; - - // Some trace authors store subtraces as specific properties of the trace. - for (var 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.v.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']; - } - } - } - } - - /** - * @return {boolean} Whether obj is a TraceEvent array. - */ - TraceEventImporter.canImport = function(eventData) { - // May be encoded JSON. But we dont want to parse it fully yet. - // Use a simple heuristic: - // - 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 (typeof(eventData) === 'string' || eventData instanceof String) { - eventData = eventData.trim(); - return eventData[0] === '{' || eventData[0] === '['; - } - - // Might just be an array of events - if (eventData instanceof Array && eventData.length && eventData[0].ph) - return true; - - // Might be an object with a traceEvents field in it. - if (eventData.traceEvents) { - if (eventData.traceEvents instanceof Array) { - if (eventData.traceEvents.length && eventData.traceEvents[0].ph) - return true; - if (eventData.samples.length && eventData.stackFrames !== undefined) - return true; - } - } - - return false; - }; - - TraceEventImporter.prototype = { - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'TraceEventImporter'; - }, - - extractSubtraces: function() { - // Because subtraces can be quite large, we need to make sure that we - // don't hold a reference to the memory. - var subtraces = this.subtraces_; - this.subtraces_ = []; - return subtraces; - }, - - /** - * Deep copying is only needed if the trace was given to us as events. - */ - deepCopyIfNeeded_: function(obj) { - if (obj === undefined) - obj = {}; - if (this.eventsWereFromString_) - return obj; - return deepCopy(obj); - }, - - /** - * Always perform deep copying. - */ - deepCopyAlways_: function(obj) { - if (obj === undefined) - obj = {}; - return deepCopy(obj); - }, - - /** - * Helper to process an async event. - */ - processAsyncEvent: function(event) { - var thread = this.model_.getOrCreateProcess(event.pid). - getOrCreateThread(event.tid); - this.allAsyncEvents_.push({ - sequenceNumber: this.allAsyncEvents_.length, - event: event, - thread: thread - }); - }, - - /** - * Helper to process a flow event. - */ - processFlowEvent: function(event, opt_slice) { - var thread = this.model_.getOrCreateProcess(event.pid). - getOrCreateThread(event.tid); - this.allFlowEvents_.push({ - refGuid: tr.b.GUID.getLastSimpleGuid(), - sequenceNumber: this.allFlowEvents_.length, - event: event, - slice: opt_slice, // slice for events that have flow info - thread: thread - }); - }, - - /** - * Helper that creates and adds samples to a Counter object based on - * 'C' phase events. - */ - processCounterEvent: function(event) { - var ctr_name; - if (event.id !== undefined) - ctr_name = event.name + '[' + event.id + ']'; - else - ctr_name = event.name; - - var ctr = this.model_.getOrCreateProcess(event.pid) - .getOrCreateCounter(event.cat, ctr_name); - var reservedColorId = event.cname ? getEventColor(event) : undefined; - - // Initialize the counter's series fields if needed. - if (ctr.numSeries === 0) { - for (var seriesName in event.args) { - var colorId = reservedColorId || - getEventColor(event, ctr.name + '.' + seriesName); - ctr.addSeries(new tr.model.CounterSeries(seriesName, colorId)); - } - - if (ctr.numSeries === 0) { - this.model_.importWarning({ - type: 'counter_parse_error', - message: 'Expected counter ' + event.name + - ' to have at least one argument to use as a value.' - }); - - // Drop the counter. - delete ctr.parent.counters[ctr.name]; - return; - } - } - - var ts = timestampFromUs(event.ts); - ctr.series.forEach(function(series) { - var val = event.args[series.name] ? event.args[series.name] : 0; - series.addCounterSample(ts, val); - }); - }, - - scopedIdForEvent_: function(event) { - return new tr.model.ScopedId( - event.scope || tr.model.OBJECT_DEFAULT_SCOPE, event.id); - }, - - processObjectEvent: function(event) { - var thread = this.model_.getOrCreateProcess(event.pid). - getOrCreateThread(event.tid); - this.allObjectEvents_.push({ - sequenceNumber: this.allObjectEvents_.length, - event: event, - thread: thread}); - if (thread.guid in this.contextProcessorPerThread) { - var processor = this.contextProcessorPerThread[thread.guid]; - var scopedId = this.scopedIdForEvent_(event); - if (event.ph === 'D') - processor.destroyContext(scopedId); - // The context processor maintains a cache of unique context objects and - // active context sets to reduce memory usage. If an object is modified, - // we should invalidate this cache, because otherwise context sets from - // before and after the modification may erroneously point to the same - // context snapshot (as both are the same set/object instances). - processor.invalidateContextCacheForSnapshot(scopedId); - } - }, - - processContextEvent: function(event) { - var thread = this.model_.getOrCreateProcess(event.pid). - getOrCreateThread(event.tid); - if (!(thread.guid in this.contextProcessorPerThread)) { - this.contextProcessorPerThread[thread.guid] = - new tr.importer.ContextProcessor(this.model_); - } - var scopedId = this.scopedIdForEvent_(event); - var contextType = event.name; - var processor = this.contextProcessorPerThread[thread.guid]; - if (event.ph === '(') { - processor.enterContext(contextType, scopedId); - } else if (event.ph === ')') { - processor.leaveContext(contextType, scopedId); - } else { - this.model_.importWarning({ - type: 'unknown_context_phase', - message: 'Unknown context event phase: ' + event.ph + '.' - }); - } - }, - - setContextsFromThread_: function(thread, slice) { - if (thread.guid in this.contextProcessorPerThread) { - slice.contexts = - this.contextProcessorPerThread[thread.guid].activeContexts; - } - }, - - processDurationEvent: function(event) { - var thread = this.model_.getOrCreateProcess(event.pid) - .getOrCreateThread(event.tid); - var ts = timestampFromUs(event.ts); - if (!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)) { - this.model_.importWarning({ - type: 'duration_parse_error', - message: 'Timestamps are moving backward.' - }); - return; - } - - if (event.ph === 'B') { - var slice = thread.sliceGroup.beginSlice( - event.cat, event.name, timestampFromUs(event.ts), - this.deepCopyIfNeeded_(event.args), - timestampFromUs(event.tts), event.argsStripped, - getEventColor(event)); - slice.startStackFrame = this.getStackFrameForEvent_(event); - this.setContextsFromThread_(thread, slice); - } else if (event.ph === 'I' || event.ph === 'i' || event.ph === 'R') { - if (event.s !== undefined && event.s !== 't') - throw new Error('This should never happen'); - - thread.sliceGroup.beginSlice(event.cat, event.name, - timestampFromUs(event.ts), - this.deepCopyIfNeeded_(event.args), - timestampFromUs(event.tts), - event.argsStripped, - getEventColor(event)); - var slice = thread.sliceGroup.endSlice(timestampFromUs(event.ts), - timestampFromUs(event.tts)); - slice.startStackFrame = this.getStackFrameForEvent_(event); - slice.endStackFrame = undefined; - } else { - if (!thread.sliceGroup.openSliceCount) { - this.model_.importWarning({ - type: 'duration_parse_error', - message: 'E phase event without a matching B phase event.' - }); - return; - } - - var slice = thread.sliceGroup.endSlice(timestampFromUs(event.ts), - timestampFromUs(event.tts), - getEventColor(event)); - if (event.name && slice.title != event.name) { - this.model_.importWarning({ - type: 'title_match_error', - message: 'Titles do not match. Title is ' + - slice.title + ' in openSlice, and is ' + - event.name + ' in endSlice' - }); - } - slice.endStackFrame = this.getStackFrameForEvent_(event); - - this.mergeArgsInto_(slice.args, event.args, slice.title); - } - }, - - mergeArgsInto_: function(dstArgs, srcArgs, eventName) { - for (var arg in srcArgs) { - if (dstArgs[arg] !== undefined) { - this.model_.importWarning({ - type: 'arg_merge_error', - message: 'Different phases of ' + eventName + - ' provided values for argument ' + arg + '.' + - ' The last provided value will be used.' - }); - } - dstArgs[arg] = this.deepCopyIfNeeded_(srcArgs[arg]); - } - }, - - processCompleteEvent: function(event) { - // Preventing the overhead slices from making it into the model. This - // only applies to legacy traces, as the overhead traces have been - // removed from the chromium code. - if (event.cat !== undefined && - event.cat.indexOf('trace_event_overhead') > -1) - return undefined; - - var thread = this.model_.getOrCreateProcess(event.pid) - .getOrCreateThread(event.tid); - - if (event.flow_out) { - if (event.flow_in) - event.flowPhase = STEP; - else - event.flowPhase = PRODUCER; - } else if (event.flow_in) { - event.flowPhase = CONSUMER; - } - - var slice = thread.sliceGroup.pushCompleteSlice(event.cat, event.name, - timestampFromUs(event.ts), - maybeTimestampFromUs(event.dur), - maybeTimestampFromUs(event.tts), - maybeTimestampFromUs(event.tdur), - this.deepCopyIfNeeded_(event.args), - event.argsStripped, - getEventColor(event), - event.bind_id); - slice.startStackFrame = this.getStackFrameForEvent_(event); - slice.endStackFrame = this.getStackFrameForEvent_(event, true); - this.setContextsFromThread_(thread, slice); - - return slice; - }, - - processJitCodeEvent: function(event) { - if (this.v8ProcessCodeMaps_[event.pid] === undefined) - this.v8ProcessCodeMaps_[event.pid] = new tr.e.importer.TraceCodeMap(); - var map = this.v8ProcessCodeMaps_[event.pid]; - - var data = event.args.data; - // 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. - // Handle JitCodeMoved and JitCodeAdded event. - if (event.name === 'JitCodeMoved') - map.moveEntry(data.code_start, data.new_code_start, data.code_len); - else // event.name === 'JitCodeAdded' - map.addEntry(data.code_start, data.code_len, data.name, data.script_id); - }, - - processMetadataEvent: function(event) { - // V8 JIT events are currently logged as phase 'M' so we need to - // separate them out and handle specially. - if (event.name === 'JitCodeAdded' || event.name === 'JitCodeMoved') { - this.v8SamplingData_.push(event); - return; - } - - // The metadata events aren't useful without args. - if (event.argsStripped) - return; - - if (event.name === 'process_name') { - var process = this.model_.getOrCreateProcess(event.pid); - process.name = event.args.name; - } else if (event.name === 'process_labels') { - var process = this.model_.getOrCreateProcess(event.pid); - var labels = event.args.labels.split(','); - for (var i = 0; i < labels.length; i++) - process.addLabelIfNeeded(labels[i]); - } else if (event.name === 'process_sort_index') { - var process = this.model_.getOrCreateProcess(event.pid); - process.sortIndex = event.args.sort_index; - } else if (event.name === 'thread_name') { - var thread = this.model_.getOrCreateProcess(event.pid). - getOrCreateThread(event.tid); - thread.name = event.args.name; - } else if (event.name === 'thread_sort_index') { - var thread = this.model_.getOrCreateProcess(event.pid). - getOrCreateThread(event.tid); - thread.sortIndex = event.args.sort_index; - } else if (event.name === 'num_cpus') { - var n = event.args.number; - // Not all render processes agree on the cpu count in trace_event. Some - // processes will report 1, while others will report the actual cpu - // count. To deal with this, take the max of what is reported. - if (this.softwareMeasuredCpuCount_ !== undefined) - n = Math.max(n, this.softwareMeasuredCpuCount_); - this.softwareMeasuredCpuCount_ = n; - } else if (event.name === 'stackFrames') { - var stackFrames = event.args.stackFrames; - if (stackFrames === undefined) { - this.model_.importWarning({ - type: 'metadata_parse_error', - message: 'No stack frames found in a \'' + event.name + - '\' metadata event' - }); - } else { - this.importStackFrames_(stackFrames, 'p' + event.pid + ':'); - } - } else if (event.name === 'typeNames') { - var objectTypeNameMap = event.args.typeNames; - if (objectTypeNameMap === undefined) { - this.model_.importWarning({ - type: 'metadata_parse_error', - message: 'No mapping from object type IDs to names found in a \'' + - event.name + '\' metadata event' - }); - } else { - this.importObjectTypeNameMap_(objectTypeNameMap, event.pid); - } - } else if (event.name === 'TraceConfig') { - this.model_.metadata.push( - {name: 'TraceConfig', value: event.args.value}); - } else { - this.model_.importWarning({ - type: 'metadata_parse_error', - message: 'Unrecognized metadata name: ' + event.name - }); - } - }, - - processInstantEvent: function(event) { - // V8 JIT events were logged as phase 'I' in the old format, - // so we need to separate them out and handle specially. - if (event.name === 'JitCodeAdded' || event.name === 'JitCodeMoved') { - this.v8SamplingData_.push(event); - return; - } - - // Thread-level instant events are treated as zero-duration slices. - if (event.s === 't' || event.s === undefined) { - this.processDurationEvent(event); - return; - } - - var constructor; - switch (event.s) { - case 'g': - constructor = tr.model.GlobalInstantEvent; - break; - case 'p': - constructor = tr.model.ProcessInstantEvent; - break; - default: - this.model_.importWarning({ - type: 'instant_parse_error', - message: 'I phase event with unknown "s" field value.' - }); - return; - } - - var instantEvent = new constructor(event.cat, event.name, - getEventColor(event), timestampFromUs(event.ts), - this.deepCopyIfNeeded_(event.args)); - - switch (instantEvent.type) { - case tr.model.InstantEventType.GLOBAL: - this.model_.instantEvents.push(instantEvent); - break; - - case tr.model.InstantEventType.PROCESS: - var process = this.model_.getOrCreateProcess(event.pid); - process.instantEvents.push(instantEvent); - break; - - default: - throw new Error('Unknown instant event type: ' + event.s); - } - }, - - processV8Sample: function(event) { - var data = event.args.data; - - // As-per DevTools, the backend sometimes creates bogus samples. Skip it. - if (data.vm_state === 'js' && !data.stack.length) - return; - - var rootStackFrame = this.v8ProcessRootStackFrame_[event.pid]; - if (!rootStackFrame) { - rootStackFrame = new tr.model.StackFrame( - undefined /* parent */, 'v8-root-stack-frame' /* id */, - '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.allocateSimple(), entry.name, - ColorScheme.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 entry = map.lookupEntry(data.stack[i]); - if (entry === undefined) { - 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.v8SamplingData_.push(event); - return; - } - - var stackFrame = this.getStackFrameForEvent_(event); - if (stackFrame === undefined) { - stackFrame = this.traceEventSampleStackFramesByName_[ - event.name]; - } - if (stackFrame === undefined) { - var id = 'te-' + tr.b.GUID.allocateSimple(); - stackFrame = new tr.model.StackFrame( - undefined, id, event.name, - ColorScheme.getColorIdForGeneralPurposeString(event.name)); - this.model_.addStackFrame(stackFrame); - 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', - timestampFromUs(event.ts), stackFrame, 1, - this.deepCopyIfNeeded_(event.args)); - this.setContextsFromThread_(thread, sample); - this.model_.samples.push(sample); - }, - - processMemoryDumpEvent: function(event) { - if (event.ph !== 'v') - throw new Error('Invalid memory dump event phase "' + event.ph + '".'); - - var dumpId = event.id; - if (dumpId === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Memory dump event (phase \'' + event.ph + - '\') without a dump ID.' - }); - return; - } - - var pid = event.pid; - if (pid === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Memory dump event (phase\'' + event.ph + '\', dump ID \'' + - dumpId + '\') without a PID.' - }); - return; - } - - // Dump ID -> PID -> [process memory dump events]. - var allEvents = this.allMemoryDumpEvents_; - - // PID -> [process memory dump events]. - var dumpIdEvents = allEvents[dumpId]; - if (dumpIdEvents === undefined) - allEvents[dumpId] = dumpIdEvents = {}; - - // [process memory dump events]. - var processEvents = dumpIdEvents[pid]; - if (processEvents === undefined) - dumpIdEvents[pid] = processEvents = []; - - processEvents.push(event); - }, - - processClockSyncEvent: function(event) { - if (event.ph !== 'c') - throw new Error('Invalid clock sync event phase "' + event.ph + '".'); - - var syncId = event.args.sync_id; - if (syncId === undefined) { - this.model_.importWarning({ - type: 'clock_sync_parse_error', - message: 'Clock sync at time ' + event.ts + ' without an ID.' - }); - return; - } - - if (event.args && event.args.issue_ts !== undefined) { - // When Chrome is the tracing controller and is the requester of the - // clock sync, the clock sync event looks like: - // - // { - // "args": { - // "sync_id": "abc123", - // "issue_ts": 12340 - // } - // "ph": "c" - // "ts": 12345 - // ... - // } - this.model_.clockSyncManager.addClockSyncMarker( - this.clockDomainId_, syncId, timestampFromUs(event.args.issue_ts), - timestampFromUs(event.ts)); - } else { - // When Chrome is a tracing agent and is the recipient of the clock - // sync request, the clock sync event looks like: - // - // { - // "args": { "sync_id": "abc123" } - // "ph": "c" - // "ts": 12345 - // ... - // } - this.model_.clockSyncManager.addClockSyncMarker( - this.clockDomainId_, syncId, timestampFromUs(event.ts)); - } - }, - - // Because the order of Jit code events and V8 samples are not guaranteed, - // We store them in an array, sort by timestamp, and then process them. - processV8Events: function() { - this.v8SamplingData_.sort(function(a, b) { - if (a.ts !== b.ts) - return a.ts - b.ts; - if (a.ph === 'M' || a.ph === 'I') - return -1; - else if (b.ph === 'M' || b.ph === 'I') - return 1; - return 0; - }); - var length = this.v8SamplingData_.length; - for (var i = 0; i < length; ++i) { - var event = this.v8SamplingData_[i]; - if (event.ph === 'M' || event.ph === 'I') { - this.processJitCodeEvent(event); - } else if (event.ph === 'P') { - this.processV8Sample(event); - } - } - }, - - importClockSyncMarkers: function() { - for (var i = 0; i < this.events_.length; i++) { - var event = this.events_[i]; - - if (event.ph !== 'c') - continue; - - var eventSizeInBytes = - this.model_.importOptions.trackDetailedModelStats ? - JSON.stringify(event).length : undefined; - - this.model_.stats.willProcessBasicTraceEvent( - 'clock_sync', event.cat, event.name, event.ts, eventSizeInBytes); - this.processClockSyncEvent(event); - } - }, - - /** - * Walks through the events_ list and outputs the structures discovered to - * model_. - */ - importEvents: function() { - if (this.stackFrameEvents_) - this.importStackFrames_(this.stackFrameEvents_, 'g'); - - if (this.traceAnnotations_) - this.importAnnotations_(); - - var importOptions = this.model_.importOptions; - var trackDetailedModelStats = importOptions.trackDetailedModelStats; - - var modelStats = this.model_.stats; - - var events = this.events_; - for (var eI = 0; eI < events.length; eI++) { - var event = events[eI]; - - if (event.args === '__stripped__') { - event.argsStripped = true; - event.args = undefined; - } - - var eventSizeInBytes; - if (trackDetailedModelStats) - eventSizeInBytes = JSON.stringify(event).length; - else - eventSizeInBytes = undefined; - - if (event.ph === 'B' || event.ph === 'E') { - modelStats.willProcessBasicTraceEvent( - 'begin_end (non-compact)', event.cat, event.name, event.ts, - eventSizeInBytes); - this.processDurationEvent(event); - - } else if (event.ph === 'X') { - modelStats.willProcessBasicTraceEvent( - 'begin_end (compact)', event.cat, event.name, event.ts, - eventSizeInBytes); - var 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') { - modelStats.willProcessBasicTraceEvent( - 'async', event.cat, event.name, event.ts, eventSizeInBytes); - this.processAsyncEvent(event); - - // 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') { - modelStats.willProcessBasicTraceEvent( - 'instant', event.cat, event.name, event.ts, eventSizeInBytes); - this.processInstantEvent(event); - - } else if (event.ph === 'P') { - modelStats.willProcessBasicTraceEvent( - 'samples', event.cat, event.name, event.ts, eventSizeInBytes); - this.processTraceSampleEvent(event); - } else if (event.ph === 'C') { - modelStats.willProcessBasicTraceEvent( - 'counters', event.cat, event.name, event.ts, eventSizeInBytes); - this.processCounterEvent(event); - } else if (event.ph === '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') { - modelStats.willProcessBasicTraceEvent( - 'objects', event.cat, event.name, event.ts, eventSizeInBytes); - this.processObjectEvent(event); - - } else if (event.ph === 's' || event.ph === 't' || event.ph === 'f') { - modelStats.willProcessBasicTraceEvent( - 'flows', event.cat, event.name, event.ts, eventSizeInBytes); - this.processFlowEvent(event); - - } else if (event.ph === 'v') { - modelStats.willProcessBasicTraceEvent( - 'memory_dumps', event.cat, event.name, event.ts, - eventSizeInBytes); - this.processMemoryDumpEvent(event); - - } else if (event.ph === '(' || event.ph === ')') { - this.processContextEvent(event); - } else if (event.ph === 'c') { - // No-op. Clock sync events have already been processed in - // importClockSyncMarkers(). - } else { - modelStats.willProcessBasicTraceEvent( - 'unknown', event.cat, event.name, event.ts, eventSizeInBytes); - this.model_.importWarning({ - type: 'parse_error', - message: 'Unrecognized event phase: ' + - event.ph + ' (' + event.name + ')' - }); - } - } - this.processV8Events(); - - // 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(rawStackFrames, idPrefix) { - var model = this.model_; - - for (var id in rawStackFrames) { - var rawStackFrame = rawStackFrames[id]; - var fullId = idPrefix + id; - var textForColor = rawStackFrame.category ? - rawStackFrame.category : rawStackFrame.name; - var stackFrame = new tr.model.StackFrame( - undefined /* parentFrame */, fullId, rawStackFrame.name, - ColorScheme.getColorIdForGeneralPurposeString(textForColor)); - model.addStackFrame(stackFrame); - } - - for (var id in rawStackFrames) { - var fullId = idPrefix + id; - var stackFrame = model.stackFrames[fullId]; - if (stackFrame === undefined) - throw new Error('Internal error'); - - var rawStackFrame = rawStackFrames[id]; - var parentId = rawStackFrame.parent; - var parentStackFrame; - if (parentId === undefined) { - parentStackFrame = undefined; - } else { - var parentFullId = idPrefix + parentId; - parentStackFrame = model.stackFrames[parentFullId]; - if (parentStackFrame === undefined) { - this.model_.importWarning({ - type: 'metadata_parse_error', - message: 'Missing parent frame with ID ' + parentFullId + - ' for stack frame \'' + stackFrame.name + '\' (ID ' + fullId + - ').' - }); - } - } - stackFrame.parentFrame = parentStackFrame; - } - }, - - importObjectTypeNameMap_: function(rawObjectTypeNameMap, pid) { - if (pid in this.objectTypeNameMap_) { - this.model_.importWarning({ - type: 'metadata_parse_error', - message: 'Mapping from object type IDs to names provided for pid=' + - pid + ' multiple times.' - }); - return; - } - - var objectTypeNamePrefix = undefined; - var objectTypeNameSuffix = undefined; - var objectTypeNameMap = {}; - for (var objectTypeId in rawObjectTypeNameMap) { - var rawObjectTypeName = rawObjectTypeNameMap[objectTypeId]; - - // If we haven't figured out yet which compiler the object type names - // come from, we try to do it now. - if (objectTypeNamePrefix === undefined) { - for (var i = 0; i < OBJECT_TYPE_NAME_PATTERNS.length; i++) { - var pattern = OBJECT_TYPE_NAME_PATTERNS[i]; - if (rawObjectTypeName.startsWith(pattern.prefix) && - rawObjectTypeName.endsWith(pattern.suffix)) { - objectTypeNamePrefix = pattern.prefix; - objectTypeNameSuffix = pattern.suffix; - break; - } - } - } - - if (objectTypeNamePrefix !== undefined && - rawObjectTypeName.startsWith(objectTypeNamePrefix) && - rawObjectTypeName.endsWith(objectTypeNameSuffix)) { - // With compiler-specific prefix and suffix (automatically annotated - // object types). - objectTypeNameMap[objectTypeId] = rawObjectTypeName.substring( - objectTypeNamePrefix.length, - rawObjectTypeName.length - objectTypeNameSuffix.length); - } else { - // Without compiler-specific prefix and suffix (manually annotated - // object types and '[unknown]'). - objectTypeNameMap[objectTypeId] = rawObjectTypeName; - } - } - - this.objectTypeNameMap_[pid] = objectTypeNameMap; - }, - - importAnnotations_: function() { - for (var id in this.traceAnnotations_) { - var annotation = tr.model.Annotation.fromDictIfPossible( - this.traceAnnotations_[id]); - if (!annotation) { - this.model_.importWarning({ - type: 'annotation_warning', - message: 'Unrecognized traceAnnotation typeName \"' + - this.traceAnnotations_[id].typeName + '\"' - }); - continue; - } - this.model_.addAnnotation(annotation); - } - }, - - /** - * Called by the Model after all other importers have imported their - * events. - */ - finalizeImport: function() { - if (this.softwareMeasuredCpuCount_ !== undefined) { - this.model_.kernel.softwareMeasuredCpuCount = - this.softwareMeasuredCpuCount_; - } - this.createAsyncSlices_(); - this.createFlowSlices_(); - this.createExplicitObjects_(); - this.createImplicitObjects_(); - this.createMemoryDumps_(); - }, - - /* Events can have one or more stack frames associated with them, but - * that frame might be encoded either as a stack trace of program counters, - * or as a direct stack frame reference. This handles either case and - * if found, returns the stackframe. - */ - getStackFrameForEvent_: function(event, opt_lookForEndEvent) { - var sf; - var stack; - if (opt_lookForEndEvent) { - sf = event.esf; - stack = event.estack; - } else { - sf = event.sf; - stack = event.stack; - } - if (stack !== undefined && sf !== undefined) { - this.model_.importWarning({ - type: 'stack_frame_and_stack_error', - message: 'Event at ' + event.ts + - ' cannot have both a stack and a stackframe.' - }); - return undefined; - } - - if (stack !== undefined) - return this.model_.resolveStackToStackFrame_(event.pid, stack); - if (sf === undefined) - return undefined; - - var stackFrame = this.model_.stackFrames['g' + sf]; - if (stackFrame === undefined) { - this.model_.importWarning({ - type: 'sample_import_error', - message: 'No frame for ' + sf - }); - return; - } - return stackFrame; - }, - - resolveStackToStackFrame_: function(pid, stack) { - // TODO(alph,fmeawad): Add codemap resolution code here. - return undefined; - }, - - importSampleData: function() { - if (!this.sampleEvents_) - return; - var m = this.model_; - - // If this is the only importer, then fake-create the threads. - var events = this.sampleEvents_; - if (this.events_.length === 0) { - for (var i = 0; i < events.length; i++) { - var event = events[i]; - m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid); - } - } - - var threadsByTid = {}; - m.getAllThreads().forEach(function(t) { - threadsByTid[t.tid] = t; - }); - - for (var i = 0; i < events.length; i++) { - var event = events[i]; - var thread = threadsByTid[event.tid]; - if (thread === undefined) { - m.importWarning({ - type: 'sample_import_error', - message: 'Thread ' + events.tid + 'not found' - }); - continue; - } - - var cpu; - if (event.cpu !== undefined) - cpu = m.kernel.getOrCreateCpu(event.cpu); - - var stackFrame = this.getStackFrameForEvent_(event); - - var sample = new tr.model.Sample( - cpu, thread, - event.name, - timestampFromUs(event.ts), - stackFrame, - event.weight); - m.samples.push(sample); - } - }, - - createAsyncSlices_: function() { - if (this.allAsyncEvents_.length === 0) - return; - - this.allAsyncEvents_.sort(function(x, y) { - var d = x.event.ts - y.event.ts; - if (d !== 0) - return d; - return x.sequenceNumber - y.sequenceNumber; - }); - - var legacyEvents = []; - // Group nestable async events by ID. Events with the same ID should - // belong to the same parent async event. - var nestableAsyncEventsByKey = {}; - var nestableMeasureAsyncEventsByKey = {}; - for (var i = 0; i < this.allAsyncEvents_.length; i++) { - var asyncEventState = this.allAsyncEvents_[i]; - var event = asyncEventState.event; - if (event.ph === 'S' || event.ph === 'F' || event.ph === 'T' || - event.ph === 'p') { - legacyEvents.push(asyncEventState); - continue; - } - if (event.cat === undefined) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'Nestable async events (ph: b, e, or n) require a ' + - 'cat parameter.' - }); - continue; - } - - if (event.name === undefined) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'Nestable async events (ph: b, e, or n) require a ' + - 'name parameter.' - }); - continue; - } - - if (event.id === undefined) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'Nestable async events (ph: b, e, or n) require an ' + - 'id parameter.' - }); - continue; - } - - if (event.cat === 'blink.user_timing') { - var matched = /([^\/:]+):([^\/:]+)\/?(.*)/.exec(event.name); - if (matched !== null) { - var key = matched[1] + ':' + event.cat; - event.args = JSON.parse(Base64.atob(matched[3]) || '{}'); - if (nestableMeasureAsyncEventsByKey[key] === undefined) - nestableMeasureAsyncEventsByKey[key] = []; - nestableMeasureAsyncEventsByKey[key].push(asyncEventState); - continue; - } - } - - var key = event.cat + ':' + event.id; - if (nestableAsyncEventsByKey[key] === undefined) - nestableAsyncEventsByKey[key] = []; - nestableAsyncEventsByKey[key].push(asyncEventState); - } - // Handle legacy async events. - this.createLegacyAsyncSlices_(legacyEvents); - - // Parse nestable measure async events into AsyncSlices. - this.createNestableAsyncSlices_(nestableMeasureAsyncEventsByKey); - - // Parse nestable async events into AsyncSlices. - this.createNestableAsyncSlices_(nestableAsyncEventsByKey); - }, - - createLegacyAsyncSlices_: function(legacyEvents) { - if (legacyEvents.length === 0) - return; - - legacyEvents.sort(function(x, y) { - var d = x.event.ts - y.event.ts; - if (d != 0) - return d; - return x.sequenceNumber - y.sequenceNumber; - }); - - var asyncEventStatesByNameThenID = {}; - - for (var i = 0; i < legacyEvents.length; i++) { - var asyncEventState = legacyEvents[i]; - - var event = asyncEventState.event; - var name = event.name; - if (name === undefined) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'Async events (ph: S, T, p, or F) require a name ' + - ' parameter.' - }); - continue; - } - - var id = event.id; - if (id === undefined) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'Async events (ph: S, T, p, or F) require an id parameter.' - }); - continue; - } - - // TODO(simonjam): Add a synchronous tick on the appropriate thread. - - if (event.ph === 'S') { - if (asyncEventStatesByNameThenID[name] === undefined) - asyncEventStatesByNameThenID[name] = {}; - if (asyncEventStatesByNameThenID[name][id]) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'At ' + event.ts + ', a slice of the same id ' + id + - ' was alrady open.' - }); - continue; - } - asyncEventStatesByNameThenID[name][id] = []; - asyncEventStatesByNameThenID[name][id].push(asyncEventState); - } else { - if (asyncEventStatesByNameThenID[name] === undefined) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'At ' + event.ts + ', no slice named ' + name + - ' was open.' - }); - continue; - } - if (asyncEventStatesByNameThenID[name][id] === undefined) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'At ' + event.ts + ', no slice named ' + name + - ' with id=' + id + ' was open.' - }); - continue; - } - var events = asyncEventStatesByNameThenID[name][id]; - events.push(asyncEventState); - - if (event.ph === 'F') { - // Create a slice from start to end. - var asyncSliceConstructor = - tr.model.AsyncSlice.getConstructor( - events[0].event.cat, - name); - var slice = new asyncSliceConstructor( - events[0].event.cat, - name, - getEventColor(events[0].event), - timestampFromUs(events[0].event.ts), - tr.b.concatenateObjects(events[0].event.args, - events[events.length - 1].event.args), - timestampFromUs(event.ts - events[0].event.ts), - true, undefined, undefined, events[0].event.argsStripped); - slice.startThread = events[0].thread; - slice.endThread = asyncEventState.thread; - slice.id = id; - - var stepType = events[1].event.ph; - var isValid = true; - - // Create subSlices for each step. Skip the start and finish events, - // which are always first and last respectively. - for (var j = 1; j < events.length - 1; ++j) { - if (events[j].event.ph === 'T' || events[j].event.ph === 'p') { - isValid = this.assertStepTypeMatches_(stepType, events[j]); - if (!isValid) - break; - } - - if (events[j].event.ph === 'S') { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'At ' + event.event.ts + ', a slice named ' + - event.event.name + ' with id=' + event.event.id + - ' had a step before the start event.' - }); - continue; - } - - if (events[j].event.ph === 'F') { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'At ' + event.event.ts + ', a slice named ' + - event.event.name + ' with id=' + event.event.id + - ' had a step after the finish event.' - }); - continue; - } - - var startIndex = j + (stepType === 'T' ? 0 : -1); - var endIndex = startIndex + 1; - - var subName = events[j].event.name; - if (!events[j].event.argsStripped && - (events[j].event.ph === 'T' || events[j].event.ph === 'p')) - subName = subName + ':' + events[j].event.args.step; - - var asyncSliceConstructor = - tr.model.AsyncSlice.getConstructor( - events[0].event.cat, - subName); - var subSlice = new asyncSliceConstructor( - events[0].event.cat, - subName, - getEventColor(event, subName + j), - timestampFromUs(events[startIndex].event.ts), - this.deepCopyIfNeeded_(events[j].event.args), - timestampFromUs( - events[endIndex].event.ts - events[startIndex].event.ts), - undefined, undefined, - events[startIndex].event.argsStripped); - subSlice.startThread = events[startIndex].thread; - subSlice.endThread = events[endIndex].thread; - subSlice.id = id; - - slice.subSlices.push(subSlice); - } - - if (isValid) { - // Add |slice| to the start-thread's asyncSlices. - slice.startThread.asyncSliceGroup.push(slice); - } - - delete asyncEventStatesByNameThenID[name][id]; - } - } - } - }, - - createNestableAsyncSlices_: function(nestableEventsByKey) { - for (var key in nestableEventsByKey) { - var eventStateEntries = nestableEventsByKey[key]; - // Stack of enclosing BEGIN events. - var parentStack = []; - for (var i = 0; i < eventStateEntries.length; ++i) { - var eventStateEntry = eventStateEntries[i]; - // If this is the end of an event, match it to the start. - if (eventStateEntry.event.ph === 'e') { - // Walk up the parent stack to find the corresponding BEGIN for - // this END. - var parentIndex = -1; - for (var k = parentStack.length - 1; k >= 0; --k) { - if (parentStack[k].event.name === eventStateEntry.event.name) { - parentIndex = k; - break; - } - } - if (parentIndex === -1) { - // Unmatched end. - eventStateEntry.finished = false; - } else { - parentStack[parentIndex].end = eventStateEntry; - // Pop off all enclosing unmatched BEGINs util parentIndex. - while (parentIndex < parentStack.length) { - parentStack.pop(); - } - } - } - // Inherit the current parent. - if (parentStack.length > 0) - eventStateEntry.parentEntry = parentStack[parentStack.length - 1]; - if (eventStateEntry.event.ph === 'b') { - parentStack.push(eventStateEntry); - } - } - var topLevelSlices = []; - for (var i = 0; i < eventStateEntries.length; ++i) { - var eventStateEntry = eventStateEntries[i]; - // Skip matched END, as its slice will be created when we - // encounter its corresponding BEGIN. - if (eventStateEntry.event.ph === 'e' && - eventStateEntry.finished === undefined) { - continue; - } - var startState = undefined; - var endState = undefined; - var sliceArgs = eventStateEntry.event.args || {}; - var sliceError = undefined; - if (eventStateEntry.event.ph === 'n') { - startState = eventStateEntry; - endState = eventStateEntry; - } else if (eventStateEntry.event.ph === 'b') { - if (eventStateEntry.end === undefined) { - // Unmatched BEGIN. End it when last event with this ID ends. - eventStateEntry.end = - eventStateEntries[eventStateEntries.length - 1]; - sliceError = - 'Slice has no matching END. End time has been adjusted.'; - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'Nestable async BEGIN event at ' + - eventStateEntry.event.ts + ' with name=' + - eventStateEntry.event.name + - ' and id=' + eventStateEntry.event.id + ' was unmatched.' - }); - } else { - // Include args for both END and BEGIN for a matched pair. - 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. - var args3 = {}; - args3.params = tr.b.concatenateObjects(args1.params, - args2.params); - return tr.b.concatenateObjects(args1, args2, args3); - } - var endArgs = eventStateEntry.end.event.args || {}; - sliceArgs = concatenateArguments(sliceArgs, endArgs); - } - startState = eventStateEntry; - endState = eventStateEntry.end; - } else { - // Unmatched END. Start it at the first event with this ID starts. - sliceError = - 'Slice has no matching BEGIN. Start time has been adjusted.'; - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'Nestable async END event at ' + - eventStateEntry.event.ts + ' with name=' + - eventStateEntry.event.name + - ' and id=' + eventStateEntry.event.id + ' was unmatched.' - }); - startState = eventStateEntries[0]; - endState = eventStateEntry; - } - - var isTopLevel = (eventStateEntry.parentEntry === undefined); - var asyncSliceConstructor = - tr.model.AsyncSlice.getConstructor( - eventStateEntry.event.cat, - eventStateEntry.event.name); - - var thread_start = undefined; - var thread_duration = undefined; - if (startState.event.tts && startState.event.use_async_tts) { - thread_start = timestampFromUs(startState.event.tts); - if (endState.event.tts) { - var thread_end = timestampFromUs(endState.event.tts); - thread_duration = thread_end - thread_start; - } - } - - var slice = new asyncSliceConstructor( - eventStateEntry.event.cat, - eventStateEntry.event.name, - getEventColor(endState.event), - timestampFromUs(startState.event.ts), - sliceArgs, - timestampFromUs(endState.event.ts - startState.event.ts), - isTopLevel, - thread_start, - thread_duration, - startState.event.argsStripped); - - slice.startThread = startState.thread; - slice.endThread = endState.thread; - - slice.startStackFrame = this.getStackFrameForEvent_(startState.event); - slice.endStackFrame = this.getStackFrameForEvent_(endState.event); - - slice.id = key; - if (sliceError !== undefined) - slice.error = sliceError; - eventStateEntry.slice = slice; - // Add the slice to the topLevelSlices array if there is no parent. - // Otherwise, add the slice to the subSlices of its parent. - if (isTopLevel) { - topLevelSlices.push(slice); - } else if (eventStateEntry.parentEntry.slice !== undefined) { - eventStateEntry.parentEntry.slice.subSlices.push(slice); - } - } - for (var si = 0; si < topLevelSlices.length; si++) { - topLevelSlices[si].startThread.asyncSliceGroup.push( - topLevelSlices[si]); - } - } - }, - - assertStepTypeMatches_: function(stepType, event) { - if (stepType != event.event.ph) { - this.model_.importWarning({ - type: 'async_slice_parse_error', - message: 'At ' + event.event.ts + ', a slice named ' + - event.event.name + ' with id=' + event.event.id + - ' had both begin and end steps, which is not allowed.' - }); - return false; - } - return true; - }, - - createFlowSlices_: function() { - if (this.allFlowEvents_.length === 0) - return; - - var that = this; - - function validateFlowEvent() { - if (event.name === undefined) { - that.model_.importWarning({ - type: 'flow_slice_parse_error', - message: 'Flow events (ph: s, t or f) require a name parameter.' - }); - return false; - } - - // Support Flow API v1. - if (event.ph === 's' || event.ph === 'f' || event.ph === 't') { - if (event.id === undefined) { - that.model_.importWarning({ - type: 'flow_slice_parse_error', - message: 'Flow events (ph: s, t or f) require an id parameter.' - }); - return false; - } - return true; - } - - // Support Flow API v2. - if (event.bind_id) { - if (event.flow_in === undefined && event.flow_out === undefined) { - that.model_.importWarning({ - type: 'flow_slice_parse_error', - message: 'Flow producer or consumer require flow_in or flow_out.' - }); - return false; - } - return true; - } - - return false; - } - - function createFlowEvent(thread, event, opt_slice) { - var startSlice, flowId, flowStartTs; - - if (event.bind_id) { - // Support Flow API v2. - startSlice = opt_slice; - flowId = event.bind_id; - flowStartTs = timestampFromUs(event.ts + event.dur); - } else { - // Support Flow API v1. - var ts = timestampFromUs(event.ts); - startSlice = thread.sliceGroup.findSliceAtTs(ts); - if (startSlice === undefined) - return undefined; - flowId = event.id; - flowStartTs = ts; - } - - var flowEvent = new tr.model.FlowEvent( - event.cat, - flowId, - event.name, - getEventColor(event), - flowStartTs, - that.deepCopyAlways_(event.args)); - flowEvent.startSlice = startSlice; - flowEvent.startStackFrame = that.getStackFrameForEvent_(event); - flowEvent.endStackFrame = undefined; - startSlice.outFlowEvents.push(flowEvent); - return flowEvent; - } - - function finishFlowEventWith(flowEvent, thread, event, - refGuid, bindToParent, opt_slice) { - var endSlice; - - if (event.bind_id) { - // Support Flow API v2. - endSlice = opt_slice; - } else { - // Support Flow API v1. - var ts = timestampFromUs(event.ts); - if (bindToParent) { - endSlice = thread.sliceGroup.findSliceAtTs(ts); - } else { - endSlice = thread.sliceGroup.findNextSliceAfter(ts, refGuid); - } - if (endSlice === undefined) - return false; - } - - endSlice.inFlowEvents.push(flowEvent); - flowEvent.endSlice = endSlice; - flowEvent.duration = timestampFromUs(event.ts) - flowEvent.start; - flowEvent.endStackFrame = that.getStackFrameForEvent_(event); - that.mergeArgsInto_(flowEvent.args, event.args, flowEvent.title); - return true; - } - - function processFlowConsumer(flowIdToEvent, sliceGuidToEvent, event, - slice) { - var flowEvent = flowIdToEvent[event.bind_id]; - if (flowEvent === undefined) { - that.model_.importWarning({ - type: 'flow_slice_ordering_error', - message: 'Flow consumer ' + event.bind_id + ' does not have ' + - 'a flow producer'}); - return false; - } else if (flowEvent.endSlice) { - // One flow producer can have more than one flow consumers. - // In this case, create a new flow event using the flow producer. - var flowProducer = flowEvent.startSlice; - flowEvent = createFlowEvent(undefined, - sliceGuidToEvent[flowProducer.guid], flowProducer); - } - - var ok = finishFlowEventWith(flowEvent, undefined, event, - refGuid, undefined, slice); - if (ok) { - that.model_.flowEvents.push(flowEvent); - } else { - that.model_.importWarning({ - type: 'flow_slice_end_error', - message: 'Flow consumer ' + event.bind_id + ' does not end ' + - 'at an actual slice, so cannot be created.'}); - return false; - } - - return true; - } - - function processFlowProducer(flowIdToEvent, flowStatus, event, slice) { - if (flowIdToEvent[event.bind_id] && - flowStatus[event.bind_id]) { - // Can't open the same flow again while it's still open. - // This is essentially the multi-producer case which we don't support - that.model_.importWarning({ - type: 'flow_slice_start_error', - message: 'Flow producer ' + event.bind_id + ' already seen'}); - return false; - } - - var flowEvent = createFlowEvent(undefined, event, slice); - if (!flowEvent) { - that.model_.importWarning({ - type: 'flow_slice_start_error', - message: 'Flow producer ' + event.bind_id + ' does not start' + - 'a flow'}); - return false; - } - flowIdToEvent[event.bind_id] = flowEvent; - - return; - } - - // Actual import. - this.allFlowEvents_.sort(function(x, y) { - var d = x.event.ts - y.event.ts; - if (d != 0) - return d; - return x.sequenceNumber - y.sequenceNumber; - }); - - var flowIdToEvent = {}; - var sliceGuidToEvent = {}; - var flowStatus = {}; // true: open; false: closed. - for (var i = 0; i < this.allFlowEvents_.length; ++i) { - var data = this.allFlowEvents_[i]; - var refGuid = data.refGuid; - var event = data.event; - var thread = data.thread; - if (!validateFlowEvent(event)) - continue; - - // Support for Flow API v2. - if (event.bind_id) { - var slice = data.slice; - sliceGuidToEvent[slice.guid] = event; - - if (event.flowPhase === PRODUCER) { - if (!processFlowProducer(flowIdToEvent, flowStatus, event, slice)) - continue; - flowStatus[event.bind_id] = true; // open the flow. - } - else { - if (!processFlowConsumer(flowIdToEvent, sliceGuidToEvent, - event, slice)) - continue; - flowStatus[event.bind_id] = false; // close the flow. - - if (event.flowPhase === STEP) { - if (!processFlowProducer(flowIdToEvent, flowStatus, - event, slice)) - continue; - flowStatus[event.bind_id] = true; // open the flow again. - } - } - continue; - } - - // Support for Flow API v1. - var flowEvent; - if (event.ph === 's') { - if (flowIdToEvent[event.id]) { - this.model_.importWarning({ - type: 'flow_slice_start_error', - message: 'event id ' + event.id + ' already seen when ' + - 'encountering start of flow event.'}); - continue; - } - flowEvent = createFlowEvent(thread, event); - if (!flowEvent) { - this.model_.importWarning({ - type: 'flow_slice_start_error', - message: 'event id ' + event.id + ' does not start ' + - 'at an actual slice, so cannot be created.'}); - continue; - } - flowIdToEvent[event.id] = flowEvent; - - } else if (event.ph === 't' || event.ph === 'f') { - flowEvent = flowIdToEvent[event.id]; - if (flowEvent === undefined) { - this.model_.importWarning({ - type: 'flow_slice_ordering_error', - message: 'Found flow phase ' + event.ph + ' for id: ' + event.id + - ' but no flow start found.' - }); - continue; - } - - var bindToParent = event.ph === 't'; - - if (event.ph === 'f') { - if (event.bp === undefined) { - // TODO(yuhaoz): In flow V2, there is no notion of binding point. - // Removal of binding point is tracked in - // https://github.com/google/trace-viewer/issues/991. - if (event.cat.indexOf('input') > -1) - bindToParent = true; - else if (event.cat.indexOf('ipc.flow') > -1) - bindToParent = true; - } else { - if (event.bp !== 'e') { - this.model_.importWarning({ - type: 'flow_slice_bind_point_error', - message: 'Flow event with invalid binding point (event.bp).' - }); - continue; - } - bindToParent = true; - } - } - - var ok = finishFlowEventWith(flowEvent, thread, event, - refGuid, bindToParent); - if (ok) { - that.model_.flowEvents.push(flowEvent); - } else { - this.model_.importWarning({ - type: 'flow_slice_end_error', - message: 'event id ' + event.id + ' does not end ' + - 'at an actual slice, so cannot be created.'}); - } - flowIdToEvent[event.id] = undefined; - - // If this is a step, then create another flow event. - if (ok && event.ph === 't') { - flowEvent = createFlowEvent(thread, event); - flowIdToEvent[event.id] = flowEvent; - } - } - } - }, - - /** - * This function creates objects described via the N, D, and O phase - * events. - */ - createExplicitObjects_: function() { - if (this.allObjectEvents_.length === 0) - return; - - function processEvent(objectEventState) { - var event = objectEventState.event; - var scopedId = this.scopedIdForEvent_(event); - var thread = objectEventState.thread; - if (event.name === undefined) { - this.model_.importWarning({ - type: 'object_parse_error', - message: 'While processing ' + JSON.stringify(event) + ': ' + - 'Object events require an name parameter.' - }); - } - - if (scopedId.id === undefined) { - this.model_.importWarning({ - type: 'object_parse_error', - message: 'While processing ' + JSON.stringify(event) + ': ' + - 'Object events require an id parameter.' - }); - } - var process = thread.parent; - var ts = timestampFromUs(event.ts); - var instance; - if (event.ph === 'N') { - try { - instance = process.objects.idWasCreated( - scopedId, event.cat, event.name, ts); - } catch (e) { - this.model_.importWarning({ - type: 'object_parse_error', - message: 'While processing create of ' + - scopedId + ' at ts=' + ts + ': ' + e - }); - return; - } - } else if (event.ph === 'O') { - if (event.args.snapshot === undefined) { - this.model_.importWarning({ - type: 'object_parse_error', - message: 'While processing ' + scopedId + ' at ts=' + ts + ': ' + - 'Snapshots must have args: {snapshot: ...}' - }); - return; - } - var snapshot; - try { - var args = this.deepCopyIfNeeded_(event.args.snapshot); - var cat; - if (args.cat) { - cat = args.cat; - delete args.cat; - } else { - cat = event.cat; - } - - var baseTypename; - if (args.base_type) { - baseTypename = args.base_type; - delete args.base_type; - } else { - baseTypename = undefined; - } - snapshot = process.objects.addSnapshot( - scopedId, cat, event.name, ts, args, baseTypename); - snapshot.snapshottedOnThread = thread; - } catch (e) { - this.model_.importWarning({ - type: 'object_parse_error', - message: 'While processing snapshot of ' + - scopedId + ' at ts=' + ts + ': ' + e - }); - return; - } - instance = snapshot.objectInstance; - } else if (event.ph === 'D') { - try { - process.objects.idWasDeleted(scopedId, event.cat, event.name, ts); - var instanceMap = process.objects.getOrCreateInstanceMap_(scopedId); - instance = instanceMap.lastInstance; - } catch (e) { - this.model_.importWarning({ - type: 'object_parse_error', - message: 'While processing delete of ' + - scopedId + ' at ts=' + ts + ': ' + e - }); - return; - } - } - - if (instance) - instance.colorId = getEventColor(event, instance.typeName); - } - - this.allObjectEvents_.sort(function(x, y) { - var d = x.event.ts - y.event.ts; - if (d != 0) - return d; - return x.sequenceNumber - y.sequenceNumber; - }); - - var allObjectEvents = this.allObjectEvents_; - for (var i = 0; i < allObjectEvents.length; i++) { - var objectEventState = allObjectEvents[i]; - try { - processEvent.call(this, objectEventState); - } catch (e) { - this.model_.importWarning({ - type: 'object_parse_error', - message: e.message - }); - } - } - }, - - createImplicitObjects_: function() { - tr.b.iterItems(this.model_.processes, function(pid, process) { - this.createImplicitObjectsForProcess_(process); - }, this); - }, - - // Here, we collect all the snapshots that internally contain a - // Javascript-level object inside their args list that has an "id" field, - // and turn that into a snapshot of the instance referred to by id. - createImplicitObjectsForProcess_: function(process) { - - function processField(referencingObject, - referencingObjectFieldName, - referencingObjectFieldValue, - containingSnapshot) { - if (!referencingObjectFieldValue) - return; - - if (referencingObjectFieldValue instanceof - tr.model.ObjectSnapshot) - return null; - if (referencingObjectFieldValue.id === undefined) - return; - - var implicitSnapshot = referencingObjectFieldValue; - - var rawId = implicitSnapshot.id; - var m = /(.+)\/(.+)/.exec(rawId); - if (!m) - throw new Error('Implicit snapshots must have names.'); - delete implicitSnapshot.id; - var name = m[1]; - var id = m[2]; - var res; - - var cat; - if (implicitSnapshot.cat !== undefined) - cat = implicitSnapshot.cat; - else - cat = containingSnapshot.objectInstance.category; - - var baseTypename; - if (implicitSnapshot.base_type) - baseTypename = implicitSnapshot.base_type; - else - baseTypename = undefined; - - var scope = containingSnapshot.objectInstance.scopedId.scope; - - try { - res = process.objects.addSnapshot( - new tr.model.ScopedId(scope, id), cat, - name, containingSnapshot.ts, - implicitSnapshot, baseTypename); - } catch (e) { - this.model_.importWarning({ - type: 'object_snapshot_parse_error', - message: 'While processing implicit snapshot of ' + - rawId + ' at ts=' + containingSnapshot.ts + ': ' + e - }); - return; - } - res.objectInstance.hasImplicitSnapshots = true; - res.containingSnapshot = containingSnapshot; - res.snapshottedOnThread = containingSnapshot.snapshottedOnThread; - referencingObject[referencingObjectFieldName] = res; - if (!(res instanceof tr.model.ObjectSnapshot)) - throw new Error('Created object must be instanceof snapshot'); - return res.args; - } - - /** - * Iterates over the fields in the object, calling func for every - * field/value found. - * - * @return {object} If the function does not want the field's value to be - * iterated, return null. If iteration of the field value is desired, then - * return either undefined (if the field value did not change) or the new - * field value if it was changed. - */ - function iterObject(object, func, containingSnapshot, thisArg) { - if (!(object instanceof Object)) - return; - - if (object instanceof Array) { - for (var i = 0; i < object.length; i++) { - var res = func.call(thisArg, object, i, object[i], - containingSnapshot); - if (res === null) - continue; - if (res) - iterObject(res, func, containingSnapshot, thisArg); - else - iterObject(object[i], func, containingSnapshot, thisArg); - } - return; - } - - for (var key in object) { - var res = func.call(thisArg, object, key, object[key], - containingSnapshot); - if (res === null) - continue; - if (res) - iterObject(res, func, containingSnapshot, thisArg); - else - iterObject(object[key], func, containingSnapshot, thisArg); - } - } - - // TODO(nduca): We may need to iterate the instances in sorted order by - // creationTs. - process.objects.iterObjectInstances(function(instance) { - instance.snapshots.forEach(function(snapshot) { - if (snapshot.args.id !== undefined) - throw new Error('args cannot have an id field inside it'); - iterObject(snapshot.args, processField, snapshot, this); - }, this); - }, this); - }, - - createMemoryDumps_: function() { - for (var dumpId in this.allMemoryDumpEvents_) - this.createGlobalMemoryDump_(this.allMemoryDumpEvents_[dumpId], dumpId); - }, - - createGlobalMemoryDump_: function(dumpIdEvents, dumpId) { - // 1. Create a GlobalMemoryDump for the provided process memory dump - // the events, all of which have the same dump ID. - - // Calculate the range of the global memory dump. - var globalRange = new tr.b.Range(); - for (var pid in dumpIdEvents) { - var processEvents = dumpIdEvents[pid]; - for (var i = 0; i < processEvents.length; i++) - globalRange.addValue(timestampFromUs(processEvents[i].ts)); - } - if (globalRange.isEmpty) - throw new Error('Internal error: Global memory dump without events'); - - // Create the global memory dump. - var globalMemoryDump = new tr.model.GlobalMemoryDump( - this.model_, globalRange.min); - globalMemoryDump.duration = globalRange.range; - this.model_.globalMemoryDumps.push(globalMemoryDump); - - var globalMemoryAllocatorDumpsByFullName = {}; - var levelsOfDetail = {}; - var allMemoryAllocatorDumpsByGuid = {}; - - // 2. Create a ProcessMemoryDump for each PID in the provided process - // memory dump events. Everything except for edges between memory - // allocator dumps is parsed from the process memory dump trace events at - // this step. - for (var pid in dumpIdEvents) { - this.createProcessMemoryDump_(globalMemoryDump, - globalMemoryAllocatorDumpsByFullName, levelsOfDetail, - allMemoryAllocatorDumpsByGuid, dumpIdEvents[pid], pid, dumpId); - } - - // 3. Set the level of detail and memory allocator dumps of the - // GlobalMemoryDump, which come from the process memory dump trace - // events parsed in the prebvious step. - globalMemoryDump.levelOfDetail = levelsOfDetail.global; - - // Find the root allocator dumps and establish the parent links of - // the global memory dump. - globalMemoryDump.memoryAllocatorDumps = - this.inferMemoryAllocatorDumpTree_( - globalMemoryAllocatorDumpsByFullName); - - // 4. Finally, parse the edges between all memory allocator dumps within - // the GlobalMemoryDump. This can only be done once all memory allocator - // dumps have been parsed (i.e. it is necessary to iterate over the - // process memory dump trace events once more). - this.parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid, - dumpIdEvents, dumpId); - }, - - createProcessMemoryDump_: function(globalMemoryDump, - globalMemoryAllocatorDumpsByFullName, levelsOfDetail, - allMemoryAllocatorDumpsByGuid, processEvents, pid, dumpId) { - // Calculate the range of the process memory dump. - var processRange = new tr.b.Range(); - for (var i = 0; i < processEvents.length; i++) - processRange.addValue(timestampFromUs(processEvents[i].ts)); - if (processRange.isEmpty) - throw new Error('Internal error: Process memory dump without events'); - - // Create the process memory dump. - var process = this.model_.getOrCreateProcess(pid); - var processMemoryDump = new tr.model.ProcessMemoryDump( - globalMemoryDump, process, processRange.min); - processMemoryDump.duration = processRange.range; - process.memoryDumps.push(processMemoryDump); - globalMemoryDump.processMemoryDumps[pid] = processMemoryDump; - - var processMemoryAllocatorDumpsByFullName = {}; - - // Parse all process memory dump trace events for the newly created - // ProcessMemoryDump. - for (var i = 0; i < processEvents.length; i++) { - var processEvent = processEvents[i]; - - var dumps = processEvent.args.dumps; - if (dumps === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: '\'dumps\' field not found in a process memory dump' + - ' event for PID=' + pid + ' and dump ID=' + dumpId + '.' - }); - continue; - } - - // Totals, VM regions, and heap dumps for the newly created - // ProcessMemoryDump should be present in at most one event, so they - // can be added to the ProcessMemoryDump immediately. - this.parseMemoryDumpTotals_(processMemoryDump, dumps, pid, dumpId); - this.parseMemoryDumpVmRegions_(processMemoryDump, dumps, pid, dumpId); - this.parseMemoryDumpHeapDumps_(processMemoryDump, dumps, pid, dumpId); - - // All process memory dump trace events for the newly created - // ProcessMemoryDump must be processed before level of detail and - // allocator dumps can be added to it. - this.parseMemoryDumpLevelOfDetail_(levelsOfDetail, dumps, pid, - dumpId); - this.parseMemoryDumpAllocatorDumps_(processMemoryDump, globalMemoryDump, - processMemoryAllocatorDumpsByFullName, - globalMemoryAllocatorDumpsByFullName, - allMemoryAllocatorDumpsByGuid, dumps, pid, dumpId); - } - - if (levelsOfDetail.process === undefined) { - // Infer level of detail from the presence of VM regions in legacy - // traces (where raw process memory dump events don't contain the - // level_of_detail field). - levelsOfDetail.process = processMemoryDump.vmRegions ? DETAILED : LIGHT; - } - if (!this.updateMemoryDumpLevelOfDetail_( - levelsOfDetail, 'global', levelsOfDetail.process)) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'diffent levels of detail provided for global memory' + - ' dump (dump ID=' + dumpId + ').' - }); - } - processMemoryDump.levelOfDetail = levelsOfDetail.process; - delete levelsOfDetail.process; // Reused for all process dumps. - - // Find the root allocator dumps and establish the parent links of - // the process memory dump. - processMemoryDump.memoryAllocatorDumps = - this.inferMemoryAllocatorDumpTree_( - processMemoryAllocatorDumpsByFullName); - }, - - parseMemoryDumpTotals_: function(processMemoryDump, dumps, pid, dumpId) { - var rawTotals = dumps.process_totals; - if (rawTotals === undefined) - return; - - if (processMemoryDump.totals !== undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Process totals provided multiple times for' + - ' process memory dump for PID=' + pid + - ' and dump ID=' + dumpId + '.' - }); - return; - } - - var totals = {}; - var platformSpecificTotals = undefined; - - for (var rawTotalName in rawTotals) { - var rawTotalValue = rawTotals[rawTotalName]; - if (rawTotalValue === undefined) - continue; - - // Total resident bytes. - if (rawTotalName === 'resident_set_bytes') { - totals.residentBytes = parseInt(rawTotalValue, 16); - continue; - } - - // Peak resident bytes. - if (rawTotalName === 'peak_resident_set_bytes') { - totals.peakResidentBytes = parseInt(rawTotalValue, 16); - continue; - } - if (rawTotalName === 'is_peak_rss_resetable') { - totals.arePeakResidentBytesResettable = !!rawTotalValue; - continue; - } - - // OS-specific totals (e.g. private resident on Mac). - if (platformSpecificTotals === undefined) { - platformSpecificTotals = {}; - totals.platformSpecific = platformSpecificTotals; - } - platformSpecificTotals[rawTotalName] = parseInt(rawTotalValue, 16); - } - - // Either both peak_resident_set_bytes and is_peak_rss_resetable should - // be present in the trace, or neither. - if (totals.peakResidentBytes === undefined && - totals.arePeakResidentBytesResettable !== undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Optional field peak_resident_set_bytes found' + - ' but is_peak_rss_resetable not found in' + - ' process memory dump for PID=' + pid + - ' and dump ID=' + dumpId + '.' - }); - } - if (totals.arePeakResidentBytesResettable !== undefined && - totals.peakResidentBytes === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Optional field is_peak_rss_resetable found' + - ' but peak_resident_set_bytes not found in' + - ' process memory dump for PID=' + pid + - ' and dump ID=' + dumpId + '.' - }); - } - - processMemoryDump.totals = totals; - }, - - parseMemoryDumpVmRegions_: function(processMemoryDump, dumps, pid, dumpId) { - var rawProcessMmaps = dumps.process_mmaps; - if (rawProcessMmaps === undefined) - return; - - var rawVmRegions = rawProcessMmaps.vm_regions; - if (rawVmRegions === undefined) - return; - - if (processMemoryDump.vmRegions !== undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'VM regions provided multiple times for' + - ' process memory dump for PID=' + pid + - ' and dump ID=' + dumpId + '.' - }); - return; - } - - // See //base/trace_event/process_memory_maps.cc in Chromium. - var vmRegions = new Array(rawVmRegions.length); - for (var i = 0; i < rawVmRegions.length; i++) { - var rawVmRegion = rawVmRegions[i]; - - var byteStats = {}; - var rawByteStats = rawVmRegion.bs; - for (var rawByteStatName in rawByteStats) { - var rawByteStatValue = rawByteStats[rawByteStatName]; - if (rawByteStatValue === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Byte stat \'' + rawByteStatName + '\' of VM region ' + - i + ' (' + rawVmRegion.mf + ') in process memory dump for ' + - 'PID=' + pid + ' and dump ID=' + dumpId + - ' does not have a value.' - }); - continue; - } - var byteStatName = BYTE_STAT_NAME_MAP[rawByteStatName]; - if (byteStatName === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Unknown byte stat name \'' + rawByteStatName + '\' (' + - rawByteStatValue + ') of VM region ' + i + ' (' + - rawVmRegion.mf + ') in process memory dump for PID=' + pid + - ' and dump ID=' + dumpId + '.' - }); - continue; - } - byteStats[byteStatName] = parseInt(rawByteStatValue, 16); - } - - vmRegions[i] = new tr.model.VMRegion( - parseInt(rawVmRegion.sa, 16), // startAddress - parseInt(rawVmRegion.sz, 16), // sizeInBytes - rawVmRegion.pf, // protectionFlags - rawVmRegion.mf, // mappedFile - byteStats); - } - - processMemoryDump.vmRegions = - tr.model.VMRegionClassificationNode.fromRegions(vmRegions); - }, - - parseMemoryDumpHeapDumps_: function(processMemoryDump, dumps, pid, dumpId) { - var rawHeapDumps = dumps.heaps; - if (rawHeapDumps === undefined) - return; - - if (processMemoryDump.heapDumps !== undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Heap dumps provided multiple times for' + - ' process memory dump for PID=' + pid + - ' and dump ID=' + dumpId + '.' - }); - return; - } - - var model = this.model_; - var idPrefix = 'p' + pid + ':'; - var heapDumps = {}; - - var objectTypeNameMap = this.objectTypeNameMap_[pid]; - if (objectTypeNameMap === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Missing mapping from object type IDs to names.' - }); - } - - for (var allocatorName in rawHeapDumps) { - var entries = rawHeapDumps[allocatorName].entries; - if (entries === undefined || entries.length === 0) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'No heap entries in a ' + allocatorName + - ' heap dump for PID=' + pid + ' and dump ID=' + dumpId + '.' - }); - continue; - } - - // The old format always starts with a {size: <total>} entry. - // See https://goo.gl/WYStil - // TODO(petrcermak): Remove support for the old format once the new - // format has been around long enough. - var isOldFormat = entries[0].bt === undefined; - if (!isOldFormat && objectTypeNameMap === undefined) { - // Mapping from object type IDs to names must be provided in the new - // format. - continue; - } - - var heapDump = new tr.model.HeapDump(processMemoryDump, allocatorName); - - for (var i = 0; i < entries.length; i++) { - var entry = entries[i]; - var leafStackFrameIndex = entry.bt; - var leafStackFrame; - - // There are two possible mappings from leaf stack frame indices - // (provided in the trace) to the corresponding stack frames - // depending on the format. - if (isOldFormat) { - // Old format: - // Undefined index -> / (root) - // Defined index for /A/B -> /A/B/<self> - if (leafStackFrameIndex === undefined) { - leafStackFrame = undefined /* root */; - } else { - // Get the leaf stack frame corresponding to the provided index. - var leafStackFrameId = idPrefix + leafStackFrameIndex; - if (leafStackFrameIndex === '') { - leafStackFrame = undefined /* root */; - } else { - leafStackFrame = model.stackFrames[leafStackFrameId]; - if (leafStackFrame === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Missing leaf stack frame (ID ' + - leafStackFrameId + ') of heap entry ' + i + ' (size ' + - size + ') in a ' + allocatorName + - ' heap dump for PID=' + pid + '.' - }); - continue; - } - } - - // Inject an artificial <self> leaf stack frame. - leafStackFrameId += ':self'; - if (model.stackFrames[leafStackFrameId] !== undefined) { - // The frame might already exist if there are multiple process - // memory dumps (for the same process) in the trace. - leafStackFrame = model.stackFrames[leafStackFrameId]; - } else { - leafStackFrame = new tr.model.StackFrame( - leafStackFrame, leafStackFrameId, '<self>', - undefined /* colorId */); - model.addStackFrame(leafStackFrame); - } - } - } else { - // New format: - // Undefined index -> (invalid value) - // Defined index for /A/B -> /A/B - if (leafStackFrameIndex === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Missing stack frame ID of heap entry ' + i + - ' (size ' + size + ') in a ' + allocatorName + - ' heap dump for PID=' + pid + '.' - }); - continue; - } - - // Get the leaf stack frame corresponding to the provided index. - var leafStackFrameId = idPrefix + leafStackFrameIndex; - if (leafStackFrameIndex === '') { - leafStackFrame = undefined /* root */; - } else { - leafStackFrame = model.stackFrames[leafStackFrameId]; - if (leafStackFrame === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Missing leaf stack frame (ID ' + leafStackFrameId + - ') of heap entry ' + i + ' (size ' + size + ') in a ' + - allocatorName + ' heap dump for PID=' + pid + '.' - }); - continue; - } - } - } - - var objectTypeId = entry.type; - var objectTypeName; - if (objectTypeId === undefined) { - objectTypeName = undefined /* total over all types */; - } else if (objectTypeNameMap === undefined) { - // This can only happen when the old format is used. - continue; - } else { - objectTypeName = objectTypeNameMap[objectTypeId]; - if (objectTypeName === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Missing object type name (ID ' + objectTypeId + - ') of heap entry ' + i + ' (size ' + size + ') in a ' + - allocatorName + ' heap dump for pid=' + pid + '.' - }); - continue; - } - } - - var size = parseInt(entry.size, 16); - var count = entry.count === undefined ? undefined : - parseInt(entry.count, 16); - heapDump.addEntry(leafStackFrame, objectTypeName, size, count); - } - - // Throw away heap dumps with no entries. This can happen if all raw - // entries in the trace are skipped for some reason (e.g. invalid leaf - // stack frame ID). - if (heapDump.entries.length > 0) - heapDumps[allocatorName] = heapDump; - } - - if (Object.keys(heapDumps).length > 0) - processMemoryDump.heapDumps = heapDumps; - }, - - parseMemoryDumpLevelOfDetail_: function(levelsOfDetail, dumps, pid, - dumpId) { - var rawLevelOfDetail = dumps.level_of_detail; - var level; - switch (rawLevelOfDetail) { - case 'light': - level = LIGHT; - break; - case 'detailed': - level = DETAILED; - break; - case undefined: - level = undefined; - break; - default: - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'unknown raw level of detail \'' + rawLevelOfDetail + - '\' of process memory dump for PID=' + pid + - ' and dump ID=' + dumpId + '.' - }); - return; - } - - if (!this.updateMemoryDumpLevelOfDetail_( - levelsOfDetail, 'process', level)) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'diffent levels of detail provided for process memory' + - ' dump for PID=' + pid + ' (dump ID=' + dumpId + ').' - }); - } - }, - - updateMemoryDumpLevelOfDetail_: function(levelsOfDetail, scope, level) { - // If all process memory dump events have the same level of detail (for - // the particular 'process' or 'global' scope), return true. - if (!(scope in levelsOfDetail) || level === levelsOfDetail[scope]) { - levelsOfDetail[scope] = level; - return true; - } - - // If the process memory dump events have different levels of detail (for - // the particular 'process' or 'global' scope), use the highest level and - // return false. - if (MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(level) > - MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(levelsOfDetail[scope])) { - levelsOfDetail[scope] = level; - } - return false; - }, - - parseMemoryDumpAllocatorDumps_: function(processMemoryDump, - globalMemoryDump, processMemoryAllocatorDumpsByFullName, - globalMemoryAllocatorDumpsByFullName, allMemoryAllocatorDumpsByGuid, - dumps, pid, dumpId) { - var rawAllocatorDumps = dumps.allocators; - if (rawAllocatorDumps === undefined) - return; - - // Construct the MemoryAllocatorDump objects without parent links - // and add them to the processMemoryAllocatorDumpsByName and - // globalMemoryAllocatorDumpsByName indices appropriately. - for (var fullName in rawAllocatorDumps) { - var rawAllocatorDump = rawAllocatorDumps[fullName]; - - // Every memory allocator dump should have a GUID. If not, then - // it cannot be associated with any edges. - var guid = rawAllocatorDump.guid; - if (guid === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Memory allocator dump ' + fullName + ' for PID=' + pid + - ' and dump ID=' + dumpId + ' does not have a GUID.' - }); - } - - // A memory allocator dump can have optional flags. - var flags = rawAllocatorDump.flags || 0; - var isWeakDump = !!(flags & WEAK_MEMORY_ALLOCATOR_DUMP_FLAG); - - // Determine if this is a global memory allocator dump (check if - // it's prefixed with 'global/'). - var containerMemoryDump; - var dstIndex; - if (fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)) { - // Global memory allocator dump. - fullName = fullName.substring( - GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length); - containerMemoryDump = globalMemoryDump; - dstIndex = globalMemoryAllocatorDumpsByFullName; - } else { - // Process memory allocator dump. - containerMemoryDump = processMemoryDump; - dstIndex = processMemoryAllocatorDumpsByFullName; - } - - // Construct or retrieve a memory allocator dump with the provided - // GUID. - var allocatorDump = allMemoryAllocatorDumpsByGuid[guid]; - if (allocatorDump === undefined) { - if (fullName in dstIndex) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Multiple GUIDs provided for' + - ' memory allocator dump ' + fullName + ': ' + - dstIndex[fullName].guid + ', ' + guid + ' (ignored) for' + - ' PID=' + pid + ' and dump ID=' + dumpId + '.' - }); - continue; - } - allocatorDump = new tr.model.MemoryAllocatorDump( - containerMemoryDump, fullName, guid); - allocatorDump.weak = isWeakDump; - dstIndex[fullName] = allocatorDump; - if (guid !== undefined) - allMemoryAllocatorDumpsByGuid[guid] = allocatorDump; - } else { - // A memory allocator dump with this GUID has already been - // dumped (so we will only add new attributes). Check that it - // belonged to the same process or was also global. - if (allocatorDump.containerMemoryDump !== containerMemoryDump) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Memory allocator dump ' + fullName + - ' (GUID=' + guid + ') for PID=' + pid + ' and dump ID=' + - dumpId + ' dumped in different contexts.' - }); - continue; - } - // Check that the names of the memory allocator dumps match. - if (allocatorDump.fullName !== fullName) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Memory allocator dump with GUID=' + guid + ' for PID=' + - pid + ' and dump ID=' + dumpId + ' has multiple names: ' + - allocatorDump.fullName + ', ' + fullName + ' (ignored).' - }); - continue; - } - if (!isWeakDump) { - // A MemoryAllocatorDump is non-weak if at least one process dumped - // it without WEAK_MEMORY_ALLOCATOR_DUMP_FLAG. - allocatorDump.weak = false; - } - } - - // Add all new attributes to the memory allocator dump. - var attributes = rawAllocatorDump.attrs; - if (attributes === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Memory allocator dump ' + fullName + ' (GUID=' + guid + - ') for PID=' + pid + ' and dump ID=' + dumpId + - ' does not have attributes.' - }); - attributes = {}; - } - - for (var attrName in attributes) { - var attrArgs = attributes[attrName]; - var attrType = attrArgs.type; - var attrValue = attrArgs.value; - - switch (attrType) { - case 'scalar': - if (attrName in allocatorDump.numerics) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Multiple values provided for scalar attribute ' + - attrName + ' of memory allocator dump ' + fullName + - ' (GUID=' + guid + ') for PID=' + pid + ' and dump ID=' + - dumpId + '.' - }); - break; - } - var unit = attrArgs.units === 'bytes' ? - tr.v.Unit.byName.sizeInBytes_smallerIsBetter : - tr.v.Unit.byName.unitlessNumber_smallerIsBetter; - var value = parseInt(attrValue, 16); - allocatorDump.addNumeric(attrName, - new tr.v.ScalarNumeric(unit, value)); - break; - - case 'string': - if (attrName in allocatorDump.diagnostics) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Multiple values provided for string attribute ' + - attrName + ' of memory allocator dump ' + fullName + - ' (GUID=' + guid + ') for PID=' + pid + ' and dump ID=' + - dumpId + '.' - }); - break; - } - allocatorDump.addDiagnostic(attrName, attrValue); - break; - - default: - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Unknown type provided for attribute ' + attrName + - ' of memory allocator dump ' + fullName + ' (GUID=' + guid + - ') for PID=' + pid + ' and dump ID=' + dumpId + ': ' + - attrType - }); - break; - } - } - } - }, - - inferMemoryAllocatorDumpTree_: function(memoryAllocatorDumpsByFullName) { - var rootAllocatorDumps = []; - - var fullNames = Object.keys(memoryAllocatorDumpsByFullName); - fullNames.sort(); - for (var i = 0; i < fullNames.length; i++) { - var fullName = fullNames[i]; - var allocatorDump = memoryAllocatorDumpsByFullName[fullName]; - - // This is a loop because we might need to build implicit - // ancestors in case they were not present in the trace. - while (true) { - var lastSlashIndex = fullName.lastIndexOf('/'); - if (lastSlashIndex === -1) { - // If the dump is a root, add it to the top-level - // rootAllocatorDumps list. - rootAllocatorDumps.push(allocatorDump); - break; - } - - // If the dump is not a root, find its parent. - var parentFullName = fullName.substring(0, lastSlashIndex); - var parentAllocatorDump = - memoryAllocatorDumpsByFullName[parentFullName]; - - // If the parent dump does not exist yet, we build an implicit - // one and continue up the ancestor chain. - var parentAlreadyExisted = true; - if (parentAllocatorDump === undefined) { - parentAlreadyExisted = false; - parentAllocatorDump = new tr.model.MemoryAllocatorDump( - allocatorDump.containerMemoryDump, parentFullName); - if (allocatorDump.weak !== false) { - // If we are inferring a parent dump (e.g. 'root/parent') of a - // current dump (e.g. 'root/parent/current') which is weak (or - // was also inferred and we don't know yet whether it's weak or - // not), then we clear the weak flag on the parent dump because - // we don't know yet whether it should be weak or non-weak: - // - // * We can't mark the parent as non-weak straightaway because - // the parent might have no non-weak descendants (in which - // case we want the inferred parent to be weak, so that it - // would be later removed like the current dump). - // * We can't mark the parent as weak immediately either. If we - // did and later encounter a non-weak child of the parent - // (e.g. 'root/parent/another_child'), then we couldn't - // retroactively mark the inferred parent dump as non-weak - // because we couldn't tell whether the parent dump was - // dumped in the trace as weak (in which case it should stay - // weak and be subsequently removed) or whether it was - // inferred as weak (in which case it should be changed to - // non-weak). - // - // Therefore, we defer marking the inferred parent as - // weak/non-weak. If an inferred parent dump does not have any - // non-weak child, it will be marked as weak at the end of this - // method. - // - // Note that this should not be confused with the recursive - // propagation of the weak flag from parent dumps to their - // children and from owned dumps to their owners, which is - // performed in GlobalMemoryDump.prototype.removeWeakDumps(). - parentAllocatorDump.weak = undefined; - } - memoryAllocatorDumpsByFullName[parentFullName] = - parentAllocatorDump; - } - - // Setup the parent <-> children relationships - allocatorDump.parent = parentAllocatorDump; - parentAllocatorDump.children.push(allocatorDump); - - // If the parent already existed, then its ancestors were/will be - // constructed in another iteration of the forEach loop. - if (parentAlreadyExisted) { - if (!allocatorDump.weak) { - // If the current dump is non-weak, then we must ensure that all - // its inferred ancestors are also non-weak. - while (parentAllocatorDump !== undefined && - parentAllocatorDump.weak === undefined) { - parentAllocatorDump.weak = false; - parentAllocatorDump = parentAllocatorDump.parent; - } - } - break; - } - - fullName = parentFullName; - allocatorDump = parentAllocatorDump; - } - } - - // All inferred ancestor dumps that have a non-weak child have already - // been marked as non-weak. We now mark the rest as weak. - for (var fullName in memoryAllocatorDumpsByFullName) { - var allocatorDump = memoryAllocatorDumpsByFullName[fullName]; - if (allocatorDump.weak === undefined) - allocatorDump.weak = true; - } - - return rootAllocatorDumps; - }, - - parseMemoryDumpAllocatorEdges_: function(allMemoryAllocatorDumpsByGuid, - dumpIdEvents, dumpId) { - for (var pid in dumpIdEvents) { - var processEvents = dumpIdEvents[pid]; - - for (var i = 0; i < processEvents.length; i++) { - var processEvent = processEvents[i]; - - var dumps = processEvent.args.dumps; - if (dumps === undefined) - continue; - - var rawEdges = dumps.allocators_graph; - if (rawEdges === undefined) - continue; - - for (var j = 0; j < rawEdges.length; j++) { - var rawEdge = rawEdges[j]; - - var sourceGuid = rawEdge.source; - var sourceDump = allMemoryAllocatorDumpsByGuid[sourceGuid]; - if (sourceDump === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Edge for PID=' + pid + ' and dump ID=' + dumpId + - ' is missing source memory allocator dump (GUID=' + - sourceGuid + ').' - }); - continue; - } - - var targetGuid = rawEdge.target; - var targetDump = allMemoryAllocatorDumpsByGuid[targetGuid]; - if (targetDump === undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Edge for PID=' + pid + ' and dump ID=' + dumpId + - ' is missing target memory allocator dump (GUID=' + - targetGuid + ').' - }); - continue; - } - - var importance = rawEdge.importance; - var edge = new tr.model.MemoryAllocatorDumpLink( - sourceDump, targetDump, importance); - - switch (rawEdge.type) { - case 'ownership': - if (sourceDump.owns !== undefined) { - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Memory allocator dump ' + sourceDump.fullName + - ' (GUID=' + sourceGuid + ') already owns a memory' + - ' allocator dump (' + - sourceDump.owns.target.fullName + ').' - }); - } else { - sourceDump.owns = edge; - targetDump.ownedBy.push(edge); - } - break; - - case 'retention': - sourceDump.retains.push(edge); - targetDump.retainedBy.push(edge); - break; - - default: - this.model_.importWarning({ - type: 'memory_dump_parse_error', - message: 'Invalid edge type: ' + rawEdge.type + - ' (PID=' + pid + ', dump ID=' + dumpId + - ', source=' + sourceGuid + ', target=' + targetGuid + - ', importance=' + importance + ').' - }); - } - } - } - } - } - }; - - tr.importer.Importer.register(TraceEventImporter); - - return { - TraceEventImporter: TraceEventImporter - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer_perf_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer_perf_test.html deleted file mode 100644 index b7a7c57b3ae..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer_perf_test.html +++ /dev/null @@ -1,69 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/base/xhr.html"> -<link rel="import" href="/tracing/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/trace_event_importer.html"> -<link rel="import" href="/tracing/model/model.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - var eventStrings = {}; - - // @const - var TEST_NAMES = ['simple_trace', 'lthi_cats']; - // @const - var TEST_FILES_PATHS = ['/test_data/simple_trace.json', - '/test_data/lthi_cats.json.gz']; - - function getEvents(url) { - if (url in eventStrings) - return eventStrings[url]; - eventStrings[url] = tr.b.getSync(url); - return eventStrings[url]; - } - - function timedPerfTestWithEvents(name, testFn, initialOptions) { - if (initialOptions.setUp) - throw new Error( - 'Per-test setUp not supported. Trivial to fix if needed.'); - - var options = {}; - for (var k in initialOptions) - options[k] = initialOptions[k]; - options.setUp = function() { - TEST_FILES_PATHS.forEach( - function warmup(url) { - getEvents(url); - }); - }; - timedPerfTest(name, testFn, options); - } - - var n110100 = [1, 10, 100]; - n110100.forEach(function(val) { - timedPerfTestWithEvents(TEST_NAMES[0] + '_' + val, function() { - var events = getEvents(TEST_FILES_PATHS[0]); - var m = tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false, - pruneContainers: false - }); - }, {iterations: val}); - }); - - timedPerfTestWithEvents(TEST_NAMES[1] + '_1', function() { - var events = getEvents(TEST_FILES_PATHS[1]); - var m = tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false, - pruneContainers: false - }); - }, {iterations: 1}); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer_test.html deleted file mode 100644 index 9270fd150ee..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/trace_event_importer_test.html +++ /dev/null @@ -1,5754 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/trace_event_importer.html"> -<link rel="import" href="/tracing/extras/measure/measure.html"> -<link rel="import" href="/tracing/importer/import.html"> -<link rel="import" href="/tracing/model/container_memory_dump.html"> -<link rel="import" href="/tracing/model/memory_dump_test_utils.html"> -<link rel="import" href="/tracing/model/scoped_id.html"> -<link rel="import" href="/tracing/model/vm_region.html"> -<link rel="import" href="/tracing/value/numeric.html"> -<link rel="import" href="/tracing/value/time_display_mode.html"> -<link rel="import" href="/tracing/value/unit.html"> - -<script> -'use strict'; - -tr.b.unittest.testSuite(function() { - var findSliceNamed = tr.c.TestUtils.findSliceNamed; - var ClockDomainId = tr.model.ClockDomainId; - var ColorScheme = tr.b.ColorScheme; - var MeasureAsyncSlice = tr.e.measure.MeasureAsyncSlice; - var ScopedId = tr.model.ScopedId; - var VMRegion = tr.model.VMRegion; - var ScalarNumeric = tr.v.ScalarNumeric; - var unitlessNumber_smallerIsBetter = - tr.v.Unit.byName.unitlessNumber_smallerIsBetter; - var checkDumpNumericsAndDiagnostics = - tr.model.MemoryDumpTestUtils.checkDumpNumericsAndDiagnostics; - var checkVMRegions = tr.model.MemoryDumpTestUtils.checkVMRegions; - var LIGHT = tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT; - var DETAILED = tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED; - - function makeModel(events, opt_shift, opt_prune) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: opt_shift, - pruneEmptyContainers: opt_prune - }); - } - - function makeUnshiftedModel(events) { - return makeModel(events, false); - } - - function checkHeapEntry(entry, expectedDump, expectedSize, expectedTitles, - expectedObjectTypeName, expectedCount) { - assert.strictEqual(entry.heapDump, expectedDump); - assert.strictEqual(entry.size, expectedSize); - assert.strictEqual(entry.objectTypeName, expectedObjectTypeName); - assert.strictEqual(entry.count, expectedCount); - if (expectedTitles === undefined) { - assert.isUndefined(entry.leafStackFrame); - } else { - assert.deepEqual( - entry.leafStackFrame.getUserFriendlyStackTrace(), expectedTitles); - } - } - - function getFrame(heapEntry, distance) { - var frame = heapEntry.leafStackFrame; - for (; distance > 0; distance--) - frame = frame.parentFrame; - return frame; - } - - test('canImportEmpty', function() { - assert.isFalse(tr.e.importer.TraceEventImporter.canImport([])); - assert.isFalse(tr.e.importer.TraceEventImporter.canImport('')); - }); - - test('basicSingleThreadNonnestedParsing', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'}, - {name: 'b', args: {}, pid: 52, ts: 629, cat: 'bar', tid: 53, ph: 'B'}, - {name: 'b', args: {}, pid: 52, ts: 631, cat: 'bar', tid: 53, ph: 'E'} - ]; - - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - var p = m.processes[52]; - assert.isDefined(p); - - assert.equal(p.numThreads, 1); - var t = p.threads[53]; - assert.isDefined(t); - assert.equal(t.sliceGroup.length, 2); - assert.equal(t.tid, 53); - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - assert.equal(slice.start, 0); - assert.closeTo((560 - 520) / 1000, slice.duration, 1e-5); - assert.equal(slice.subSlices.length, 0); - - slice = t.sliceGroup.slices[1]; - assert.equal(slice.title, 'b'); - assert.equal(slice.category, 'bar'); - assert.closeTo((629 - 520) / 1000, slice.start, 1e-5); - assert.closeTo((631 - 629) / 1000, slice.duration, 1e-5); - assert.equal(slice.subSlices.length, 0); - }); - - test('basicSingleThreadNonnestedParsingWithCpuDuration', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B', tts: 221}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E', tts: 259}, // @suppress longLineCheck - {name: 'b', args: {}, pid: 52, ts: 629, cat: 'bar', tid: 53, ph: 'B', tts: 329}, // @suppress longLineCheck - {name: 'b', args: {}, pid: 52, ts: 631, cat: 'bar', tid: 53, ph: 'E', tts: 331} // @suppress longLineCheck - ]; - - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - var p = m.processes[52]; - assert.isDefined(p); - - assert.equal(p.numThreads, 1); - var t = p.threads[53]; - assert.isDefined(t); - assert.equal(t.sliceGroup.length, 2); - assert.equal(t.tid, 53); - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - assert.equal(slice.start, 0); - assert.closeTo((560 - 520) / 1000, slice.duration, 1e-5); - assert.closeTo((259 - 221) / 1000, slice.cpuDuration, 1e-5); - assert.equal(slice.subSlices.length, 0); - - slice = t.sliceGroup.slices[1]; - assert.equal(slice.title, 'b'); - assert.equal(slice.category, 'bar'); - assert.closeTo((629 - 520) / 1000, slice.start, 1e-5); - assert.closeTo((631 - 629) / 1000, slice.duration, 1e-5); - assert.closeTo((331 - 329) / 1000, slice.cpuDuration, 1e-5); - assert.equal(slice.subSlices.length, 0); - }); - - test('argumentDupeCreatesNonFailingImportError', function() { - var events = [ - {name: 'a', - args: {'x': 1}, - pid: 1, - ts: 520, - cat: 'foo', - tid: 1, - ph: 'B'}, - {name: 'a', - args: {'x': 2}, - pid: 1, - ts: 560, - cat: 'foo', - tid: 1, - ph: 'E'} - ]; - - var m = makeModel(events); - var t = m.processes[1].threads[1]; - var sA = findSliceNamed(t.sliceGroup, 'a'); - - assert.equal(sA.args.x, 2); - assert.isTrue(m.hasImportWarnings); - assert.equal(1, m.importWarnings.length); - }); - - test('importMissingArgs', function() { - var events = [ - {name: 'a', pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'}, - {name: 'b', pid: 52, ts: 629, cat: 'bar', tid: 53, ph: 'I'} - ]; - - // This should not throw an exception. - makeModel(events); - }); - - test('importDoesNotChokeOnNulls', function() { - var events = [ - {name: 'a', args: { foo: null }, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'}, // @suppress longLineCheck - {name: 'a', pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ]; - - // This should not throw an exception. - makeModel(events); - }); - - test('categoryBeginEndMismatchPrefersBegin', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'bar', tid: 53, ph: 'E'} - ]; - - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - var p = m.processes[52]; - assert.isDefined(p); - - assert.equal(p.numThreads, 1); - var t = p.threads[53]; - assert.isDefined(t); - assert.equal(t.sliceGroup.length, 1); - assert.equal(t.tid, 53); - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - }); - - test('beginEndNameMismatch', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'b', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ]; - - var m = makeModel(events); - assert.isTrue(m.hasImportWarnings); - assert.equal(m.importWarnings.length, 1); - }); - - test('nestedParsing', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, tts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 2, tts: 2, cat: 'bar', tid: 1, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 3, tts: 3, cat: 'bar', tid: 1, ph: 'E'}, - {name: 'a', args: {}, pid: 1, ts: 4, tts: 3, cat: 'foo', tid: 1, ph: 'E'} - ]; - var m = makeModel(events, false); - var t = m.processes[1].threads[1]; - - var sA = findSliceNamed(t.sliceGroup, 'a'); - var sB = findSliceNamed(t.sliceGroup, 'b'); - - assert.equal(sA.title, 'a'); - assert.equal(sA.category, 'foo'); - assert.equal(sA.start, 0.001); - assert.equal(sA.duration, 0.003); - assert.equal(sA.selfTime, 0.002); - assert.equal(sA.cpuSelfTime, 0.001); - - assert.equal(sB.title, 'b'); - assert.equal(sB.category, 'bar'); - assert.equal(sB.start, 0.002); - assert.equal(sB.duration, 0.001); - - assert.equal(1, sA.subSlices.length); - assert.equal(sB, sA.subSlices[0]); - assert.equal(sA, sB.parentSlice); - }); - - test('nestedParsingWithTwoSubSlices', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, tts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 2, tts: 2, cat: 'bar', tid: 1, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 3, tts: 3, cat: 'bar', tid: 1, ph: 'E'}, - {name: 'c', args: {}, pid: 1, ts: 5, tts: 5, cat: 'baz', tid: 1, ph: 'B'}, - {name: 'c', args: {}, pid: 1, ts: 7, tts: 6, cat: 'baz', tid: 1, ph: 'E'}, - {name: 'a', args: {}, pid: 1, ts: 8, tts: 8, cat: 'foo', tid: 1, ph: 'E'} - ]; - var m = makeModel(events, false); - var t = m.processes[1].threads[1]; - - var sA = findSliceNamed(t.sliceGroup, 'a'); - var sB = findSliceNamed(t.sliceGroup, 'b'); - var sC = findSliceNamed(t.sliceGroup, 'c'); - - assert.equal(sA.title, 'a'); - assert.equal(sA.category, 'foo'); - assert.equal(sA.start, 0.001); - assert.equal(sA.duration, 0.007); - assert.equal(sA.selfTime, 0.004); - assert.equal(sA.cpuSelfTime, 0.005); - - assert.equal(sB.title, 'b'); - assert.equal(sB.category, 'bar'); - assert.equal(sB.start, 0.002); - assert.equal(sB.duration, 0.001); - - assert.equal(sC.title, 'c'); - assert.equal(sC.category, 'baz'); - assert.equal(sC.start, 0.005); - assert.equal(sC.duration, 0.002); - - assert.equal(sA.subSlices.length, 2); - assert.equal(sA.subSlices[0], sB); - assert.equal(sA.subSlices[1], sC); - assert.equal(sB.parentSlice, sA); - assert.equal(sC.parentSlice, sA); - }); - - test('nestedParsingWithDoubleNesting', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 2, cat: 'bar', tid: 1, ph: 'B'}, - {name: 'c', args: {}, pid: 1, ts: 3, cat: 'baz', tid: 1, ph: 'B'}, - {name: 'c', args: {}, pid: 1, ts: 5, cat: 'baz', tid: 1, ph: 'E'}, - {name: 'b', args: {}, pid: 1, ts: 7, cat: 'bar', tid: 1, ph: 'E'}, - {name: 'a', args: {}, pid: 1, ts: 8, cat: 'foo', tid: 1, ph: 'E'} - ]; - var m = makeModel(events, false); - var t = m.processes[1].threads[1]; - - var sA = findSliceNamed(t.sliceGroup, 'a'); - var sB = findSliceNamed(t.sliceGroup, 'b'); - var sC = findSliceNamed(t.sliceGroup, 'c'); - - assert.equal(sA.title, 'a'); - assert.equal(sA.category, 'foo'); - assert.equal(sA.start, 0.001); - assert.equal(sA.duration, 0.007); - assert.equal(sA.selfTime, 0.002); - - assert.equal(sB.title, 'b'); - assert.equal(sB.category, 'bar'); - assert.equal(sB.start, 0.002); - assert.equal(sB.duration, 0.005); - assert.equal(sA.selfTime, 0.002); - - assert.equal(sC.title, 'c'); - assert.equal(sC.category, 'baz'); - assert.equal(sC.start, 0.003); - assert.equal(sC.duration, 0.002); - - assert.equal(sA.subSlices.length, 1); - assert.equal(sA.subSlices[0], sB); - assert.equal(sB.parentSlice, sA); - - assert.equal(sB.subSlices.length, 1); - assert.equal(sB.subSlices[0], sC); - assert.equal(sC.parentSlice, sB); - }); - - - test('autoclosing', function() { - var events = [ - // Slice that doesn't finish. - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'}, - - // Slice that does finish to give an 'end time' to make autoclosing work. - {name: 'b', args: {}, pid: 1, ts: 1, cat: 'bar', tid: 2, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 2, cat: 'bar', tid: 2, ph: 'E'} - ]; - var m = makeUnshiftedModel(events); - var p = m.processes[1]; - var t1 = p.threads[1]; - var t2 = p.threads[2]; - assert.isTrue(t1.sliceGroup.slices[0].didNotFinish); - assert.equal(t1.sliceGroup.slices[0].end, 0.001); - }); - - test('autoclosingLoneBegin', function() { - var events = [ - // Slice that doesn't finish. - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'} - ]; - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - assert.isTrue(slice.didNotFinish); - assert.equal(slice.start, 0); - assert.equal(slice.duration, 0); - }); - - test('autoclosingWithSubTasks', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'b1', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'b1', args: {}, pid: 1, ts: 3, cat: 'foo', tid: 1, ph: 'E'}, - {name: 'b2', args: {}, pid: 1, ts: 3, cat: 'foo', tid: 1, ph: 'B'} - ]; - var m = makeModel(events, false); - var t = m.processes[1].threads[1]; - - var sA = findSliceNamed(t.sliceGroup, 'a'); - var sB1 = findSliceNamed(t.sliceGroup, 'b1'); - var sB2 = findSliceNamed(t.sliceGroup, 'b2'); - - assert.equal(sA.end, 0.003); - assert.equal(sB1.end, 0.003); - assert.equal(sB2.end, 0.003); - }); - - test('autoclosingWithEventsOutsideBounds', function() { - var events = [ - // Slice that begins before min and ends after max of the other threads. - {name: 'a', args: {}, pid: 1, ts: 0, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 3, cat: 'foo', tid: 1, ph: 'B'}, - - // Slice that does finish to give an 'end time' to establish a basis - {name: 'c', args: {}, pid: 1, ts: 1, cat: 'bar', tid: 2, ph: 'B'}, - {name: 'c', args: {}, pid: 1, ts: 2, cat: 'bar', tid: 2, ph: 'E'} - ]; - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - assert.equal(t.sliceGroup.length, 2); - - var slice = findSliceNamed(t.sliceGroup, 'a'); - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - assert.equal(slice.start, 0); - assert.equal(slice.duration, 0.003); - - var t2 = p.threads[2]; - var slice2 = findSliceNamed(t2.sliceGroup, 'c'); - assert.equal(slice2.title, 'c'); - assert.equal(slice2.category, 'bar'); - assert.equal(slice2.start, 0.001); - assert.equal(slice2.duration, 0.001); - - assert.equal(m.bounds.min, 0.000); - assert.equal(m.bounds.max, 0.003); - }); - - test('nestedAutoclosing', function() { - var events = [ - // Tasks that don't finish. - {name: 'a1', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'a2', args: {}, pid: 1, ts: 1.5, cat: 'foo', tid: 1, ph: 'B'}, - - // Slice that does finish to give an 'end time' to make autoclosing work. - {name: 'b', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 2, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 2, ph: 'E'} - ]; - var m = makeUnshiftedModel(events, false); - var t1 = m.processes[1].threads[1]; - var t2 = m.processes[1].threads[2]; - - var sA1 = findSliceNamed(t1.sliceGroup, 'a1'); - var sA2 = findSliceNamed(t1.sliceGroup, 'a2'); - var sB = findSliceNamed(t2.sliceGroup, 'b'); - - assert.equal(sA1.end, 0.0015); - assert.equal(sA2.end, 0.0015); - }); - - test('taskColoring', function() { - // The test below depends on hashing of 'a' != 'b'. Fail early if that - // assumption is incorrect. - assert.notEqual(ColorScheme.getStringHash('a'), - ColorScheme.getStringHash('b')); - - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'a', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 1, ph: 'E'}, - {name: 'b', args: {}, pid: 1, ts: 3, cat: 'bar', tid: 1, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 4, cat: 'bar', tid: 1, ph: 'E'}, - {name: 'a', args: {}, pid: 1, ts: 5, cat: 'baz', tid: 1, ph: 'B'}, - {name: 'a', args: {}, pid: 1, ts: 6, cat: 'baz', tid: 1, ph: 'E'} - ]; - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - var a1 = t.sliceGroup.slices[0]; - assert.equal(a1.title, 'a'); - assert.equal(a1.category, 'foo'); - var b = t.sliceGroup.slices[1]; - assert.equal(b.title, 'b'); - assert.equal(b.category, 'bar'); - assert.notEqual(b.colorId, a1.colorId); - var a2 = t.sliceGroup.slices[2]; - assert.equal(a2.title, 'a'); - assert.equal(a2.category, 'baz'); - assert.equal(a1.colorId, a2.colorId); - }); - - test('durationColorArgument', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B', cname: 'thread_state_unknown'}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'E', cname: 'thread_state_unknown'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - assert.equal(t.sliceGroup.slices[0].colorId, - ColorScheme.getColorIdForReservedName('thread_state_unknown')); - }); - - test('durationColorEnd', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B', cname: 'thread_state_sleeping'}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'E', cname: 'thread_state_unknown'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - assert.equal(t.sliceGroup.slices[0].colorId, - ColorScheme.getColorIdForReservedName('thread_state_unknown')); - }); - - test('completeColorArgument', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, dur: 1, cat: 'foo', tid: 1, ph: 'X', cname: 'generic_work'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - assert.equal(t.sliceGroup.slices[0].colorId, - ColorScheme.getColorIdForReservedName('generic_work')); - }); - - test('asyncColorArgument', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'b', id: 1, cname: 'generic_work'}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 1, ph: 'e', id: 1, cname: 'generic_work'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - assert.equal(t.asyncSliceGroup.slices[0].colorId, - ColorScheme.getColorIdForReservedName('generic_work')); - }); - - test('asyncColorEnd', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'b', id: 1, cname: 'thread_state_unknown'}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 1, ph: 'e', id: 1, cname: 'generic_work'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - assert.equal(t.asyncSliceGroup.slices[0].colorId, - ColorScheme.getColorIdForReservedName('generic_work')); - }); - - test('instantThreadColorArgument', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'I', id: 1, cname: 'generic_work'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - var t = p.threads[1]; - assert.equal(t.sliceGroup.slices[0].colorId, - ColorScheme.getColorIdForReservedName('generic_work')); - }); - - test('instantProcessColorArgument', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'I', id: 1, s: 'p', cname: 'generic_work'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - assert.equal(p.instantEvents[0].colorId, - ColorScheme.getColorIdForReservedName('generic_work')); - }); - - test('counterColorArgument', function() { - var events = [ - {name: 'a', args: {'cats': 10}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'C', id: 1, cname: 'generic_work'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - assert.equal(p.counters['foo.a[1]'].series[0].color, - ColorScheme.getColorIdForReservedName('generic_work')); - assert.equal(p.counters['foo.a[1]'].series.length, 1); - }); - - test('objectColorArgument', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'N', id: 1, cname: 'generic_work'}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 1, ph: 'O', id: 1, cname: 'generic_work'}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 1, ts: 3, cat: 'foo', tid: 1, ph: 'D', id: 1, cname: 'generic_work'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - var i = p.objects.instanceMapsByScopedId_['ptr'][1].instances[0]; - assert.equal(i.colorId, - ColorScheme.getColorIdForReservedName('generic_work')); - }); - - test('objectColorEnd', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'N', id: 1, cname: 'thread_state_sleeping'}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 1, ph: 'O', id: 1, cname: 'thread_state_unknown'}, // @suppress longLineCheck - {name: 'a', args: {}, pid: 1, ts: 3, cat: 'foo', tid: 1, ph: 'D', id: 1, cname: 'generic_work'} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p = m.processes[1]; - var i = p.objects.instanceMapsByScopedId_['ptr'][1].instances[0]; - assert.equal(i.colorId, - ColorScheme.getColorIdForReservedName('generic_work')); - }); - - test('multipleThreadParsing', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'a', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 1, ph: 'E'}, - {name: 'b', args: {}, pid: 1, ts: 3, cat: 'bar', tid: 2, ph: 'B'}, - {name: 'b', args: {}, pid: 1, ts: 4, cat: 'bar', tid: 2, ph: 'E'} - ]; - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - var p = m.processes[1]; - assert.isDefined(p); - - assert.equal(p.numThreads, 2); - - // Check thread 1. - var t = p.threads[1]; - assert.isDefined(t); - assert.equal(t.sliceGroup.length, 1); - assert.equal(t.tid, 1); - - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - assert.equal(slice.start, 0); - assert.equal(slice.duration, (2 - 1) / 1000); - assert.equal(slice.subSlices.length, 0); - - // Check thread 2. - var t = p.threads[2]; - assert.isDefined(t); - assert.equal(t.sliceGroup.length, 1); - assert.equal(t.tid, 2); - - slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'b'); - assert.equal(slice.category, 'bar'); - assert.equal(slice.start, (3 - 1) / 1000); - assert.equal(slice.duration, (4 - 3) / 1000); - assert.equal(slice.subSlices.length, 0); - }); - - test('multiplePidParsing', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'a', args: {}, pid: 1, ts: 2, cat: 'foo', tid: 1, ph: 'E'}, - {name: 'b', args: {}, pid: 2, ts: 3, cat: 'bar', tid: 2, ph: 'B'}, - {name: 'b', args: {}, pid: 2, ts: 4, cat: 'bar', tid: 2, ph: 'E'} - ]; - var m = makeModel(events); - assert.equal(m.numProcesses, 2); - var p = m.processes[1]; - assert.isDefined(p); - - assert.equal(p.numThreads, 1); - - // Check process 1 thread 1. - var t = p.threads[1]; - assert.isDefined(t); - assert.equal(t.sliceGroup.length, 1); - assert.equal(t.tid, 1); - - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - assert.equal(slice.start, 0); - assert.equal(slice.duration, (2 - 1) / 1000); - assert.equal(slice.subSlices.length, 0); - - // Check process 2 thread 2. - var p = m.processes[2]; - assert.isDefined(p); - assert.equal(p.numThreads, 1); - var t = p.threads[2]; - assert.isDefined(t); - assert.equal(t.sliceGroup.length, 1); - assert.equal(t.tid, 2); - - slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'b'); - assert.equal(slice.category, 'bar'); - assert.equal(slice.start, (3 - 1) / 1000); - assert.equal(slice.duration, (4 - 3) / 1000); - assert.equal(slice.subSlices.length, 0); - - // Check getAllThreads. - assert.deepEqual(m.getAllThreads(), - [m.processes[1].threads[1], m.processes[2].threads[2]]); - }); - - // Process names. - test('processNames', function() { - var events = [ - {name: 'process_name', args: {name: 'SomeProcessName'}, - pid: 1, ts: 0, tid: 1, ph: 'M'}, - {name: 'process_name', args: {name: 'SomeProcessName'}, - pid: 2, ts: 0, tid: 1, ph: 'M'} - ]; - var m = makeModel(events); - assert.equal(m.processes[1].name, 'SomeProcessName'); - }); - - // Process labels. - test('processLabels', function() { - var events = [ - {name: 'process_labels', args: {labels: 'foo,bar,bar,foo,baz'}, - pid: 1, ts: 0, tid: 1, ph: 'M'}, - {name: 'process_labels', args: {labels: 'baz'}, - pid: 2, ts: 0, tid: 1, ph: 'M'} - ]; - var m = makeModel(events); - assert.deepEqual(m.processes[1].labels, ['foo', 'bar', 'baz']); - assert.deepEqual(m.processes[2].labels, ['baz']); - }); - - // Process sort index. - test('processSortIndex', function() { - var events = [ - {name: 'process_name', args: {name: 'First'}, - pid: 2, ts: 0, tid: 1, ph: 'M'}, - {name: 'process_name', args: {name: 'Second'}, - pid: 2, ts: 0, tid: 1, ph: 'M'}, - {name: 'process_sort_index', args: {sort_index: 1}, - pid: 1, ts: 0, tid: 1, ph: 'M'} - ]; - var m = makeModel(events); - - // By name, p1 is before p2. But, its sort index overrides that. - assert.isAbove(m.processes[1].compareTo(m.processes[2]), 0); - }); - - // Thread names. - test('threadNames', function() { - var events = [ - {name: 'thread_name', args: {name: 'Thread 1'}, - pid: 1, ts: 0, tid: 1, ph: 'M'}, - {name: 'thread_name', args: {name: 'Thread 2'}, - pid: 2, ts: 0, tid: 2, ph: 'M'} - ]; - var m = makeModel(events, false, false); - assert.equal(m.processes[1].threads[1].name, 'Thread 1'); - assert.equal(m.processes[2].threads[2].name, 'Thread 2'); - }); - - // Thread sort index. - test('threadSortIndex', function() { - var events = [ - {name: 'thread_name', args: {name: 'Thread 1'}, - pid: 1, ts: 0, tid: 1, ph: 'M'}, - {name: 'thread_name', args: {name: 'Thread 2'}, - pid: 1, ts: 0, tid: 2, ph: 'M'}, - {name: 'thread_sort_index', args: {sort_index: 1}, - pid: 1, ts: 0, tid: 1, ph: 'M'} - ]; - var m = makeModel(events, false, false); - - // By name, t1 is before t2. But, its sort index overrides that. - var t1 = m.processes[1].threads[1]; - var t2 = m.processes[1].threads[2]; - assert.isAbove(t1.compareTo(t2), 0); - }); - - // CPU counts. - test('cpuCounts', function() { - var events = [ - {name: 'num_cpus', args: {number: 4}, - pid: 7, ts: 0, tid: 0, ph: 'M'}, - {name: 'num_cpus', args: {number: 4}, - pid: 14, ts: 0, tid: 0, ph: 'M'} - ]; - var m = makeModel(events); - assert.equal(m.kernel.softwareMeasuredCpuCount, 4); - assert.equal(m.kernel.bestGuessAtCpuCount, 4); - }); - - test('cpuCountsWithSandboxBeingConfused', function() { - var events = [ - {name: 'num_cpus', args: {number: 4}, - pid: 7, ts: 0, tid: 0, ph: 'M'}, - {name: 'num_cpus', args: {number: 1}, - pid: 14, ts: 0, tid: 0, ph: 'M'} - ]; - var m = makeModel(events); - assert.equal(m.kernel.softwareMeasuredCpuCount, 4); - assert.equal(m.kernel.bestGuessAtCpuCount, 4); - }); - - test('parsingWhenEndComesFirst', function() { - var events = [ - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'E'}, - {name: 'a', args: {}, pid: 1, ts: 4, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'a', args: {}, pid: 1, ts: 5, cat: 'foo', tid: 1, ph: 'E'} - ]; - var m = makeModel(events, false); - var p = m.processes[1]; - var t = p.threads[1]; - assert.equal(t.sliceGroup.length, 1); - assert.equal(t.sliceGroup.slices[0].title, 'a'); - assert.equal(t.sliceGroup.slices[0].category, 'foo'); - assert.equal(t.sliceGroup.slices[0].start, 0.004); - assert.equal(t.sliceGroup.slices[0].duration, 0.001); - assert.isTrue(m.hasImportWarnings); - assert.equal(m.importWarnings.length, 1); - }); - - test('immediateParsing', function() { - var events = [ - // Need to include immediates inside a task so the timeline - // recentering/zeroing doesn't clobber their timestamp. - {name: 'a', args: {}, pid: 1, ts: 1, cat: 'foo', tid: 1, ph: 'B'}, - {name: 'immediate', args: {}, pid: 1, ts: 2, cat: 'bar', tid: 1, ph: 'I'}, - {name: 'slower', args: {}, pid: 1, ts: 4, cat: 'baz', tid: 1, ph: 'i'}, - {name: 'a', args: {}, pid: 1, ts: 4, cat: 'foo', tid: 1, ph: 'E'} - ]; - var m = makeModel(events, false); - var p = m.processes[1]; - var t = p.threads[1]; - - assert.equal(t.sliceGroup.length, 3); - assert.equal(t.sliceGroup.slices[0].start, 0.001); - assert.equal(t.sliceGroup.slices[0].duration, 0.003); - assert.equal(t.sliceGroup.slices[1].start, 0.002); - assert.equal(t.sliceGroup.slices[1].duration, 0); - assert.equal(t.sliceGroup.slices[2].start, 0.004); - - var slice = findSliceNamed(t.sliceGroup, 'a'); - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - assert.equal(slice.duration, 0.003); - - var immed = findSliceNamed(t.sliceGroup, 'immediate'); - assert.equal(immed.title, 'immediate'); - assert.equal(immed.category, 'bar'); - assert.equal(immed.start, 0.002); - assert.equal(immed.duration, 0); - - var slower = findSliceNamed(t.sliceGroup, 'slower'); - assert.equal(slower.title, 'slower'); - assert.equal(slower.category, 'baz'); - assert.equal(slower.start, 0.004); - assert.equal(slower.duration, 0); - }); - - test('simpleCounter', function() { - var events = [ - {name: 'ctr', args: {'value': 0}, pid: 1, ts: 0, cat: 'foo', tid: 1, - ph: 'C'}, - {name: 'ctr', args: {'value': 10}, pid: 1, ts: 10, cat: 'foo', tid: 1, - ph: 'C'}, - {name: 'ctr', args: {'value': 0}, pid: 1, ts: 20, cat: 'foo', tid: 1, - ph: 'C'} - - ]; - var m = makeModel(events); - var p = m.processes[1]; - var ctr = m.processes[1].counters['foo.ctr']; - - assert.equal(ctr.name, 'ctr'); - assert.equal(ctr.category, 'foo'); - assert.equal(ctr.numSamples, 3); - assert.equal(ctr.numSeries, 1); - - assert.equal(ctr.series[0].name, 'value'); - assert.equal(ctr.series[0].color, - ColorScheme.getColorIdForGeneralPurposeString('ctr.value')); - - assert.deepEqual(ctr.timestamps, [0, 0.01, 0.02]); - - var samples = []; - ctr.series[0].samples.forEach(function(sample) { - samples.push(sample.value); - }); - assert.deepEqual(samples, [0, 10, 0]); - - assert.deepEqual(ctr.totals, [0, 10, 0]); - assert.equal(ctr.maxTotal, 10); - }); - - test('instanceCounter', function() { - var events = [ - {name: 'ctr', args: {'value': 0}, pid: 1, ts: 0, cat: 'foo', tid: 1, - ph: 'C', id: 0}, - {name: 'ctr', args: {'value': 10}, pid: 1, ts: 10, cat: 'foo', tid: 1, - ph: 'C', id: 0}, - {name: 'ctr', args: {'value': 10}, pid: 1, ts: 10, cat: 'foo', tid: 1, - ph: 'C', id: 1}, - {name: 'ctr', args: {'value': 20}, pid: 1, ts: 15, cat: 'foo', tid: 1, - ph: 'C', id: 1}, - {name: 'ctr', args: {'value': 30}, pid: 1, ts: 18, cat: 'foo', tid: 1, - ph: 'C', id: 1}, - {name: 'ctr', args: {'value': 40}, pid: 1, ts: 20, cat: 'bar', tid: 1, - ph: 'C', id: 2} - ]; - var m = makeModel(events); - var p = m.processes[1]; - var ctr = m.processes[1].counters['foo.ctr[0]']; - assert.equal(ctr.name, 'ctr[0]'); - assert.equal(ctr.category, 'foo'); - assert.equal(ctr.numSamples, 2); - assert.equal(ctr.numSeries, 1); - - assert.deepEqual(ctr.timestamps, [0, 0.01]); - var samples = []; - ctr.series[0].samples.forEach(function(sample) { - samples.push(sample.value); - }); - assert.deepEqual(samples, [0, 10]); - - ctr = m.processes[1].counters['foo.ctr[1]']; - assert.equal(ctr.name, 'ctr[1]'); - assert.equal(ctr.category, 'foo'); - assert.equal(ctr.numSamples, 3); - assert.equal(ctr.numSeries, 1); - assert.deepEqual(ctr.timestamps, [0.01, 0.015, 0.018]); - - samples = []; - ctr.series[0].samples.forEach(function(sample) { - samples.push(sample.value); - }); - assert.deepEqual(samples, [10, 20, 30]); - - ctr = m.processes[1].counters['bar.ctr[2]']; - assert.equal(ctr.name, 'ctr[2]'); - assert.equal(ctr.category, 'bar'); - assert.equal(ctr.numSamples, 1); - assert.equal(ctr.numSeries, 1); - assert.deepEqual(ctr.timestamps, [0.02]); - var samples = []; - ctr.series[0].samples.forEach(function(sample) { - samples.push(sample.value); - }); - assert.deepEqual(samples, [40]); - }); - - test('multiCounterUpdateBounds', function() { - var ctr = new tr.model.Counter(undefined, 'testBasicCounter', - '', 'testBasicCounter'); - var value1Series = new tr.model.CounterSeries( - 'value1', 'testBasicCounter.value1'); - var value2Series = new tr.model.CounterSeries( - 'value2', 'testBasicCounter.value2'); - ctr.addSeries(value1Series); - ctr.addSeries(value2Series); - - value1Series.addCounterSample(0, 0); - value1Series.addCounterSample(1, 1); - value1Series.addCounterSample(2, 1); - value1Series.addCounterSample(3, 2); - value1Series.addCounterSample(4, 3); - value1Series.addCounterSample(5, 1); - value1Series.addCounterSample(6, 3); - value1Series.addCounterSample(7, 3.1); - - value2Series.addCounterSample(0, 0); - value2Series.addCounterSample(1, 0); - value2Series.addCounterSample(2, 1); - value2Series.addCounterSample(3, 1.1); - value2Series.addCounterSample(4, 0); - value2Series.addCounterSample(5, 7); - value2Series.addCounterSample(6, 0); - value2Series.addCounterSample(7, 0.5); - - ctr.updateBounds(); - - assert.equal(ctr.bounds.min, 0); - assert.equal(ctr.bounds.max, 7); - assert.equal(ctr.maxTotal, 8); - assert.deepEqual([0, 0, - 1, 1, - 1, 2, - 2, 3.1, - 3, 3, - 1, 8, - 3, 3, - 3.1, 3.6], ctr.totals); - }); - - test('multiCounter', function() { - var events = [ - {name: 'ctr', args: {'value1': 0, 'value2': 7}, pid: 1, ts: 0, cat: 'foo', tid: 1, ph: 'C'}, // @suppress longLineCheck - {name: 'ctr', args: {'value1': 10, 'value2': 4}, pid: 1, ts: 10, cat: 'foo', tid: 1, ph: 'C'}, // @suppress longLineCheck - {name: 'ctr', args: {'value1': 0, 'value2': 1 }, pid: 1, ts: 20, cat: 'foo', tid: 1, ph: 'C'} // @suppress longLineCheck - ]; - var m = makeModel(events); - var p = m.processes[1]; - var ctr = m.processes[1].counters['foo.ctr']; - assert.equal(ctr.name, 'ctr'); - - assert.equal(ctr.name, 'ctr'); - assert.equal(ctr.category, 'foo'); - assert.equal(ctr.numSamples, 3); - assert.equal(ctr.numSeries, 2); - - assert.equal(ctr.series[0].name, 'value1'); - assert.equal(ctr.series[1].name, 'value2'); - assert.equal(ctr.series[0].color, - ColorScheme.getColorIdForGeneralPurposeString('ctr.value1')); - assert.equal(ctr.series[1].color, - ColorScheme.getColorIdForGeneralPurposeString('ctr.value2')); - - assert.deepEqual(ctr.timestamps, [0, 0.01, 0.02]); - var samples = []; - ctr.series[0].samples.forEach(function(sample) { - samples.push(sample.value); - }); - assert.deepEqual(samples, [0, 10, 0]); - - var samples1 = []; - ctr.series[1].samples.forEach(function(sample) { - samples1.push(sample.value); - }); - assert.deepEqual(samples1, [7, 4, 1]); - assert.deepEqual([0, 7, - 10, 14, - 0, 1], ctr.totals); - assert.equal(ctr.maxTotal, 14); - }); - - test('importObjectInsteadOfArray', function() { - var events = { traceEvents: [ - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ] }; - - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - }); - - test('importString', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ]; - - var m = makeModel(JSON.stringify(events)); - assert.equal(m.numProcesses, 1); - }); - - test('importStringWithLeadingSpaces', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ]; - - var m = makeModel(' ' + JSON.stringify(events)); - assert.equal(m.numProcesses, 1); - }); - - test('importStringWithTrailingNewLine', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ]; - - var m = makeModel(JSON.stringify(events) + '\n'); - assert.equal(m.numProcesses, 1); - }); - - test('importStringWithMissingCloseSquareBracket', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ]; - - var tmp = JSON.stringify(events); - assert.equal(tmp[tmp.length - 1], ']'); - - // Drop off the trailing ] - var dropped = tmp.substring(0, tmp.length - 1); - var m = makeModel(dropped); - assert.equal(m.numProcesses, 1); - }); - - test('importStringWithEndingCommaButMissingCloseSquareBracket', function() { - var lines = [ - '[', - '{"name": "a", "args": {}, "pid": 52, "ts": 524, "cat": "foo", "tid": 53, "ph": "B"},', // @suppress longLineCheck - '{"name": "a", "args": {}, "pid": 52, "ts": 560, "cat": "foo", "tid": 53, "ph": "E"},' // @suppress longLineCheck - ]; - var text = lines.join('\n'); - - var m = makeModel(text); - assert.equal(m.numProcesses, 1); - assert.equal(m.processes[52].threads[53].sliceGroup.length, 1); - }); - - test('importStringWithMissingCloseSquareBracketAndNewline', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ]; - - var tmp = JSON.stringify(events); - assert.equal(tmp[tmp.length - 1], ']'); - - // Drop off the trailing ] and add a newline - var dropped = tmp.substring(0, tmp.length - 1); - var m = makeModel(dropped + '\n'); - assert.equal(m.numProcesses, 1); - }); - - test('ImportStringEndingCommaButMissingCloseSquareBracketCRLF', function() { - var lines = [ - '[', - '{"name": "a", "args": {}, "pid": 52, "ts": 524, "cat": "foo", "tid": 53, "ph": "B"},', // @suppress longLineCheck - '{"name": "a", "args": {}, "pid": 52, "ts": 560, "cat": "foo", "tid": 53, "ph": "E"},' // @suppress longLineCheck - ]; - var text = lines.join('\r\n'); - - var m = makeModel(text); - assert.equal(m.numProcesses, 1); - assert.equal(m.processes[52].threads[53].sliceGroup.length, 1); - }); - - test('importOldFormat', function() { - var lines = [ - '[', - '{"cat":"a","pid":9,"tid":8,"ts":194,"ph":"E","name":"I","args":{}},', - '{"cat":"b","pid":9,"tid":8,"ts":194,"ph":"B","name":"I","args":{}}', - ']' - ]; - var text = lines.join('\n'); - var m = makeModel(text); - assert.equal(m.numProcesses, 1); - assert.equal(m.processes[9].threads[8].sliceGroup.length, 1); - }); - - test('startFinishOneSliceOneThread', function() { - var events = [ - // Time is intentionally out of order. - {name: 'a', args: {}, pid: 52, ts: 560, cat: 'cat', tid: 53, - ph: 'F', id: 72}, - {name: 'a', pid: 52, ts: 524, cat: 'cat', tid: 53, - ph: 'S', id: 72, args: {'foo': 'bar'}} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - assert.equal(t.asyncSliceGroup.slices[0].title, 'a'); - assert.equal(t.asyncSliceGroup.slices[0].category, 'cat'); - assert.isTrue(t.asyncSliceGroup.slices[0].isTopLevel); - assert.equal(t.asyncSliceGroup.slices[0].id, 72); - assert.equal(t.asyncSliceGroup.slices[0].args.foo, 'bar'); - assert.equal(t.asyncSliceGroup.slices[0].start, 0); - assert.closeTo( - (60 - 24) / 1000, t.asyncSliceGroup.slices[0].duration, 1e-5); - assert.equal(t.asyncSliceGroup.slices[0].startThread, t); - assert.equal(t.asyncSliceGroup.slices[0].endThread, t); - }); - - test('endArgsAddedToSlice', function() { - var events = [ - {name: 'a', args: {x: 1}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'a', args: {y: 2}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'E'} - ]; - - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - var p = m.processes[52]; - assert.isDefined(p); - - assert.equal(p.numThreads, 1); - var t = p.threads[53]; - assert.isDefined(t); - assert.equal(t.sliceGroup.length, 1); - assert.equal(t.tid, 53); - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'foo'); - assert.equal(slice.start, 0); - assert.equal(slice.subSlices.length, 0); - assert.equal(slice.args['x'], 1); - assert.equal(slice.args['y'], 2); - }); - - test('endArgOverrwritesOriginalArgValueIfDuplicated', function() { - var events = [ - {name: 'b', args: {z: 3}, pid: 52, ts: 629, cat: 'foo', tid: 53, ph: 'B'}, - {name: 'b', args: {z: 4}, pid: 52, ts: 631, cat: 'foo', tid: 53, ph: 'E'} - ]; - - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - var p = m.processes[52]; - assert.isDefined(p); - - assert.equal(p.numThreads, 1); - var t = p.threads[53]; - assert.isDefined(t); - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'b'); - assert.equal(slice.category, 'foo'); - assert.equal(slice.start, 0); - assert.equal(slice.subSlices.length, 0); - assert.equal(slice.args['z'], 4); - }); - - test('asyncEndArgsAddedToSlice', function() { - var events = [ - // Time is intentionally out of order. - {name: 'c', args: {y: 2}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'F', id: 72}, - {name: 'c', args: {x: 1}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'S', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'c'); - assert.equal(parentSlice.category, 'foo'); - assert.isTrue(parentSlice.isTopLevel); - assert.equal(parentSlice.args['x'], 1); - assert.equal(parentSlice.args['y'], 2); - - assert.isDefined(parentSlice.subSlices); - assert.equal(parentSlice.subSlices.length, 0); - }); - - test('asyncEndArgOverwritesOriginalArgValueIfDuplicated', function() { - var events = [ - // Time is intentionally out of order. - {name: 'd', args: {z: 4}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'F', id: 72}, - {name: 'd', args: {z: 3}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'S', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'd'); - assert.equal(parentSlice.category, 'foo'); - assert.isTrue(parentSlice.isTopLevel); - assert.equal(parentSlice.args['z'], 4); - - assert.isDefined(parentSlice.subSlices); - assert.equal(parentSlice.subSlices.length, 0); - }); - - test('asyncStepsInOneThread', function() { - var events = [ - // Time is intentionally out of order. - {name: 'a', args: {z: 3}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'F', id: 72}, // @suppress longLineCheck - {name: 'a', args: {step: 's1', y: 2}, pid: 52, ts: 548, cat: 'foo', tid: 53, ph: 'T', id: 72}, // @suppress longLineCheck - {name: 'a', args: {x: 1}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'S', id: 72} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'a'); - assert.equal(parentSlice.category, 'foo'); - assert.isTrue(parentSlice.isTopLevel); - assert.equal(parentSlice.start, 0); - assert.equal(parentSlice.args['x'], 1); - assert.isUndefined(parentSlice.args['y']); - assert.equal(parentSlice.args['z'], 3); - - assert.isDefined(parentSlice.subSlices); - assert.equal(parentSlice.subSlices.length, 1); - - var subSlice = parentSlice.subSlices[0]; - assert.equal(subSlice.title, 'a:s1'); - assert.equal(subSlice.category, 'foo'); - assert.isFalse(subSlice.isTopLevel); - assert.closeTo((548 - 524) / 1000, subSlice.start, 1e-5); - assert.closeTo((560 - 548) / 1000, subSlice.duration, 1e-5); - assert.isUndefined(subSlice.args['x']); - assert.equal(subSlice.args['y'], 2); - assert.isUndefined(subSlice.args['z']); - }); - - test('asyncStepsMissingStart', function() { - var events = [ - // Time is intentionally out of order. - {name: 'a', args: {z: 3}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'F', id: 72}, - {name: 'a', args: {step: 's1', y: 2}, pid: 52, ts: 548, cat: 'foo', - tid: 53, ph: 'T', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isUndefined(t); - }); - - test('asyncStepsMissingFinish', function() { - var events = [ - // Time is intentionally out of order. - {name: 'a', args: {step: 's1', y: 2}, pid: 52, ts: 548, cat: 'foo', - tid: 53, ph: 'T', id: 72}, - {name: 'a', args: {z: 3}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'S', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isUndefined(t); - }); - - test('asyncStepEndEvent', function() { - var events = [ - // Time is intentionally out of order. - {name: 'a', args: {z: 3}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'F', id: 72}, - {name: 'a', args: {step: 's1', y: 2}, pid: 52, ts: 548, cat: 'foo', - tid: 53, ph: 'p', id: 72}, - {name: 'a', args: {x: 1}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'S', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'a'); - assert.equal(parentSlice.category, 'foo'); - assert.isTrue(parentSlice.isTopLevel); - assert.equal(parentSlice.start, 0); - assert.equal(parentSlice.args['x'], 1); - assert.isUndefined(parentSlice.args['y']); - assert.equal(parentSlice.args['z'], 3); - - assert.isDefined(parentSlice.subSlices); - assert.equal(parentSlice.subSlices.length, 1); - var subSlice = parentSlice.subSlices[0]; - assert.equal(subSlice.title, 'a:s1'); - assert.equal(subSlice.category, 'foo'); - assert.isFalse(subSlice.isTopLevel); - assert.equal(subSlice.start, 0); - assert.closeTo((548 - 524) / 1000, subSlice.duration, 1e-5); - assert.isUndefined(subSlice.args['x']); - assert.equal(subSlice.args['y'], 2); - assert.isUndefined(subSlice.args['z']); - }); - - test('asyncStepMismatch', function() { - var events = [ - // Time is intentionally out of order. - {name: 'a', args: {z: 3}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'F', id: 72}, - {name: 'a', args: {step: 's2'}, pid: 52, ts: 548, cat: 'foo', tid: 53, - ph: 'T', id: 72}, - {name: 'a', args: {step: 's1'}, pid: 52, ts: 548, cat: 'foo', tid: 53, - ph: 'p', id: 72}, - {name: 'a', args: {x: 1}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'S', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isUndefined(t); - assert.isTrue(m.hasImportWarnings); - }); - - test('asyncSliceWithoutCPUDuration', function() { - var events = [ - // Async slice without tts field. - {name: 'a', args: {params: ''}, pid: 52, ts: 10, cat: 'foo', tid: 53, - id: 72, ph: 'b'}, - {name: 'a', args: {params: ''}, pid: 52, ts: 20, cat: 'foo', tid: 53, - id: 72, ph: 'e'}, - // Async slice with tts field but without use_async_tts marker field. - {name: 'b', args: {params: ''}, pid: 52, ts: 30, cat: 'foo', tid: 53, - id: 72, ph: 'b', tts: 30000}, - {name: 'b', args: {params: ''}, pid: 52, ts: 40, cat: 'foo', tid: 53, - id: 72, ph: 'e', tts: 40000}, - // Async slice with tts field but with use_async_tts marker set to 0. - {name: 'c', args: {params: ''}, pid: 52, ts: 50000, cat: 'foo', tid: 53, - id: 72, ph: 'b', tts: 50000, use_async_tts: 0}, - {name: 'c', args: {params: ''}, pid: 52, ts: 60000, cat: 'foo', tid: 53, - id: 72, ph: 'e', tts: 60000, use_async_tts: 0} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 3); - - var noTTSNoField = t.asyncSliceGroup.slices[0]; - assert.isUndefined(noTTSNoField.cpuStart); - assert.isUndefined(noTTSNoField.cpuDuration); - - var TTSNoField = t.asyncSliceGroup.slices[1]; - assert.isUndefined(TTSNoField.cpuStart); - assert.isUndefined(TTSNoField.cpuDuration); - - var TTSZeroField = t.asyncSliceGroup.slices[2]; - assert.isUndefined(TTSZeroField.cpuStart); - assert.isUndefined(TTSZeroField.cpuDuration); - }); - - test('asyncSliceWithCPUDuration', function() { - var events = [ - {name: 'a', args: {params: ''}, pid: 52, ts: 50000, cat: 'foo', tid: 53, - id: 72, ph: 'b', tts: 100000, use_async_tts: 1}, - {name: 'a', args: {params: ''}, pid: 52, ts: 60000, cat: 'foo', tid: 53, - id: 72, ph: 'e', tts: 105000, use_async_tts: 1} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - - var asyncSlice = t.asyncSliceGroup.slices[0]; - assert.isDefined(asyncSlice); - assert.equal(asyncSlice.duration, 10); - assert.equal(asyncSlice.cpuStart, 100); - assert.equal(asyncSlice.cpuDuration, 5); - }); - - test('nestableAsyncBasic', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'b', args: {x: 1}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'b', args: {y: 2}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'e', id: 72}, - {name: 'a', args: {}, pid: 52, ts: 565, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'a'); - assert.equal(parentSlice.category, 'foo'); - assert.isTrue(parentSlice.isTopLevel); - - assert.isDefined(parentSlice.subSlices); - assert.equal(parentSlice.subSlices.length, 1); - var subSlice = parentSlice.subSlices[0]; - assert.isFalse(subSlice.isTopLevel); - // Arguments should include both BEGIN and END event. - assert.equal(subSlice.args['x'], 1); - assert.equal(subSlice.args['y'], 2); - assert.sameMembers(subSlice.subSlices, []); - }); - - - test('nestableAsyncNoArgs', function() { - var events = [ - {name: 'name', pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'name', pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var slice = t.asyncSliceGroup.slices[0]; - assert.equal(slice.title, 'name'); - assert.equal(slice.category, 'foo'); - assert.isTrue(slice.isTopLevel); - - assert.isDefined(slice.subSlices); - assert.equal(slice.subSlices.length, 0); - - assert.deepEqual(slice.args, {}); - }); - - test('nestableAsyncCombinedParams', function() { - var events = [ - {name: 'a', args: {x: 1, params: {p1: 'hello', p2: 123}}, - pid: 52, ts: 525, cat: 'foo', tid: 53, ph: 'b', id: 72}, - {name: 'a', args: {y: 2, params: {p3: 'hi'}}, pid: 52, ts: 560, - cat: 'foo', tid: 53, ph: 'e', id: 72}, - {name: 'b', args: {params: {p4: 'foo'}}, - pid: 52, ts: 525, cat: 'foo', tid: 53, ph: 'b', id: 73}, - {name: 'b', args: {params: ''}, pid: 52, ts: 560, - cat: 'foo', tid: 53, ph: 'e', id: 73}, - {name: 'c', args: {params: {p5: 'bar'}}, - pid: 52, ts: 525, cat: 'foo', tid: 53, ph: 'b', id: 74}, - {name: 'c', args: {}, pid: 52, ts: 560, - cat: 'foo', tid: 53, ph: 'e', id: 74} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 3); - - var sliceA = t.asyncSliceGroup.slices[0]; - // Arguments should include both BEGIN and END event. - assert.equal(sliceA.args['x'], 1); - assert.equal(sliceA.args['y'], 2); - var paramsA = sliceA.args['params']; - assert.isDefined(paramsA); - assert.equal(paramsA.p1, 'hello'); - assert.equal(paramsA.p2, 123); - assert.equal(paramsA.p3, 'hi'); - assert.isTrue(sliceA.isTopLevel); - - var sliceB = t.asyncSliceGroup.slices[1]; - // Arguments should include both BEGIN and END event. - var paramsB = sliceB.args['params']; - assert.isDefined(paramsB); - assert.equal(paramsB.p4, 'foo'); - assert.isTrue(sliceB.isTopLevel); - - var sliceC = t.asyncSliceGroup.slices[2]; - // Arguments should include both BEGIN and END event. - var paramsC = sliceC.args['params']; - assert.isDefined(paramsC); - assert.equal(paramsC.p5, 'bar'); - assert.isTrue(sliceC.isTopLevel); - }); - - test('nestableAsyncManyLevels', function() { - // There are 5 nested levels. - var events = [ - {name: 'l1', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'l2', args: {}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'l3', args: {}, pid: 52, ts: 526, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'l4', args: {}, pid: 52, ts: 527, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'l5', args: {}, pid: 52, ts: 528, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'l5', args: {}, pid: 52, ts: 529, cat: 'foo', tid: 53, - ph: 'e', id: 72}, - {name: 'l4', args: {}, pid: 52, ts: 530, cat: 'foo', tid: 53, - ph: 'e', id: 72}, - {name: 'l3', args: {}, pid: 52, ts: 531, cat: 'foo', tid: 53, - ph: 'e', id: 72}, - {name: 'l2', args: {}, pid: 52, ts: 532, cat: 'foo', tid: 53, - ph: 'e', id: 72}, - {name: 'l1', args: {}, pid: 52, ts: 533, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - // Perfectly matched events should not produce a warning. - assert.isFalse(m.hasImportWarnings); - assert.equal(t.asyncSliceGroup.slices.length, 1); - - var l1Slice = t.asyncSliceGroup.slices[0]; - assert.equal(l1Slice.title, 'l1'); - assert.closeTo(0, l1Slice.start, 1e-5); - assert.closeTo(9 / 1000, l1Slice.duration, 1e-5); - assert.isTrue(l1Slice.isTopLevel); - - assert.isDefined(l1Slice.subSlices); - assert.equal(l1Slice.subSlices.length, 1); - var l2Slice = l1Slice.subSlices[0]; - assert.equal(l2Slice.title, 'l2'); - assert.closeTo(1 / 1000, l2Slice.start, 1e-5); - assert.closeTo(7 / 1000, l2Slice.duration, 1e-5); - assert.isFalse(l2Slice.isTopLevel); - - assert.isDefined(l2Slice.subSlices); - assert.equal(l2Slice.subSlices.length, 1); - var l3Slice = l2Slice.subSlices[0]; - assert.equal(l3Slice.title, 'l3'); - assert.closeTo(2 / 1000, l3Slice.start, 1e-5); - assert.closeTo(5 / 1000, l3Slice.duration, 1e-5); - assert.isFalse(l3Slice.isTopLevel); - - assert.isDefined(l3Slice.subSlices); - assert.equal(l3Slice.subSlices.length, 1); - var l4Slice = l3Slice.subSlices[0]; - assert.equal(l4Slice.title, 'l4'); - assert.closeTo(3 / 1000, l4Slice.start, 1e-5); - assert.closeTo(3 / 1000, l4Slice.duration, 1e-5); - assert.isFalse(l4Slice.isTopLevel); - - assert.isDefined(l4Slice.subSlices); - assert.equal(l4Slice.subSlices.length, 1); - var l5Slice = l4Slice.subSlices[0]; - assert.equal(l5Slice.title, 'l5'); - assert.closeTo(4 / 1000, l5Slice.start, 1e-5); - assert.closeTo(1 / 1000, l5Slice.duration, 1e-5); - assert.isFalse(l5Slice.isTopLevel); - }); - - test('nestableAsyncInstantEvent', function() { - var events = [ - {name: 'c', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'n', id: 71}, - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'd', args: {}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'n', id: 72}, - {name: 'a', args: {}, pid: 52, ts: 565, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 2); - var instantSlice = t.asyncSliceGroup.slices[0]; - assert.equal(instantSlice.title, 'c'); - assert.closeTo(0, instantSlice.start, 1e-5); - assert.closeTo(0, instantSlice.duration, 1e-5); - assert.sameMembers(instantSlice.subSlices, []); - assert.isTrue(instantSlice.isTopLevel); - - var nestedSlice = t.asyncSliceGroup.slices[1]; - assert.equal(nestedSlice.title, 'a'); - assert.closeTo(0, nestedSlice.start, 1e-5); - assert.closeTo((565 - 524) / 1000, nestedSlice.duration, 1e-5); - assert.isTrue(nestedSlice.isTopLevel); - assert.isDefined(nestedSlice.subSlices); - assert.equal(nestedSlice.subSlices.length, 1); - var nestedInstantSlice = nestedSlice.subSlices[0]; - assert.sameMembers(nestedInstantSlice.subSlices, []); - assert.equal(nestedInstantSlice.title, 'd'); - assert.isFalse(nestedInstantSlice.isTopLevel); - }); - - test('nestableAsyncUnmatchedOuterBeginEvent', function() { - var events = [ - {name: 'a', args: {x: 1}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'b', args: {}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'b', args: {y: 2}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - // Unmatched BEGIN should produce a warning. - assert.isTrue(m.hasImportWarnings); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'a'); - assert.equal(parentSlice.category, 'foo'); - assert.isTrue(parentSlice.isTopLevel); - assert.closeTo(0, parentSlice.start, 0.0001); - // Unmatched BEGIN event ends at the last event of that ID. - assert.closeTo(36 / 1000, parentSlice.duration, 0.0001); - // Arguments should include only include its arguments. - assert.isUndefined(parentSlice.args['y']); - assert.equal(parentSlice.args['x'], 1); - assert.isDefined(parentSlice.error); - - assert.isDefined(parentSlice.subSlices); - assert.equal(parentSlice.subSlices.length, 1); - var subSlice = parentSlice.subSlices[0]; - assert.isFalse(subSlice.isTopLevel); - assert.closeTo(1 / 1000, subSlice.start, 1e-5); - assert.closeTo(35 / 1000, subSlice.duration, 1e-5); - assert.sameMembers(subSlice.subSlices, []); - // Arguments should include those of the END event. - assert.equal(subSlice.args['y'], 2); - assert.sameMembers(subSlice.subSlices, []); - }); - - test('nestableAsyncUnmatchedInnerBeginEvent', function() { - var events = [ - {name: 'a', args: {z: 3}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'c', args: {}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'n', id: 72}, - {name: 'b', args: {x: 1}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'a', args: {y: 2}, pid: 52, ts: 565, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - // Unmatched BEGIN should produce a warning. - assert.isTrue(m.hasImportWarnings); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'a'); - assert.equal(parentSlice.category, 'foo'); - assert.isTrue(parentSlice.isTopLevel); - assert.closeTo(0, parentSlice.start, 1e-5); - assert.closeTo(41 / 1000, parentSlice.duration, 1e-5); - // Arguments should include both BEGIN and END event. - assert.equal(parentSlice.args['y'], 2); - assert.equal(parentSlice.args['z'], 3); - assert.isUndefined(parentSlice.args['x']); - - assert.isDefined(parentSlice.subSlices); - assert.equal(parentSlice.subSlices.length, 2); - var subSliceInstant = parentSlice.subSlices[0]; - var subSliceUnmatched = parentSlice.subSlices[1]; - assert.equal(subSliceInstant.title, 'c'); - assert.isFalse(subSliceInstant.isTopLevel); - assert.equal(subSliceUnmatched.title, 'b'); - assert.isFalse(subSliceUnmatched.isTopLevel); - // Unmatched BEGIN ends at the last event of that ID. - assert.closeTo(1 / 1000, subSliceUnmatched.start, 1e-5); - assert.closeTo(40 / 1000, subSliceUnmatched.duration, 1e-5); - assert.sameMembers(subSliceUnmatched.subSlices, []); - assert.equal(subSliceUnmatched.args['x'], 1); - assert.isUndefined(subSliceUnmatched['y']); - assert.isDefined(subSliceUnmatched.error); - assert.closeTo(1 / 1000, subSliceInstant.start, 1e-5); - assert.closeTo(0, subSliceInstant.duration, 1e-5); - assert.sameMembers(subSliceInstant.subSlices, []); - }); - - test('nestableAsyncUnmatchedOuterEndEvent', function() { - // Events are intentionally out-of-order. - var events = [ - {name: 'b', args: {x: 1}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'b', args: {y: 2}, pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'e', id: 72}, - {name: 'a', args: {z: 3}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - // Unmatched END should produce a warning. - assert.isTrue(m.hasImportWarnings); - assert.equal(t.asyncSliceGroup.slices.length, 2); - var unmatchedSlice = t.asyncSliceGroup.slices[0]; - var slice = t.asyncSliceGroup.slices[1]; - assert.equal(unmatchedSlice.title, 'a'); - assert.closeTo(0, unmatchedSlice.start, 1e-5); - assert.isTrue(unmatchedSlice.isTopLevel); - // Unmatched END event begins at the first event of that ID. In this - // case, the first event happens to be the same unmatched event. - assert.closeTo(0 / 1000, unmatchedSlice.duration, 1e-5); - assert.isUndefined(unmatchedSlice.args['x']); - assert.isUndefined(unmatchedSlice.args['y']); - assert.equal(unmatchedSlice.args['z'], 3); - assert.isDefined(unmatchedSlice.error); - assert.sameMembers(unmatchedSlice.subSlices, []); - - assert.equal(slice.title, 'b'); - assert.isTrue(slice.isTopLevel); - assert.closeTo(1 / 1000, slice.start, 1e-5); - assert.closeTo(35 / 1000, slice.duration, 1e-5); - // Arguments should include both BEGIN and END event. - assert.equal(slice.args['x'], 1); - assert.equal(slice.args['y'], 2); - assert.sameMembers(slice.subSlices, []); - }); - - test('nestableAsyncUnmatchedInnerEndEvent', function() { - var events = [ - {name: 'a', args: {x: 1}, pid: 52, ts: 524, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'c', args: {}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'n', id: 72}, - {name: 'b', args: {z: 3}, pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'e', id: 72}, - {name: 'a', args: {y: 2}, pid: 52, ts: 565, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - // Unmatched END should produce a warning. - assert.isTrue(m.hasImportWarnings); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'a'); - assert.isTrue(parentSlice.isTopLevel); - assert.closeTo(0, parentSlice.start, 1e-5); - assert.closeTo(41 / 1000, parentSlice.duration, 1e-5); - // Arguments should include both BEGIN and END event. - assert.equal(parentSlice.args['x'], 1); - assert.equal(parentSlice.args['y'], 2); - - assert.isDefined(parentSlice.subSlices); - assert.equal(parentSlice.subSlices.length, 2); - var subSliceInstant = parentSlice.subSlices[0]; - var subSliceUnmatched = parentSlice.subSlices[1]; - assert.equal(subSliceInstant.title, 'c'); - assert.isFalse(subSliceInstant.isTopLevel); - assert.equal(subSliceUnmatched.title, 'b'); - assert.isFalse(subSliceUnmatched.isTopLevel); - // Unmatched END begins at the first event of that ID. - assert.closeTo(0 / 1000, subSliceUnmatched.start, 1e-5); - assert.closeTo(1 / 1000, subSliceUnmatched.duration, 1e-5); - // Arguments should include both BEGIN and END event. - assert.isUndefined(subSliceUnmatched.args['x']); - assert.isUndefined(subSliceUnmatched.args['y']); - assert.equal(subSliceUnmatched.args['z'], 3); - assert.isDefined(subSliceUnmatched.error); - - assert.sameMembers(subSliceUnmatched.subSlices, []); - assert.closeTo(1 / 1000, subSliceInstant.start, 1e-5); - assert.closeTo(0, subSliceInstant.duration, 1e-5); - assert.sameMembers(subSliceInstant.subSlices, []); - }); - - test('nestableAsyncSameIDDifferentCategory', function() { - // Events with the same ID, but different categories should not be - // considered as nested. - var events = [ - {name: 'EVENT_A', args: {}, pid: 52, ts: 500, cat: 'foo', tid: 53, - ph: 'b', id: 72}, - {name: 'EVENT_B', args: {y: 2}, pid: 52, ts: 550, cat: 'bar', tid: 53, - ph: 'b', id: 72}, - {name: 'EVENT_B', args: {}, pid: 52, ts: 600, cat: 'bar', tid: 53, - ph: 'e', id: 72}, - {name: 'EVENT_A', args: {x: 1}, pid: 52, ts: 650, cat: 'foo', tid: 53, - ph: 'e', id: 72} - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 2); - var eventASlice = t.asyncSliceGroup.slices[0]; - assert.equal(eventASlice.title, 'EVENT_A'); - assert.equal(eventASlice.category, 'foo'); - assert.equal(eventASlice.id, 'foo:72'); - assert.isTrue(eventASlice.isTopLevel); - assert.equal(eventASlice.args['x'], 1); - assert.sameMembers(eventASlice.subSlices, []); - - var eventBSlice = t.asyncSliceGroup.slices[1]; - assert.equal(eventBSlice.title, 'EVENT_B'); - assert.equal(eventBSlice.category, 'bar'); - assert.equal(eventBSlice.id, 'bar:72'); - assert.isTrue(eventBSlice.isTopLevel); - assert.equal(eventBSlice.args['y'], 2); - assert.sameMembers(eventBSlice.subSlices, []); - }); - - test('nestableAsyncStackFrame', function() { - var events = { - traceEvents: [ - {name: 'name', pid: 52, ts: 525, cat: 'foo', tid: 53, - ph: 'b', id: 72, sf: 1}, - {name: 'name', pid: 52, ts: 560, cat: 'foo', tid: 53, - ph: 'e', id: 72, sf: 7} - ], - stackFrames: { - '1': { - category: 'm1', - name: 'main' - }, - '7': { - category: 'm2', - name: 'frame7', - parent: '1' - } - } - }; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - assert.isDefined(t); - assert.equal(t.asyncSliceGroup.slices.length, 1); - var slice = t.asyncSliceGroup.slices[0]; - - assert.equal(slice.startStackFrame.title, 'main'); - assert.equal(slice.endStackFrame.title, 'frame7'); - }); - - test('importSamples', function() { - var events = [ - {name: 'a', args: {}, pid: 52, ts: 548, cat: 'test', tid: 53, ph: 'P'}, - {name: 'b', args: {}, pid: 52, ts: 548, cat: 'test', tid: 53, ph: 'P'}, - {name: 'c', args: {}, pid: 52, ts: 558, cat: 'test', tid: 53, ph: 'P'}, - {name: 'a', args: {}, pid: 52, ts: 568, cat: 'test', tid: 53, ph: 'P'} - ]; - var m = makeModel(events); - var p = m.processes[52]; - assert.isDefined(p); - var t = p.threads[53]; - assert.isDefined(t); - assert.equal(t.samples_.length, 4); - assert.equal(t.samples_[0].start, 0.0); - assert.equal(t.samples_[1].start, 0.0); - assert.closeTo(0.01, t.samples_[2].start, 1e-5); - assert.equal(t.samples_[0].leafStackFrame.title, 'a'); - assert.equal(t.samples_[1].leafStackFrame.title, 'b'); - assert.equal(t.samples_[2].leafStackFrame.title, 'c'); - assert.equal(t.samples_[3].leafStackFrame, t.samples[0].leafStackFrame); - assert.isFalse(m.hasImportWarnings); - }); - - test('importSamplesWithStackFrames', function() { - var eventData = { - traceEvents: [ - { name: 'a', args: {}, pid: 1, ts: 0, cat: 'test', tid: 2, ph: 'P', sf: 7 } // @suppress longLineCheck - ], - stackFrames: { - '1': { - category: 'm1', - name: 'main' - }, - '7': { - category: 'm2', - name: 'frame7', - parent: '1' - } - } - }; - - var m = makeModel(eventData); - - var p = m.processes[1]; - var t = p.threads[2]; - - assert.equal(t.samples.length, 1); - assert.equal(t.samples_[0].start, 0.0); - assert.equal(t.samples_[0].leafStackFrame.title, 'frame7'); - assert.isFalse(m.hasImportWarnings); - }); - - test('importSamplesMissingArgs', function() { - var events = [ - {name: 'a', pid: 52, ts: 548, cat: 'test', tid: 53, ph: 'P'}, - {name: 'b', pid: 52, ts: 548, cat: 'test', tid: 53, ph: 'P'}, - {name: 'c', pid: 52, ts: 549, cat: 'test', tid: 53, ph: 'P'} - ]; - var m = makeModel(events); - var p = m.processes[52]; - assert.isDefined(p); - var t = p.threads[53]; - assert.isDefined(t); - assert.isDefined(t); - assert.equal(t.samples_.length, 3); - assert.isFalse(m.hasImportWarnings); - }); - - test('importV8Samples', function() { - var eventData = { - traceEvents: [ - { name: 'V8Sample', args: {data: {stack: ['0x2a574306061', '0x2a574306224'], vm_state: 'js'}}, pid: 1, ts: 4, cat: 'test', tid: 2, ph: 'P' }, // @suppress longLineCheck - { name: 'V8Sample', args: {data: {stack: [], vm_state: 'gc'}}, pid: 1, ts: 6, cat: 'test', tid: 2, ph: 'P' }, // @suppress longLineCheck - { name: 'JitCodeAdded', args: {data: {code_len: 2, name: 'LazyCompile:~foo http://example.com/bar.js:23', code_start: '0x2a574306060'}}, pid: 1, ts: 1, cat: 'test', tid: 2, ph: 'M' }, // @suppress longLineCheck - { name: 'JitCodeAdded', args: {data: {code_len: 20, name: 'bar', code_start: '0x2a574306220'}}, pid: 1, ts: 2, cat: 'test', tid: 2, ph: 'M' }, // @suppress longLineCheck - { name: 'JitCodeMoved', args: {data: {code_len: 2, old_code_start: '0x2a574306220', code_start: '0x2a574306222'}}, pid: 1, ts: 3, cat: 'test', tid: 2, ph: 'M' }, // @suppress longLineCheck - { name: 'JitCodeAdded', args: {data: {code_len: 20, name: 'baz', code_start: '0xffffffff9f90a1a0'}}, pid: 1, ts: 4, cat: 'test', tid: 2, ph: 'M' } // @suppress longLineCheck - ] - }; - - var m = makeModel(eventData); - var p = m.processes[1]; - var t = p.threads[2]; - - assert.isFalse(m.hasImportWarnings); - assert.equal(t.samples.length, 2); - - var sample = t.samples_[0]; - assert.equal(sample.leafStackFrame.title, - 'foo http://example.com/bar.js:22'); - assert.equal(sample.leafStackFrame.parentFrame.title, 'bar'); - - var sample = t.samples_[1]; - assert.equal(sample.leafStackFrame.title, 'gc'); - }); - - test('importOldFormatV8Samples', function() { - var eventData = { - traceEvents: [ - { name: 'JitCodeAdded', args: {data: {code_len: 2, name: 'LazyCompile:~foo http://example.com/bar.js:23', code_start: '0x2a574306060'}}, pid: 1, ts: 0, cat: 'test', tid: 2, ph: 'I' }, // @suppress longLineCheck - { name: 'JitCodeAdded', args: {data: {code_len: 20, name: 'bar', code_start: '0x2a574306220'}}, pid: 1, ts: 0, cat: 'test', tid: 2, ph: 'I' }, // @suppress longLineCheck - { name: 'JitCodeMoved', args: {data: {code_len: 2, old_code_start: '0x2a574306220', code_start: '0x2a574306222'}}, pid: 1, ts: 0, cat: 'test', tid: 2, ph: 'I' }, // @suppress longLineCheck - { name: 'JitCodeAdded', args: {data: {code_len: 20, name: 'baz', code_start: '0xffffffff9f90a1a0'}}, pid: 1, ts: 0, cat: 'test', tid: 2, ph: 'I' }, // @suppress longLineCheck - { name: 'V8Sample', args: {data: {stack: ['0x2a574306061', '0x2a574306224']}}, pid: 1, ts: 0, cat: 'test', tid: 2, ph: 'P' }, // @suppress longLineCheck - { name: 'V8Sample', args: {data: {stack: [], vm_state: 'gc'}}, pid: 1, ts: 10, cat: 'test', tid: 2, ph: 'P' } // @suppress longLineCheck - ] - }; - - var m = makeModel(eventData); - var p = m.processes[1]; - var t = p.threads[2]; - - assert.isFalse(m.hasImportWarnings); - assert.equal(t.samples.length, 2); - - var sample = t.samples_[0]; - assert.equal(sample.leafStackFrame.title, - 'foo http://example.com/bar.js:22'); - assert.equal(sample.leafStackFrame.parentFrame.title, 'bar'); - - var sample = t.samples_[1]; - assert.equal(sample.leafStackFrame.title, 'gc'); - }); - - test('importSimpleObject', function() { - var events = [ - {ts: 10000, pid: 1, tid: 1, ph: 'N', cat: 'c', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - {ts: 15000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', args: {snapshot: 15}}, // @suppress longLineCheck - {ts: 20000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', args: {snapshot: 20}}, // @suppress longLineCheck - {ts: 50000, pid: 1, tid: 1, ph: 'D', cat: 'c', id: '0x1000', name: 'a', args: {}} // @suppress longLineCheck - ]; - var m = makeModel(events, false); - assert.equal(m.bounds.min, 10); - assert.equal(m.bounds.max, 50); - assert.isFalse(m.hasImportWarnings); - - var p = m.processes[1]; - assert.isDefined(p); - - var i10 = p.objects.getObjectInstanceAt(new ScopedId('ptr', '0x1000'), 10); - assert.equal(i10.category, 'c'); - assert.equal(i10.creationTs, 10); - assert.equal(i10.deletionTs, 50); - assert.equal(i10.snapshots.length, 2); - - var s15 = i10.snapshots[0]; - assert.equal(s15.ts, 15); - assert.equal(s15.args, 15); - - var s20 = i10.snapshots[1]; - assert.equal(s20.ts, 20); - assert.equal(s20.args, 20); - }); - - test('importImplicitObjects', function() { - var events = [ - {ts: 10000, pid: 1, tid: 1, ph: 'N', cat: 'c', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - {ts: 15000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', - args: { snapshot: [ - { id: 'subObject/0x1', - foo: 1 - } - ]}}, - {ts: 20000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', - args: { snapshot: [ - { id: 'subObject/0x1', - foo: 2 - }, - { id: 'subObject/0x2', - foo: 1 - } - ]}} - ]; - - var m = makeModel(events, false); - var p1 = m.processes[1]; - - var iA = p1.objects.getObjectInstanceAt(new ScopedId('ptr', '0x1000'), 10); - var subObjectInstances = p1.objects.getAllInstancesByTypeName()[ - 'subObject']; - - assert.equal(subObjectInstances.length, 2); - var subObject1 = p1.objects.getObjectInstanceAt( - new ScopedId('ptr', '0x1'), 15); - assert.equal(subObject1.name, 'subObject'); - assert.equal(subObject1.creationTs, 15); - - assert.equal(subObject1.snapshots.length, 2); - assert.equal(subObject1.snapshots[0].ts, 15); - assert.equal(subObject1.snapshots[0].args.foo, 1); - assert.equal(subObject1.snapshots[1].ts, 20); - assert.equal(subObject1.snapshots[1].args.foo, 2); - - var subObject2 = p1.objects.getObjectInstanceAt( - new ScopedId('ptr', '0x2'), 20); - assert.equal(subObject2.name, 'subObject'); - assert.equal(subObject2.creationTs, 20); - assert.equal(subObject2.snapshots.length, 1); - assert.equal(subObject2.snapshots[0].ts, 20); - }); - - test('importImplicitObjectWithCategoryOverride', function() { - var events = [ - {ts: 10000, pid: 1, tid: 1, ph: 'N', cat: 'cat', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - {ts: 15000, pid: 1, tid: 1, ph: 'O', cat: 'otherCat', id: '0x1000', name: 'a', // @suppress longLineCheck - args: { snapshot: [ - { id: 'subObject/0x1', - cat: 'cat', - foo: 1 - } - ]}} - ]; - - var m = makeModel(events); - var p1 = m.processes[1]; - - var iA = p1.objects.getObjectInstanceAt(new ScopedId('ptr', '0x1000'), 10); - var subObjectInstances = p1.objects.getAllInstancesByTypeName()[ - 'subObject']; - - assert.equal(subObjectInstances.length, 1); - }); - - test('importImplicitObjectWithBaseTypeOverride', function() { - var events = [ - {ts: 10000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'PictureLayerImpl', args: { // @suppress longLineCheck - snapshot: { - base_type: 'LayerImpl' - } - }}, - {ts: 50000, pid: 1, tid: 1, ph: 'D', cat: 'c', id: '0x1000', name: 'LayerImpl', args: {}} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p1 = m.processes[1]; - assert.equal(m.importWarnings.length, 0); - - var iA = p1.objects.getObjectInstanceAt(new ScopedId('ptr', '0x1000'), 10); - assert.equal(iA.snapshots.length, 1); - }); - - test('importIDRefs', function() { - var events = [ - // An object with two snapshots. - {ts: 10000, pid: 1, tid: 1, ph: 'N', cat: 'c', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - {ts: 15000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', args: {snapshot: 15}}, // @suppress longLineCheck - {ts: 20000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', args: {snapshot: 20}}, // @suppress longLineCheck - {ts: 50000, pid: 1, tid: 1, ph: 'D', cat: 'c', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - - // A slice that references the object. - {ts: 17000, pid: 1, tid: 1, ph: 'B', cat: 'c', name: 'taskSlice', args: {my_object: {id_ref: '0x1000'}}}, // @suppress longLineCheck - {ts: 17500, pid: 1, tid: 1, ph: 'E', cat: 'c', name: 'taskSlice', args: {}} // @suppress longLineCheck - ]; - - var m = makeModel(events, false); - var p1 = m.processes[1]; - - var iA = p1.objects.getObjectInstanceAt(new ScopedId('ptr', '0x1000'), 10); - var s15 = iA.getSnapshotAt(15); - - var taskSlice = p1.threads[1].sliceGroup.slices[0]; - assert.equal(taskSlice.args.my_object, s15); - }); - - test('importIDRefsThatPointAtEachOther', function() { - var events = [ - // An object. - {ts: 10000, pid: 1, tid: 1, ph: 'N', cat: 'c', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - {ts: 15000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', args: { // @suppress longLineCheck - snapshot: { x: { - id: 'foo/0x1001', - value: 'bar' - }}}}, - {ts: 50000, pid: 1, tid: 1, ph: 'D', cat: 'c', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - - // A slice that references the object. - {ts: 17000, pid: 1, tid: 1, ph: 'B', cat: 'c', name: 'taskSlice', args: {my_object: {id_ref: '0x1001'}}}, // @suppress longLineCheck - {ts: 17500, pid: 1, tid: 1, ph: 'E', cat: 'c', name: 'taskSlice', args: {}} // @suppress longLineCheck - ]; - - var m = makeModel(events); - var p1 = m.processes[1]; - - var iA = p1.objects.getObjectInstanceAt(new ScopedId('ptr', '0x1000'), 15); - var iFoo = p1.objects.getObjectInstanceAt( - new ScopedId('ptr', '0x1001'), 15); - assert.isDefined(iA); - assert.isDefined(iFoo); - - var a15 = iA.getSnapshotAt(15); - var foo15 = iFoo.getSnapshotAt(15); - - var taskSlice = p1.threads[1].sliceGroup.slices[0]; - assert.equal(taskSlice.args.my_object, foo15); - }); - - test('importArrayWithIDs', function() { - var events = [ - {ts: 15000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', args: { // @suppress longLineCheck - snapshot: { x: [ - {id: 'foo/0x1001', value: 'bar1'}, - {id: 'foo/0x1002', value: 'bar2'}, - {id: 'foo/0x1003', value: 'bar3'} - ]}}} - ]; - - var m = makeModel(events, false); - var p1 = m.processes[1]; - - var sA = p1.objects.getSnapshotAt(new ScopedId('ptr', '0x1000'), 15); - assert.isTrue(sA.args.x instanceof Array); - assert.equal(sA.args.x.length, 3); - assert.isTrue(sA.args.x[0] instanceof tr.model.ObjectSnapshot); - assert.isTrue(sA.args.x[1] instanceof tr.model.ObjectSnapshot); - assert.isTrue(sA.args.x[2] instanceof tr.model.ObjectSnapshot); - }); - - test('importDoesNotMutateEventList', function() { - var events = [ - // An object. - {ts: 10000, pid: 1, tid: 1, ph: 'N', cat: 'c', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - {ts: 15000, pid: 1, tid: 1, ph: 'O', cat: 'c', id: '0x1000', name: 'a', args: { // @suppress longLineCheck - snapshot: {foo: 15}}}, - {ts: 50000, pid: 1, tid: 1, ph: 'D', cat: 'c', id: '0x1000', name: 'a', args: {}}, // @suppress longLineCheck - - // A slice that references the object. - {ts: 17000, pid: 1, tid: 1, ph: 'B', cat: 'c', name: 'taskSlice', args: { - my_object: {id_ref: '0x1000'}} - }, - {ts: 17500, pid: 1, tid: 1, ph: 'E', cat: 'c', name: 'taskSlice', args: {}} // @suppress longLineCheck - ]; - - // The A type family exists to mutate the args list provided to - // snapshots. - function ASnapshot() { - tr.model.ObjectSnapshot.apply(this, arguments); - this.args.foo = 7; - } - ASnapshot.prototype = { - __proto__: tr.model.ObjectSnapshot.prototype - }; - - // Import event while the A types are registered, causing the - // arguments of the snapshots to be mutated. - var m; - try { - tr.model.ObjectSnapshot.register(ASnapshot, {typeName: 'a'}); - m = makeModel(events); - } finally { - tr.model.ObjectSnapshot.unregister(ASnapshot); - } - assert.isFalse(m.hasImportWarnings); - - // Verify that the events array wasn't modified. - assert.deepEqual( - events[1].args, - {snapshot: {foo: 15}}); - assert.deepEqual( - events[3].args, - {my_object: {id_ref: '0x1000'}}); - }); - - test('importFlowEvent', function() { - var events = [ - { name: 'aSlice', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 547, ph: 'B', args: {} }, // @suppress longLineCheck - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', args: {} }, // @suppress longLineCheck - { id: 72, pid: 52, tid: 53, ts: 549, ph: 'E', args: {} }, // @suppress longLineCheck - - { name: 'bSlice', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 559, ph: 'B', args: {} }, // @suppress longLineCheck - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 560, ph: 't', args: {} }, // @suppress longLineCheck - { id: 72, pid: 52, tid: 53, ts: 561, ph: 'E', args: {} }, // @suppress longLineCheck - - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 580, ph: 'f', args: {} }, // @suppress longLineCheck - { name: 'cSlice', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 581, ph: 'B', args: {} }, // @suppress longLineCheck - { id: 72, pid: 52, tid: 53, ts: 582, ph: 'E', args: {} } // @suppress longLineCheck - ]; - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - - assert.isDefined(t); - assert.equal(m.flowEvents.length, 2); - assert.equal(m.flowIntervalTree.size, 2); - - var f0 = m.flowEvents[0]; - assert.equal(f0.title, 'a'); - assert.equal(f0.category, 'foo'); - assert.equal(f0.id, 72); - assert.closeTo(f0.start, 0.001, 1e-5); - assert.closeTo(12 / 1000, f0.duration, 1e-5); - assert.equal(f0.startSlice.title, 'aSlice'); - assert.equal(f0.endSlice.title, 'bSlice'); - - // TODO(nduca): Replace this assertion with something better when - // flow events don't create synthetic slices on their own. - assert.isDefined(f0.startSlice); - assert.isDefined(f0.endSlice); - - var f1 = m.flowEvents[1]; - assert.equal(f1.title, f0.title); - assert.equal(f1.category, f0.category); - assert.equal(f1.id, f0.id); - assert.closeTo(20 / 1000, f1.duration, 1e-5); - - assert.equal(f1.startSlice.title, 'bSlice'); - assert.equal(f1.endSlice.title, 'cSlice'); - - assert.deepEqual(f0.startSlice.outFlowEvents, [f0]); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - assert.deepEqual(f1.startSlice.outFlowEvents, [f1]); - assert.deepEqual(f1.endSlice.inFlowEvents, [f1]); - }); - - test('importOldFlowEventBindtoNext', function() { - // Old trace format without event.bp, and event.cat doesn't contain input - var events = [ - { name: 'slice1', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100}, // @suppress longLineCheck - { name: 'flow', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', args: {}}, // @suppress longLineCheck - - { name: 'flow', cat: 'foo', id: 72, pid: 70, tid: 71, ts: 580, ph: 'f', args: {}}, // @suppress longLineCheck - { name: 'slice2', cat: 'foo', pid: 70, tid: 71, ts: 570, ph: 'X', args: {}, 'dur': 100}, // @suppress longLineCheck - { name: 'slice3', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', args: {}, 'dur': 1000} // @suppress longLineCheck - - ]; - - var m = makeModel(events, false, false); - assert.equal(m.flowEvents.length, 1); - - var f0 = m.flowEvents[0]; - - assert.equal(f0.title, 'flow'); - assert.equal(f0.category, 'foo'); - assert.equal(f0.id, 72); - assert.equal(f0.start, .548); - assert.closeTo(32 / 1000, f0.duration, 1e-5); - assert.equal(f0.startSlice.title, 'slice1'); - assert.deepEqual(f0.startSlice.outFlowEvents, [f0]); - assert.equal(f0.endSlice.title, 'slice3'); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - }); - - test('importOldInputFlowEventBindtoParent', function() { - // Old trace format without event.bp, but event.cat contains input - var events = [ - { name: 'slice1', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100}, // @suppress longLineCheck - { name: 'flow', cat: 'input', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', args: {}}, // @suppress longLineCheck - - { name: 'flow', cat: 'input', id: 72, pid: 70, tid: 71, ts: 580, ph: 'f', args: {}}, // @suppress longLineCheck - { name: 'slice2', cat: 'foo', pid: 70, tid: 71, ts: 570, ph: 'X', args: {}, 'dur': 100}, // @suppress longLineCheck - { name: 'slice3', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', args: {}, 'dur': 1000} // @suppress longLineCheck - - ]; - - var m = makeModel(events, false, false); - assert.equal(m.flowEvents.length, 1); - - var f0 = m.flowEvents[0]; - - assert.equal(f0.title, 'flow'); - assert.equal(f0.category, 'input'); - assert.equal(f0.id, 72); - assert.equal(f0.start, .548); - assert.closeTo(32 / 1000, f0.duration, 1e-5); - assert.equal(f0.startSlice.title, 'slice1'); - assert.deepEqual(f0.startSlice.outFlowEvents, [f0]); - assert.equal(f0.endSlice.title, 'slice2'); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - }); - - test('importOldIPCFlowEventBindtoParent', function() { - // Old trace format without event.bp, but event.cat contains ipc.flow - var events = [ - { name: 'slice1', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100}, // @suppress longLineCheck - { name: 'flow', cat: 'disabled-by-default-ipc.flow', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', args: {}}, // @suppress longLineCheck - - { name: 'flow', cat: 'disabled-by-default-ipc.flow', id: 72, pid: 70, tid: 71, ts: 580, ph: 'f', args: {}}, // @suppress longLineCheck - { name: 'slice2', cat: 'foo', pid: 70, tid: 71, ts: 570, ph: 'X', args: {}, 'dur': 100}, // @suppress longLineCheck - { name: 'slice3', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', args: {}, 'dur': 1000} // @suppress longLineCheck - - ]; - - var m = makeModel(events, false, false); - assert.equal(m.flowEvents.length, 1); - - var f0 = m.flowEvents[0]; - - assert.equal(f0.title, 'flow'); - assert.equal(f0.category, 'disabled-by-default-ipc.flow'); - assert.equal(f0.id, 72); - assert.equal(f0.start, .548); - assert.closeTo(32 / 1000, f0.duration, 1e-5); - assert.equal(f0.startSlice.title, 'slice1'); - assert.deepEqual(f0.startSlice.outFlowEvents, [f0]); - assert.equal(f0.endSlice.title, 'slice2'); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - }); - - test('importNewFlowEventBindtoParent', function() { - // New trace format with event.bp - var events = [ - { name: 'slice1', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100}, // @suppress longLineCheck - { name: 'flow', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', bp: 'e', args: {}}, // @suppress longLineCheck - - { name: 'flow', cat: 'foo', id: 72, pid: 70, tid: 71, ts: 580, ph: 'f', bp: 'e', args: {}}, // @suppress longLineCheck - { name: 'slice2', cat: 'foo', pid: 70, tid: 71, ts: 570, ph: 'X', args: {}, 'dur': 100}, // @suppress longLineCheck - { name: 'slice3', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', args: {}, 'dur': 1000} // @suppress longLineCheck - - ]; - - var m = makeModel(events, false, false); - assert.equal(m.flowEvents.length, 1); - - var f0 = m.flowEvents[0]; - - assert.equal(f0.title, 'flow'); - assert.equal(f0.category, 'foo'); - assert.equal(f0.id, 72); - assert.equal(f0.start, .548); - assert.closeTo(32 / 1000, f0.duration, 1e-5); - assert.equal(f0.startSlice.title, 'slice1'); - assert.deepEqual(f0.startSlice.outFlowEvents, [f0]); - assert.equal(f0.endSlice.title, 'slice2'); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - }); - - test('importNewFlowEventWithInvalidBindingPoint', function() { - // New trace format with event.bp, which however !== 'e' - var events = [ - { name: 'slice1', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100}, // @suppress longLineCheck - { name: 'flow', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', bp: 'z', args: {}}, // @suppress longLineCheck - - { name: 'flow', cat: 'foo', id: 72, pid: 70, tid: 71, ts: 580, ph: 'f', bp: 'z', args: {}}, // @suppress longLineCheck - { name: 'slice2', cat: 'foo', pid: 70, tid: 71, ts: 570, ph: 'X', args: {}, 'dur': 100}, // @suppress longLineCheck - { name: 'slice3', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', args: {}, 'dur': 1000} // @suppress longLineCheck - - ]; - - var m = makeModel(events); - - assert.equal(m.flowEvents.length, 0); - }); - - test('importFlowV2OnePair', function() { - // Flow V2: one flow producer one flow consumer - var events = [ - { name: 'producer', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100, bind_id: '0xaaa', flow_out: true}, // @suppress longLineCheck - { name: 'consumer', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', 'dur': 1000, bind_id: '0xaaa', flow_in: true} // @suppress longLineCheck - ]; - - var m = makeModel(events); - - assert.equal(m.flowEvents.length, 1); - - var f0 = m.flowEvents[0]; - - assert.equal(f0.startSlice.title, 'producer'); - assert.deepEqual(f0.startSlice.outFlowEvents, [f0]); - assert.equal(f0.endSlice.title, 'consumer'); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - }); - - test('importFlowV2OneFlowStep', function() { - // Flow V2: one flow producer one flow consumer - var events = [ - { name: 'producer', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100, bind_id: '0xaaa', flow_out: true}, // @suppress longLineCheck - { name: 'step', cat: 'foo', pid: 62, tid: 63, ts: 647, ph: 'X', 'dur': 100, bind_id: '0xaaa', flow_out: true, flow_in: true}, // @suppress longLineCheck - { name: 'consumer', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', 'dur': 1000, bind_id: '0xaaa', args: { 'queue_duration': 0}, flow_in: true} // @suppress longLineCheck - ]; - - var m = makeModel(events); - - assert.equal(m.flowEvents.length, 2); - - var f0 = m.flowEvents[0]; - var f1 = m.flowEvents[1]; - - assert.equal(f0.startSlice.title, 'producer'); - assert.deepEqual(f0.startSlice.outFlowEvents, [f0]); - assert.equal(f0.endSlice.title, 'step'); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - - assert.equal(f1.startSlice.title, 'step'); - assert.deepEqual(f1.startSlice.outFlowEvents, [f1]); - assert.equal(f1.endSlice.title, 'consumer'); - assert.deepEqual(f1.endSlice.inFlowEvents, [f1]); - }); - - test('importFlowV2MultipleConsumers', function() { - // Flow V2: one flow producer multiple flow consumers - var events = [ - { name: 'producer', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100, bind_id: '0xaaa', flow_out: true}, // @suppress longLineCheck - { name: 'consumer1', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', 'dur': 1000, bind_id: '0xaaa', flow_in: true}, // @suppress longLineCheck - { name: 'consumer2', cat: 'foo', pid: 70, tid: 72, ts: 870, ph: 'X', 'dur': 1000, bind_id: '0xaaa', flow_in: true} // @suppress longLineCheck - ]; - - var m = makeModel(events); - - assert.equal(m.flowEvents.length, 2); - - var f0 = m.flowEvents[0]; - var f1 = m.flowEvents[1]; - - assert.equal(f0.startSlice.title, 'producer'); - assert.equal(f1.startSlice.title, 'producer'); - - assert.equal(f0.startSlice.outFlowEvents.length, 2); - assert.deepEqual(f0.startSlice.outFlowEvents, [f0, f1]); - assert.deepEqual(f1.startSlice.outFlowEvents, [f0, f1]); - - assert.equal(f0.endSlice.title, 'consumer1'); - assert.equal(f1.endSlice.title, 'consumer2'); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - assert.deepEqual(f1.endSlice.inFlowEvents, [f1]); - }); - - test('importFlowV2MultipleProducers', function() { - // Flow V2: multiple flow producers, which is not allowed - var events = [ - { name: 'producer1', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100, bind_id: '0xaaa', flow_out: true}, // @suppress longLineCheck - { name: 'producer2', cat: 'foo', pid: 52, tid: 54, ts: 567, ph: 'X', 'dur': 100, bind_id: '0xaaa', flow_out: true}, // @suppress longLineCheck - { name: 'consumer', cat: 'foo', pid: 70, tid: 71, ts: 770, ph: 'X', 'dur': 1000, bind_id: '0xaaa', flow_in: true} // @suppress longLineCheck - ]; - - var m = makeModel(events); - - assert.equal(m.flowEvents.length, 1); - }); - - // This test creates a flow event that stops on the same timestamp that - // the 'X' event which it triggers begins. - test('importFlowEventOverlaps', function() { - var events = [ - { name: 'SomeTask', cat: 'foo', pid: 52, tid: 53, ts: 547, ph: 'X', 'dur': 100}, // @suppress longLineCheck - { name: 'PostTask', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', args: {}}, // @suppress longLineCheck - - { name: 'PostTask', cat: 'foo', id: 72, pid: 70, tid: 71, ts: 580, ph: 'f', args: { 'queue_duration': 0}}, // @suppress longLineCheck - // Note that RunTask has the same time-stamp as PostTask 'f' - { name: 'RunTask', cat: 'foo', pid: 70, tid: 71, ts: 580, ph: 'X', args: {'src_func': 'PostRunTask'}, 'dur': 1000} // @suppress longLineCheck - ]; - - var m = makeModel(events, false); - var startT = m.processes[52].threads[53]; - var endT = m.processes[70].threads[71]; - - assert.isDefined(startT); - assert.equal(startT.sliceGroup.slices.length, 1); - - assert.isDefined(endT); - assert.equal(endT.sliceGroup.slices.length, 1); - - assert.equal(m.flowEvents.length, 1); - - // f0 represents 's' to 'f' - var f0 = m.flowEvents[0]; - - assert.equal(f0.title, 'PostTask'); - assert.equal(f0.category, 'foo'); - assert.equal(f0.id, 72); - assert.equal(f0.start, .548); - assert.closeTo(32 / 1000, f0.duration, 1e-5); - assert.equal(f0.startSlice.title, 'SomeTask'); - assert.deepEqual(f0.startSlice.outFlowEvents, [f0]); - assert.equal(f0.endSlice.title, 'RunTask'); - assert.deepEqual(f0.endSlice.inFlowEvents, [f0]); - - // TODO(nduca): Add assertions about the flow slices, esp that they were - // found correctly. - }); - - test('importOutOfOrderFlowEvent', function() { - var events = [ - { name: 'SomeTask', cat: 'foo', pid: 52, tid: 53, ts: 548, ph: 'X', 'dur': 10}, // @suppress longLineCheck - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', args: {} }, // @suppress longLineCheck - - { name: 'SomeTask', cat: 'foo', pid: 52, tid: 53, ts: 148, ph: 'X', 'dur': 10}, // @suppress longLineCheck - { name: 'b', cat: 'foo', id: 73, pid: 52, tid: 53, ts: 148, ph: 's', args: {} }, // @suppress longLineCheck - - { name: 'b', cat: 'foo', id: 73, pid: 52, tid: 53, ts: 570, ph: 'f', args: {} }, // @suppress longLineCheck - { name: 'SomeTask', cat: 'foo', pid: 52, tid: 53, ts: 571, ph: 'X', 'dur': 10}, // @suppress longLineCheck - - { name: 'SomeTask', cat: 'foo', pid: 52, tid: 53, ts: 560, ph: 'X', 'dur': 10}, // @suppress longLineCheck - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 560, ph: 't', args: {} }, // @suppress longLineCheck - - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 580, ph: 'f', args: {} }, // @suppress longLineCheck - { name: 'SomeTask', cat: 'foo', pid: 52, tid: 53, ts: 581, ph: 'X', 'dur': 10} // @suppress longLineCheck - ]; - - var expected = [0.4, 0.0, 0.412]; - var m = makeModel(events); - assert.equal(m.flowIntervalTree.size, 3); - - var order = m.flowEvents.map(function(x) { return x.start }); - for (var i = 0; i < expected.length; ++i) - assert.closeTo(expected[i], order[i], 1e-5); - }); - - test('importCompleteEvent', function() { - var events = [ - { name: 'a', args: {}, pid: 52, ts: 629, dur: 1, cat: 'baz', tid: 53, ph: 'X' }, // @suppress longLineCheck - { name: 'b', args: {}, pid: 52, ts: 730, dur: 20, cat: 'foo', tid: 53, ph: 'X' }, // @suppress longLineCheck - { name: 'c', args: {}, pid: 52, ts: 740, cat: 'baz', tid: 53, ph: 'X' } - ]; - - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - var p = m.processes[52]; - assert.isDefined(p); - - assert.equal(p.numThreads, 1); - var t = p.threads[53]; - assert.isDefined(t); - assert.equal(t.sliceGroup.slices.length, 3); - assert.equal(t.tid, 53); - - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'baz'); - assert.closeTo(0, slice.start, 1e-5); - assert.closeTo(1 / 1000, slice.duration, 1e-5); - assert.equal(slice.subSlices.length, 0); - - slice = t.sliceGroup.slices[1]; - assert.equal(slice.title, 'b'); - assert.equal(slice.category, 'foo'); - assert.closeTo((730 - 629) / 1000, slice.start, 1e-5); - assert.closeTo(20 / 1000, slice.duration, 1e-5); - assert.equal(slice.subSlices.length, 1); - - slice = t.sliceGroup.slices[2]; - assert.equal(slice.title, 'c'); - assert.isTrue(slice.didNotFinish); - assert.closeTo(10 / 1000, slice.duration, 1e-5); - }); - - test('importFlowEventsWithStackFrame', function() { - var eventData = { - traceEvents: [ - { name: 'aSlice', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 547, ph: 'B', args: {} }, // @suppress longLineCheck - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 548, ph: 's', args: {}, sf: 1 }, // @suppress longLineCheck - { id: 72, pid: 52, tid: 53, ts: 549, ph: 'E', args: {} }, // @suppress longLineCheck - - { name: 'bSlice', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 559, ph: 'B', args: {} }, // @suppress longLineCheck - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 560, ph: 't', args: {}, sf: 2 }, // @suppress longLineCheck - { id: 72, pid: 52, tid: 53, ts: 561, ph: 'E', args: {} }, // @suppress longLineCheck - - { name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 580, ph: 'f', args: {}, sf: 3 }, // @suppress longLineCheck - { name: 'cSlice', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 581, ph: 'B', args: {} }, // @suppress longLineCheck - { id: 72, pid: 52, tid: 53, ts: 582, ph: 'E', args: {} } // @suppress longLineCheck - ], - stackFrames: { - '1': { - category: 'm1', - name: 'fn1' - }, - '2': { - category: 'm2', - name: 'fn2' - }, - '3': { - category: 'm3', - name: 'fn3' - } - } - }; - - var m = makeModel(eventData); - - assert.equal(m.flowEvents.length, 2); - - var f0 = m.flowEvents[0]; - assert.equal(f0.startStackFrame.title, 'fn1'); - assert.equal(f0.endStackFrame.title, 'fn2'); - - var f1 = m.flowEvents[1]; - assert.equal(f1.startStackFrame.title, 'fn2'); - assert.equal(f1.endStackFrame.title, 'fn3'); - }); - - test('importCompleteEventWithCpuDuration', function() { - var events = [ - { name: 'a', args: {}, pid: 52, ts: 629, dur: 1, cat: 'baz', tid: 53, ph: 'X', tts: 12, tdur: 1 }, // @suppress longLineCheck - { name: 'b', args: {}, pid: 52, ts: 730, dur: 20, cat: 'foo', tid: 53, ph: 'X', tts: 110, tdur: 16 }, // @suppress longLineCheck - { name: 'c', args: {}, pid: 52, ts: 740, cat: 'baz', tid: 53, ph: 'X', tts: 115 } // @suppress longLineCheck - ]; - - var m = makeModel(events); - assert.equal(m.numProcesses, 1); - var p = m.processes[52]; - assert.isDefined(p); - - assert.equal(p.numThreads, 1); - var t = p.threads[53]; - assert.isDefined(t); - assert.equal(t.sliceGroup.slices.length, 3); - assert.equal(t.tid, 53); - - var slice = t.sliceGroup.slices[0]; - assert.equal(slice.title, 'a'); - assert.equal(slice.category, 'baz'); - assert.closeTo(0, slice.start, 1e-5); - assert.closeTo(1 / 1000, slice.duration, 1e-5); - assert.closeTo(12 / 1000, slice.cpuStart, 1e-5); - assert.closeTo(1 / 1000, slice.cpuDuration, 1e-5); - assert.equal(slice.subSlices.length, 0); - - slice = t.sliceGroup.slices[1]; - assert.equal(slice.title, 'b'); - assert.equal(slice.category, 'foo'); - assert.closeTo((730 - 629) / 1000, slice.start, 1e-5); - assert.closeTo(20 / 1000, slice.duration, 1e-5); - assert.closeTo(110 / 1000, slice.cpuStart, 1e-5); - assert.closeTo(16 / 1000, slice.cpuDuration, 1e-5); - assert.equal(slice.subSlices.length, 1); - - slice = t.sliceGroup.slices[2]; - assert.equal(slice.title, 'c'); - assert.isTrue(slice.didNotFinish); - assert.closeTo(10 / 1000, slice.duration, 1e-5); - }); - - test('importNestedCompleteEventWithTightBounds', function() { - var events = [ - { name: 'a', args: {}, pid: 52, ts: 244654227065, dur: 36075, cat: 'baz', tid: 53, ph: 'X' }, // @suppress longLineCheck - { name: 'b', args: {}, pid: 52, ts: 244654227095, dur: 36045, cat: 'foo', tid: 53, ph: 'X' } // @suppress longLineCheck - ]; - - var m = makeModel(events, false); - var t = m.processes[52].threads[53]; - - var sA = findSliceNamed(t.sliceGroup, 'a'); - var sB = findSliceNamed(t.sliceGroup, 'b'); - - assert.equal(sA.title, 'a'); - assert.equal(sA.category, 'baz'); - assert.equal(sA.start, 244654227.065); - assert.equal(sA.duration, 36.075); - assert.closeTo(0.03, sA.selfTime, 1e-5); - - assert.equal(sB.title, 'b'); - assert.equal(sB.category, 'foo'); - assert.equal(sB.start, 244654227.095); - assert.equal(sB.duration, 36.045); - - assert.equal(sA.subSlices.length, 1); - assert.equal(sA.subSlices[0], sB); - assert.equal(sB.parentSlice, sA); - }); - - - test('importCompleteEventWithStackFrame', function() { - var eventData = { - traceEvents: [ - { name: 'a', args: {}, pid: 1, ts: 0, dur: 1, cat: 'baz', tid: 2, ph: 'X', sf: 7 }, // @suppress longLineCheck - { name: 'b', args: {}, pid: 1, ts: 5, dur: 1, cat: 'baz', tid: 2, ph: 'X', sf: 8, esf: 9 } // @suppress longLineCheck - ], - stackFrames: { - '1': { - category: 'm1', - name: 'main' - }, - '7': { - category: 'm2', - name: 'frame7', - parent: '1' - }, - '8': { - category: 'm2', - name: 'frame8', - parent: '1' - }, - '9': { - category: 'm2', - name: 'frame9', - parent: '1' - } - } - }; - - var m = makeModel(eventData); - - var p = m.processes[1]; - var t = p.threads[2]; - assert.isDefined(t); - assert.equal(t.sliceGroup.slices.length, 2); - - var s0 = t.sliceGroup.slices[0]; - assert.equal(s0.startStackFrame.title, 'frame7'); - assert.isUndefined(s0.endStackFrame); - - var s1 = t.sliceGroup.slices[1]; - assert.equal(s1.startStackFrame.title, 'frame8'); - assert.equal(s1.endStackFrame.title, 'frame9'); - }); - - test('importAsyncEventWithSameTimestamp', function() { - var events = []; - // Events are added with ts 0, 1, 1, 2, 2, 3, 3 ...500, 500, 1000 - // and use 'seq' to track the order of when the event is recorded. - events.push({name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 0, ph: 'S', args: {'seq': 0}}); // @suppress longLineCheck - - for (var i = 1; i <= 1000; i++) - events.push({name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: Math.round(i / 2) , ph: 'T', args: {'seq': i}}); // @suppress longLineCheck - - events.push({name: 'a', cat: 'foo', id: 72, pid: 52, tid: 53, ts: 1000, ph: 'F', args: {'seq': 1001}}); // @suppress longLineCheck - - var m = makeModel(events); - var t = m.processes[52].threads[53]; - - assert.equal(t.asyncSliceGroup.slices.length, 1); - var parentSlice = t.asyncSliceGroup.slices[0]; - assert.equal(parentSlice.title, 'a'); - assert.equal(parentSlice.category, 'foo'); - assert.isTrue(parentSlice.isTopLevel); - - assert.isDefined(parentSlice.subSlices); - var subSlices = parentSlice.subSlices; - assert.equal(subSlices.length, 1000); - // Slices should be sorted according to 'ts'. And if 'ts' is the same, - // slices should keep the order that they were recorded. - for (var i = 0; i < 1000; i++) { - assert.equal(i + 1, subSlices[i].args['seq']); - assert.isFalse(subSlices[i].isTopLevel); - } - }); - - test('sampleDataSimple', function() { - var events = { - 'traceEvents': [], - 'stackFrames': { - '1': { - 'category': 'mod', - 'name': 'main' - }, - '2': { - 'category': 'mod', - 'name': 'a', - 'parent': 1 - }, - '3': { - 'category': 'mod', - 'name': 'a_sub', - 'parent': 2 - }, - '4': { - 'category': 'mod', - 'name': 'b', - 'parent': 1 - } - }, - 'samples': [ - { - 'cpu': 0, 'tid': 1, 'ts': 1000.0, - 'name': 'cycles:HG', 'sf': 3, 'weight': 1 - }, - { - 'cpu': 0, 'tid': 1, 'ts': 2000.0, - 'name': 'cycles:HG', 'sf': 2, 'weight': 1 - }, - { - 'cpu': 1, 'tid': 1, 'ts': 3000.0, - 'name': 'cycles:HG', 'sf': 3, 'weight': 1 - } - ] - }; - var m = makeModel(events, false); - assert.isDefined(m.kernel.cpus[0]); - assert.equal(m.getAllThreads().length, 1); - - assert.equal(tr.b.dictionaryKeys(m.stackFrames).length, 4); - assert.equal(m.samples.length, 3); - - var t1 = m.processes[1].threads[1]; - assert.equal(t1.samples.length, 3); - - var c0 = m.kernel.cpus[0]; - var c1 = m.kernel.cpus[1]; - assert.equal(c0.samples.length, 2); - assert.equal(c1.samples.length, 1); - - assert.equal(m.samples[0].cpu, c0); - assert.equal(m.samples[0].thread, t1); - assert.equal(m.samples[0].title, 'cycles:HG'); - assert.equal(m.samples[0].start, 1); - assert.deepEqual( - ['a_sub', 'a', 'main'], - m.samples[0].stackTrace.map(function(x) { return x.title; })); - assert.equal(m.samples[0].weight, 1); - }); - - test('importMemoryDumps_verifyProcessAndGlobalMemoryDumpLinks', function() { - var events = [ - // 2 process memory dump events. - { - name: 'a', - pid: 42, - ts: 10000, - cat: 'test', - tid: 53, - ph: 'v', - id: '0x0001', - args: { - dumps: { - process_totals: { - resident_set_bytes: '100' - } - } - } - }, - { - name: 'b', - pid: 43, - ts: 11000, - cat: 'test', - tid: 54, - ph: 'v', - id: '0x0001', - args: { - dumps: { - process_totals: { - resident_set_bytes: '200' - } - } - } - }, - // 1 process memory dump event. - { - name: 'd', - pid: 42, - ts: 13000, - cat: 'test', - tid: 56, - ph: 'v', - id: '0xfffffff12345678', - args: { - dumps: { - process_totals: { - resident_set_bytes: '300' - } - } - } - } - ]; - var m = makeModel(events, false); - var p1 = m.getProcess(42); - var p2 = m.getProcess(43); - assert.isDefined(p1); - assert.isDefined(p2); - - // Check that Model and Process objects contain the right dumps. - assert.equal(m.globalMemoryDumps.length, 2); - assert.equal(p1.memoryDumps.length, 2); - assert.equal(p2.memoryDumps.length, 1); - - assert.equal(m.globalMemoryDumps[0].start, 10); - assert.equal(p1.memoryDumps[0].start, 10); - assert.equal(p2.memoryDumps[0].start, 11); - assert.equal(m.globalMemoryDumps[0].duration, 1); - assert.equal(p1.memoryDumps[0].duration, 0); - assert.equal(p2.memoryDumps[0].duration, 0); - - assert.equal(m.globalMemoryDumps[1].start, 13); - assert.equal(p1.memoryDumps[1].start, 13); - assert.equal(m.globalMemoryDumps[1].duration, 0); - assert.equal(p1.memoryDumps[1].duration, 0); - - // Check that GlobalMemoryDump and ProcessMemoryDump objects are - // interconnected correctly. - assert.equal(p1.memoryDumps[0], - m.globalMemoryDumps[0].processMemoryDumps[42]); - assert.equal(p2.memoryDumps[0], - m.globalMemoryDumps[0].processMemoryDumps[43]); - assert.equal(p1.memoryDumps[0].globalMemoryDump, m.globalMemoryDumps[0]); - assert.equal(p2.memoryDumps[0].globalMemoryDump, m.globalMemoryDumps[0]); - - assert.equal(p1.memoryDumps[1], - m.globalMemoryDumps[1].processMemoryDumps[42]); - assert.equal(p1.memoryDumps[1].globalMemoryDump, m.globalMemoryDumps[1]); - }); - - test('importMemoryDumps_totalResidentBytesOnly', function() { - var events = [ - { - pid: 42, - ts: 10, - ph: 'v', - id: '0x01', - args: { - dumps: { - process_totals: { - resident_set_bytes: '1fffffffffffff' - } - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var d = p.memoryDumps[0]; - - assert.equal(d.totals.residentBytes, 9007199254740991); - assert.isUndefined(d.totals.peakResidentBytes); - assert.isUndefined(d.totals.arePeakResidentBytesResettable); - assert.isUndefined(d.totals.platformSpecific); - assert.isUndefined(d.mostRecentVmRegions); - assert.lengthOf(d.memoryAllocatorDumps, 0); - }); - - test('importMemoryDumps_withPeakResidentBytes', function() { - var events = [ - { - pid: 42, - ts: 10, - ph: 'v', - id: '0x01', - args: { - dumps: { - process_totals: { - resident_set_bytes: '1fffffffffffff', - peak_resident_set_bytes: '2fffffffffffff', - is_peak_rss_resetable: true - } - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var d = p.memoryDumps[0]; - - assert.equal(d.totals.residentBytes, 9007199254740991); - assert.equal(d.totals.peakResidentBytes, 13510798882111488); - assert.isTrue(d.totals.arePeakResidentBytesResettable); - assert.isUndefined(d.totals.platformSpecific); - assert.isUndefined(d.mostRecentVmRegions); - assert.lengthOf(d.memoryAllocatorDumps, 0); - }); - - test('importMemoryDumps_platformSpecificTotals', function() { - var events = [ - { - pid: 42, - ts: 10, - ph: 'v', - id: '0x01', - args: { - dumps: { - process_totals: { - resident_set_bytes: '1fffffffffffff', - private_bytes: 'fffffffffffff', - shared_bytes: '10000000000000' - } - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var d = p.memoryDumps[0]; - - assert.equal(d.totals.residentBytes, 9007199254740991); - assert.isUndefined(d.totals.peakResidentBytes); - assert.isUndefined(d.totals.arePeakResidentBytesResettable); - assert.deepEqual(d.totals.platformSpecific, - {private_bytes: 4503599627370495, shared_bytes: 4503599627370496}); - assert.isUndefined(d.mostRecentVmRegions); - assert.lengthOf(d.memoryAllocatorDumps, 0); - }); - - test('importMemoryDumps_vmRegions', function() { - var events = [ - { - name: 'some_dump_name', - pid: 42, - ts: 10, - cat: 'test', - tid: 53, - ph: 'v', - id: '000', - args: { - dumps: { - process_totals: { - resident_set_bytes: '0' - }, - process_mmaps: { - vm_regions: [ - { - sa: 'f0', - sz: '150', - pf: 6, - mf: '[stack:20310]', - bs: { - pss: '9e', - pc: '40', - pd: '20', - sc: '100', - sd: '0', - sw: '50' - } - }, - { - sa: '350', - sz: '250', - pf: 5, - mf: '/dev/ashmem/dalvik', - bs: { - pss: 'cd', - pd: 'cd', - sc: undefined, - sw: '0' - } - }, - { - sa: '7ff10ff4b000', - sz: '40000', - pf: 134, - mf: '/run/shm/.org.chromium.Chromium.sqqN11 (deleted)', - bs: { - pss: '40000', - pc: '0', - pd: '40000', - sc: '0', - sd: '0', - sw: '0' - } - } - ] - } - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var d = p.memoryDumps[0]; - - checkVMRegions(d.vmRegions, [ - { - startAddress: 240, - sizeInBytes: 336, - protectionFlags: VMRegion.PROTECTION_FLAG_READ | - VMRegion.PROTECTION_FLAG_WRITE, - mappedFile: '[stack:20310]', - byteStats: { - privateCleanResident: 64, - privateDirtyResident: 32, - sharedCleanResident: 256, - sharedDirtyResident: 0, - proportionalResident: 158, - swapped: 80 - } - }, - { - startAddress: 848, - sizeInBytes: 592, - protectionFlags: VMRegion.PROTECTION_FLAG_READ | - VMRegion.PROTECTION_FLAG_EXECUTE, - mappedFile: '/dev/ashmem/dalvik', - byteStats: { - proportionalResident: 205, - privateDirtyResident: 205, - swapped: 0 - } - }, - { - startAddress: 140673331539968, - sizeInBytes: 262144, - protectionFlags: VMRegion.PROTECTION_FLAG_READ | - VMRegion.PROTECTION_FLAG_WRITE | VMRegion.PROTECTION_FLAG_MAYSHARE, - mappedFile: '/run/shm/.org.chromium.Chromium.sqqN11 (deleted)', - byteStats: { - privateCleanResident: 0, - privateDirtyResident: 262144, - sharedCleanResident: 0, - sharedDirtyResident: 0, - proportionalResident: 262144, - swapped: 0 - } - } - ]); - - assert.equal(d.totals.residentBytes, 0); - assert.isUndefined(d.totals.peakResidentBytes); - assert.isUndefined(d.totals.arePeakResidentBytesResettable); - assert.isUndefined(d.totals.platformSpecific); - assert.lengthOf(d.memoryAllocatorDumps, 0); - }); - - test('importMemoryDumps_explicitMemoryAllocatorDumps', function() { - var events = [ - { - name: 'a', - pid: 42, - ts: 10, - cat: 'test', - tid: 53, - ph: 'v', - id: '0x0001', - args: { - dumps: { - process_totals: { - resident_set_bytes: '100' - }, - allocators: { - 'oilpan': { - guid: '1a', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '2f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '1000'}, - size: {type: 'scalar', units: 'bytes', value: '8000'} - } - }, - 'oilpan/heap1': { - guid: '2b', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '3f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '3000'}, - size: {type: 'scalar', units: 'bytes', value: '4000'} - } - }, - 'oilpan/heap2': { - guid: '3c', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '4f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '4000'}, - size: {type: 'scalar', units: 'bytes', value: '4000'} - } - }, - 'oilpan/heap2/bucket1': { - // Deliberately missing GUID (to check that the importer does - // not skip memory allocator dump without GUID). - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '1f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '2000'}, - size: {type: 'scalar', units: 'bytes', value: '2000'} - } - }, - 'v8': { - guid: '5e', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '5f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '5000'}, - size: {type: 'scalar', units: 'bytes', value: '6000'} - } - } - } - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var d = p.memoryDumps[0]; - - assert.equal(d.memoryAllocatorDumps.length, 2); - - var oilpanRoot = d.getMemoryAllocatorDumpByFullName('oilpan'); - var v8Root = d.getMemoryAllocatorDumpByFullName('v8'); - assert.isDefined(oilpanRoot); - assert.isDefined(v8Root); - assert.include(d.memoryAllocatorDumps, oilpanRoot); - assert.include(d.memoryAllocatorDumps, v8Root); - - checkDumpNumericsAndDiagnostics(oilpanRoot, { - 'objects_count': new ScalarNumeric(unitlessNumber_smallerIsBetter, 47), - 'size': 32768, - 'effective_size': 32768, - 'inner_size': 4096 - }, {}); - assert.equal(oilpanRoot.children.length, 2); - - var oilpanBucket1 = d.getMemoryAllocatorDumpByFullName( - 'oilpan/heap2/bucket1'); - assert.isDefined(oilpanBucket1); - assert.equal(oilpanBucket1.fullName, 'oilpan/heap2/bucket1'); - assert.equal(oilpanBucket1.name, 'bucket1'); - checkDumpNumericsAndDiagnostics(oilpanBucket1, { - 'objects_count': new ScalarNumeric(unitlessNumber_smallerIsBetter, 31), - 'size': 8192, - 'effective_size': 8192, - 'inner_size': 8192 - }, {}); - assert.equal(oilpanBucket1.children.length, 0); - - assert.isDefined(oilpanBucket1.parent); - assert.equal(oilpanBucket1.parent.fullName, 'oilpan/heap2'); - assert.equal(oilpanBucket1.parent.name, 'heap2'); - assert.include(oilpanBucket1.parent.children, oilpanBucket1); - - assert.isDefined(oilpanBucket1.parent.parent); - assert.strictEqual(oilpanBucket1.parent.parent, oilpanRoot); - - assert.equal(d.totals.residentBytes, 256); - assert.isUndefined(d.totals.peakResidentBytes); - assert.isUndefined(d.totals.arePeakResidentBytesResettable); - assert.isUndefined(d.totals.platformSpecific); - assert.isUndefined(d.mostRecentVmRegions); - }); - - test('importMemoryDumps_implicitMemoryAllocatorDumps', function() { - var events = [ - { - name: 'a', - pid: 42, - ts: 10, - cat: 'test', - tid: 53, - ph: 'v', - id: '0x0001', - args: { - dumps: { - process_totals: { - resident_set_bytes: '100' - }, - allocators: { - 'oilpan/heap1': { - guid: '999', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '3f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '3000'}, - size: {type: 'scalar', units: 'bytes', value: '4000'} - } - }, - 'oilpan/heap2/bucket1': { - guid: '888', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '1f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '2000'}, - size: {type: 'scalar', units: 'bytes', value: '2000'} - } - }, - 'v8': { - guid: '777', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '5f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '5000'}, - size: {type: 'scalar', units: 'bytes', value: '6000'} - } - } - } - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var d = p.memoryDumps[0]; - - assert.equal(d.memoryAllocatorDumps.length, 2); - - var oilpanRoot = d.getMemoryAllocatorDumpByFullName('oilpan'); - var v8Root = d.getMemoryAllocatorDumpByFullName('v8'); - assert.isDefined(oilpanRoot); - assert.isDefined(v8Root); - assert.include(d.memoryAllocatorDumps, oilpanRoot); - assert.include(d.memoryAllocatorDumps, v8Root); - - checkDumpNumericsAndDiagnostics(oilpanRoot, { - 'objects_count': new ScalarNumeric(unitlessNumber_smallerIsBetter, 94), - 'size': 24576, - 'effective_size': 24576, - 'inner_size': 20480 - }, {}); - assert.equal(oilpanRoot.children.length, 2); - - var oilpanBucket1 = d.getMemoryAllocatorDumpByFullName( - 'oilpan/heap2/bucket1'); - assert.isDefined(oilpanBucket1); - assert.equal(oilpanBucket1.fullName, 'oilpan/heap2/bucket1'); - assert.equal(oilpanBucket1.name, 'bucket1'); - checkDumpNumericsAndDiagnostics(oilpanBucket1, { - 'objects_count': new ScalarNumeric(unitlessNumber_smallerIsBetter, 31), - 'size': 8192, - 'effective_size': 8192, - 'inner_size': 8192 - }, {}); - assert.equal(oilpanBucket1.children.length, 0); - - assert.isDefined(oilpanBucket1.parent); - assert.equal(oilpanBucket1.parent.fullName, 'oilpan/heap2'); - assert.equal(oilpanBucket1.parent.name, 'heap2'); - assert.include(oilpanBucket1.parent.children, oilpanBucket1); - - assert.isDefined(oilpanBucket1.parent.parent); - assert.strictEqual(oilpanBucket1.parent.parent, oilpanRoot); - - assert.equal(d.totals.residentBytes, 256); - assert.isUndefined(d.totals.peakResidentBytes); - assert.isUndefined(d.totals.arePeakResidentBytesResettable); - assert.isUndefined(d.totals.platformSpecific); - assert.isUndefined(d.mostRecentVmRegions); - }); - - test('importMemoryDumps_globalMemoryAllocatorDumps', function() { - var events = [ - { - name: 'a', - pid: 42, - ts: 10, - cat: 'test', - tid: 53, - ph: 'v', - id: '0x0001', - args: { - dumps: { - process_totals: { - resident_set_bytes: '100' - }, - allocators: { - 'tile_manager/tile1': { - guid: '21', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '3f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '3000'}, - size: {type: 'scalar', units: 'bytes', value: '4000'}, - weather: {type: 'string', units: '', value: 'rainy'} - } - }, - 'global/shared_bitmap_manager/bitmap2': { - guid: '42', - attrs: { - objects_count: { - type: 'scalar', units: 'objects', value: '1f' - }, - inner_size: {type: 'scalar', units: 'bytes', value: '2000'}, - size: {type: 'scalar', units: 'bytes', value: '2000'}, - weather: {type: 'string', units: '', value: 'sunny'} - } - } - } - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var gmd = m.globalMemoryDumps[0]; - var pmd = p.memoryDumps[0]; - - assert.isUndefined(gmd.totals); - assert.equal(pmd.totals.residentBytes, 256); - assert.isUndefined(pmd.totals.peakResidentBytes); - assert.isUndefined(pmd.totals.arePeakResidentBytesResettable); - assert.isUndefined(pmd.totals.platformSpecific); - - assert.isUndefined(gmd.mostRecentVmRegions); - assert.isUndefined(pmd.mostRecentVmRegions); - - assert.equal(gmd.memoryAllocatorDumps.length, 1); - assert.equal(pmd.memoryAllocatorDumps.length, 1); - - // Global memory allocator dumps. - var sharedBitmapManager = gmd.getMemoryAllocatorDumpByFullName( - 'shared_bitmap_manager'); - assert.isDefined(sharedBitmapManager); - assert.include(gmd.memoryAllocatorDumps, sharedBitmapManager); - - checkDumpNumericsAndDiagnostics(sharedBitmapManager, { - 'objects_count': new ScalarNumeric(unitlessNumber_smallerIsBetter, 31), - 'size': 8192, - 'effective_size': 8192, - 'inner_size': 8192 - }, {}); - assert.lengthOf(sharedBitmapManager.children, 1); - - var bitmap2 = gmd.getMemoryAllocatorDumpByFullName( - 'shared_bitmap_manager/bitmap2'); - assert.isDefined(bitmap2); - assert.include(sharedBitmapManager.children, bitmap2); - assert.strictEqual(bitmap2.parent, sharedBitmapManager); - - checkDumpNumericsAndDiagnostics(bitmap2, { - 'objects_count': new ScalarNumeric(unitlessNumber_smallerIsBetter, 31), - 'size': 8192, - 'effective_size': 8192, - 'inner_size': 8192 - }, { 'weather': 'sunny' }); - assert.lengthOf(bitmap2.children, 0); - - assert.isUndefined(gmd.getMemoryAllocatorDumpByFullName('tile_manager')); - assert.isUndefined( - gmd.getMemoryAllocatorDumpByFullName('tile_manager/tile1')); - - // Process memory allocator dumps. - var tileManagerRoot = pmd.getMemoryAllocatorDumpByFullName('tile_manager'); - assert.isDefined(tileManagerRoot); - assert.include(pmd.memoryAllocatorDumps, tileManagerRoot); - assert.isUndefined(tileManagerRoot.parent); - - checkDumpNumericsAndDiagnostics(tileManagerRoot, { - 'objects_count': new ScalarNumeric(unitlessNumber_smallerIsBetter, 63), - 'size': 16384, - 'effective_size': 16384, - 'inner_size': 12288 - }, {}); - assert.lengthOf(tileManagerRoot.children, 1); - - var tile1 = pmd.getMemoryAllocatorDumpByFullName( - 'tile_manager/tile1'); - assert.isDefined(tile1); - assert.include(tileManagerRoot.children, tile1); - assert.strictEqual(tile1.parent, tileManagerRoot); - - checkDumpNumericsAndDiagnostics(tile1, { - 'objects_count': new ScalarNumeric(unitlessNumber_smallerIsBetter, 63), - 'size': 16384, - 'effective_size': 16384, - 'inner_size': 12288 - }, { 'weather': 'rainy' }); - assert.lengthOf(tile1.children, 0); - - assert.isUndefined( - pmd.getMemoryAllocatorDumpByFullName('shared_bitmap_manager')); - assert.isUndefined( - pmd.getMemoryAllocatorDumpByFullName('shared_bitmap_manager/bitmap2')); - }); - - test('importMemoryDumps_memoryAllocatorDumpEdges', function() { - var events = [ - { - name: 'browser', - pid: 42, - ts: 10, - cat: 'test', - tid: 53, - ph: 'v', - id: '0x0001', - args: { - dumps: { - process_totals: { - resident_set_bytes: '100' - }, - allocators: { - 'local': { - guid: '3', - attrs: { - mood: {type: 'string', units: '', value: 'very good'} - } - }, - 'global/shared': { - guid: '7', - attrs: { - color: {type: 'string', units: '', value: 'blue'} - } - } - }, - allocators_graph: [ - { - source: '3', - target: '7', - type: 'ownership', - importance: 0 - } - ] - } - } - }, - { - name: 'renderer', - pid: 43, - ts: 11, - cat: 'test', - tid: 53, - ph: 'v', - id: '0x0001', - args: { - dumps: { - process_totals: { - resident_set_bytes: '200' - }, - allocators: { - 'local': { - guid: '4', - attrs: { - length: {type: 'scalar', units: 'bytes', value: '3'} - } - }, - 'global/shared': { - guid: '7', - attrs: { - area: {type: 'scalar', units: 'sq ft', value: '9'} - } - } - }, - allocators_graph: [ - { - source: '4', - target: '7', - type: 'ownership', - importance: 1 - } - ] - } - } - }, - { - name: 'gpu', - pid: 44, - ts: 10.5, - cat: 'test', - tid: 53, - ph: 'v', - id: '0x0001', - args: { - dumps: { - process_totals: { - resident_set_bytes: '300' - }, - allocators: { - 'local1': { - guid: '5', - attrs: { - state: {type: 'string', units: '', value: 'ON'} - } - }, - 'local2': { - guid: '6', - attrs: { - temperature: {type: 'scalar', units: 'C', value: '64'} - } - } - }, - allocators_graph: [ - { - source: '5', - target: '7', - type: 'ownership', - importance: -1 - }, - { - source: '6', - target: '5', - type: 'ownership', - importance: 1 - }, - { - source: '5', - target: '4', - type: 'retention' - } - ] - } - } - } - ]; - var model = makeModel(events); - var browserProcess = model.getProcess(42); - var rendererProcess = model.getProcess(43); - var gpuProcess = model.getProcess(44); - - assert.lengthOf(model.globalMemoryDumps, 1); - assert.lengthOf(browserProcess.memoryDumps, 1); - assert.lengthOf(rendererProcess.memoryDumps, 1); - assert.lengthOf(gpuProcess.memoryDumps, 1); - - var globalDump = model.globalMemoryDumps[0]; - var browserDump = browserProcess.memoryDumps[0]; - var rendererDump = rendererProcess.memoryDumps[0]; - var gpuDump = gpuProcess.memoryDumps[0]; - - // Global memory allocator dump. - assert.lengthOf(globalDump.memoryAllocatorDumps, 1); - - var globalDumpShared = globalDump.getMemoryAllocatorDumpByFullName( - 'shared'); - assert.isDefined(globalDumpShared); - assert.include(globalDump.memoryAllocatorDumps, globalDumpShared); - checkDumpNumericsAndDiagnostics(globalDumpShared, { - 'area': new ScalarNumeric(unitlessNumber_smallerIsBetter, 9) - }, { 'color': 'blue' }); - assert.lengthOf(globalDumpShared.children, 0); - assert.isUndefined(globalDumpShared.parent); - - assert.isUndefined(globalDumpShared.owns); - assert.lengthOf(globalDumpShared.ownedBy, 3); - assert.lengthOf(globalDumpShared.retains, 0); - assert.lengthOf(globalDumpShared.retainedBy, 0); - - // Browser memory allocator dump. - assert.lengthOf(browserDump.memoryAllocatorDumps, 1); - - var browserDumpLocal = browserDump.getMemoryAllocatorDumpByFullName( - 'local'); - assert.isDefined(browserDumpLocal); - assert.include(browserDump.memoryAllocatorDumps, browserDumpLocal); - checkDumpNumericsAndDiagnostics(browserDumpLocal, { - 'area': new ScalarNumeric(unitlessNumber_smallerIsBetter, 9) - }, { 'color': 'blue', 'mood': 'very good' }); - assert.lengthOf(browserDumpLocal.children, 0); - assert.isUndefined(browserDumpLocal.parent); - - assert.isDefined(browserDumpLocal.owns); - assert.lengthOf(browserDumpLocal.ownedBy, 0); - assert.lengthOf(browserDumpLocal.retains, 0); - assert.lengthOf(browserDumpLocal.retainedBy, 0); - - var browserDumpLocalOwnsLink = browserDumpLocal.owns; - assert.include(globalDumpShared.ownedBy, browserDumpLocalOwnsLink); - assert.strictEqual(browserDumpLocalOwnsLink.source, browserDumpLocal); - assert.strictEqual(browserDumpLocalOwnsLink.target, globalDumpShared); - assert.equal(browserDumpLocalOwnsLink.importance, 0); - - // Renderer memory allocator dump. - assert.lengthOf(rendererDump.memoryAllocatorDumps, 1); - - var rendererDumpLocal = rendererDump.getMemoryAllocatorDumpByFullName( - 'local'); - assert.isDefined(rendererDumpLocal); - assert.include(rendererDump.memoryAllocatorDumps, rendererDumpLocal); - checkDumpNumericsAndDiagnostics(rendererDumpLocal, { - 'area': new ScalarNumeric(unitlessNumber_smallerIsBetter, 9), - 'length': 3 - }, { 'color': 'blue' }); - assert.lengthOf(rendererDumpLocal.children, 0); - assert.isUndefined(rendererDumpLocal.parent); - - assert.isDefined(rendererDumpLocal.owns); - assert.lengthOf(rendererDumpLocal.ownedBy, 0); - assert.lengthOf(rendererDumpLocal.retains, 0); - assert.lengthOf(rendererDumpLocal.retainedBy, 1); - - var rendererDumpLocalOwnsLink = rendererDumpLocal.owns; - assert.include(globalDumpShared.ownedBy, rendererDumpLocalOwnsLink); - assert.strictEqual(rendererDumpLocalOwnsLink.source, rendererDumpLocal); - assert.strictEqual(rendererDumpLocalOwnsLink.target, globalDumpShared); - assert.equal(rendererDumpLocalOwnsLink.importance, 1); - - // GPU memory allocator dumps. - assert.lengthOf(gpuDump.memoryAllocatorDumps, 2); - - var gpuDumpLocal1 = gpuDump.getMemoryAllocatorDumpByFullName('local1'); - assert.isDefined(gpuDumpLocal1); - assert.include(gpuDump.memoryAllocatorDumps, gpuDumpLocal1); - checkDumpNumericsAndDiagnostics(gpuDumpLocal1, { - 'area': new ScalarNumeric(unitlessNumber_smallerIsBetter, 9) - }, { 'state': 'ON', 'color': 'blue' }); - assert.lengthOf(gpuDumpLocal1.children, 0); - assert.isUndefined(gpuDumpLocal1.parent); - - assert.isDefined(gpuDumpLocal1.owns); - assert.lengthOf(gpuDumpLocal1.ownedBy, 1); - assert.lengthOf(gpuDumpLocal1.retains, 1); - assert.lengthOf(gpuDumpLocal1.retainedBy, 0); - - var gpuDumpLocal1OwnsLink = gpuDumpLocal1.owns; - assert.include(globalDumpShared.ownedBy, gpuDumpLocal1OwnsLink); - assert.strictEqual(gpuDumpLocal1OwnsLink.source, gpuDumpLocal1); - assert.strictEqual(gpuDumpLocal1OwnsLink.target, globalDumpShared); - assert.equal(gpuDumpLocal1OwnsLink.importance, -1); - - var gpuDumpLocal1RetainsLink = gpuDumpLocal1.retains[0]; - assert.include(rendererDumpLocal.retainedBy, gpuDumpLocal1RetainsLink); - assert.strictEqual(gpuDumpLocal1RetainsLink.source, gpuDumpLocal1); - assert.strictEqual(gpuDumpLocal1RetainsLink.target, rendererDumpLocal); - assert.isUndefined(gpuDumpLocal1RetainsLink.importance); - - var gpuDumpLocal2 = gpuDump.getMemoryAllocatorDumpByFullName('local2'); - assert.isDefined(gpuDumpLocal2); - assert.include(gpuDump.memoryAllocatorDumps, gpuDumpLocal2); - checkDumpNumericsAndDiagnostics(gpuDumpLocal2, { - 'temperature': new ScalarNumeric(unitlessNumber_smallerIsBetter, 100) - }, {}); - assert.lengthOf(gpuDumpLocal2.children, 0); - assert.isUndefined(gpuDumpLocal2.parent); - - assert.isDefined(gpuDumpLocal2.owns); - assert.lengthOf(gpuDumpLocal2.ownedBy, 0); - assert.lengthOf(gpuDumpLocal2.retains, 0); - assert.lengthOf(gpuDumpLocal2.retainedBy, 0); - - var gpuDumpLocal2OwnsLink = gpuDumpLocal2.owns; - assert.include(gpuDumpLocal1.ownedBy, gpuDumpLocal2OwnsLink); - assert.strictEqual(gpuDumpLocal2OwnsLink.source, gpuDumpLocal2); - assert.strictEqual(gpuDumpLocal2OwnsLink.target, gpuDumpLocal1); - assert.equal(gpuDumpLocal2OwnsLink.importance, 1); - }); - - test('importMemoryDumps_memoryAllocatorDumpsMissingFields', function() { - var events = [ - { - name: 'a', - pid: 42, - ts: 10, - ph: 'v', - id: '0x0001', - args: { - dumps: { - allocators: { - 'no_crash': { - /* Missing GUID and attributes. */ - } - } - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var d = p.memoryDumps[0]; - - assert.equal(d.memoryAllocatorDumps.length, 1); - var noCrashRoot = d.getMemoryAllocatorDumpByFullName('no_crash'); - assert.lengthOf(noCrashRoot.children, 0); - checkDumpNumericsAndDiagnostics(noCrashRoot, {}, {}); - assert.isUndefined(noCrashRoot.parent); - assert.isUndefined(noCrashRoot.guid); - }); - - test('importMemoryDumps_weakMemoryAllocatorDumps', function() { - var events = [ - { - pid: 42, - ts: 10, - ph: 'v', - id: '0x0001', - args: { - dumps: { - allocators: { - // Sinks for ownership edges (to check that the correct ownership - // edges are removed). - 'root_sink': { guid: '100', attrs: {} }, - 'root_sink/child_sink': { guid: '200', attrs: {} }, - 'root_sink/child_sink/descendant_sink': { - guid: '300', attrs: {} - }, - - // Note: 'removed' in the name of a dump means that the dump will - // be removed despite being non-weak (strong), e.g. due to one of - // its ancestors being weak. - - // All descendants of a weak root dump should be removed. - 'weak_root': { guid: '1', attrs: {}, flags: 1 }, - 'weak_root/removed_child': { guid: '2', attrs: {} }, - 'weak_root/inferred_removed_child/removed_descendant': { - guid: '3', attrs: {}, flags: 0 - }, - - // A strong root should be kept even if all its descendants are - // weak. - 'strong_root': { guid: '4', attrs: {}, flags: 0 }, - 'strong_root/weak_child': { guid: '5', attrs: {}, flags: 1 }, - 'strong_root/inferred_weak_child/weak_descendant': { - guid: '6', attrs: {}, flags: 1 - }, - - // All inferred ancestors of a weak descendant should be marked - // weak and, consequently, removed (provided that they don't have - // any non-weak descendants). - 'inferred_weak_root/inferred_weak_child/weak_descendant': { - guid: '7', attrs: {}, flags: 1 - }, - - // An inferred dump should be marked non-weak if it has at least - // one strong descendant. - 'inferred_strong_root/child1_weak': { - guid: '8', attrs: {}, flags: 1 - }, - 'inferred_strong_root/child2_strong': { - guid: '9', attrs: {} - }, - 'inferred_strong_root/child3_weak': { - guid: '10', attrs: {}, flags: 1 - }, - 'inferred_strong_root2/inferred_strong_child/desc1_strong': { - guid: '11', attrs: {} - }, - 'inferred_strong_root2/inferred_strong_child/desc2_weak': { - guid: '12', attrs: {}, flags: 1 - }, - 'inferred_strong_root2/inferred_strong_child/desc3_strong': { - guid: '13', attrs: {} - }, - 'inferred_strong_root2/weak_child': { - guid: '14', attrs: {}, flags: 1 - }, - - // A desdendant dump should be removed if it has a weak ancestor. - 'strong_root2': { guid: '15', attrs: {} }, - 'strong_root2/weak_child': { guid: '16', attrs: {}, flags: 1 }, - 'strong_root2/weak_child/removed_descendant': { - guid: '17', attrs: {} - }, - - // Check that "weakness" also propagates across ownership edges. - 'removed_root': { guid: '18', attrs: {} }, - 'removed_root/removed_child': { - guid: '19', attrs: {} - }, - 'inferred_strong_root3/removed_child': { - guid: '20', attrs: {} - }, - }, - allocators_graph: [ - { source: '1', target: '100', type: 'ownership' }, - { source: '2', target: '200', type: 'ownership' }, - { source: '3', target: '300', type: 'ownership' }, - - { source: '4', target: '100', type: 'ownership' }, // Kept. - { source: '5', target: '200', type: 'ownership' }, - { source: '6', target: '300', type: 'ownership' }, - - { source: '7', target: '300', type: 'ownership' }, - - { source: '8', target: '200', type: 'ownership' }, - { source: '9', target: '200', type: 'ownership' }, // Kept. - { source: '10', target: '200', type: 'ownership' }, - { source: '11', target: '300', type: 'ownership' }, // Kept. - { source: '12', target: '300', type: 'ownership' }, - { source: '13', target: '300', type: 'ownership' }, // Kept. - { source: '14', target: '200', type: 'ownership' }, - - { source: '15', target: '100', type: 'ownership' }, // Kept. - { source: '16', target: '200', type: 'ownership' }, - { source: '17', target: '300', type: 'ownership' }, - - { source: '18', target: '3' /* not a sink */, type: 'ownership' }, - { source: '19', target: '200', type: 'ownership' }, - { source: '20', target: '19' /* not a sink */, type: 'ownership' } - ] - } - } - } - ]; - var m = makeModel(events); - var p = m.getProcess(42); - var d = p.memoryDumps[0]; - var memoryAllocatorDumps = d.memoryAllocatorDumps; - assert.lengthOf(memoryAllocatorDumps, 6); - - function checkDump(dump, expectedFullName, expectedGuid, expectedParent, - expectedChildCount, expectedOwnsLink, expectedOwnedByLinkCount) { - assert.strictEqual(dump.fullName, expectedFullName); - assert.strictEqual(dump.guid, expectedGuid); - assert.strictEqual(dump.parent, expectedParent); - assert.lengthOf(dump.children, expectedChildCount); - assert.strictEqual(dump.owns, expectedOwnsLink); - assert.lengthOf(dump.ownedBy, expectedOwnedByLinkCount); - assert.strictEqual( - d.getMemoryAllocatorDumpByFullName(expectedFullName), dump); - } - - function checkOwnsLink(ownerDump, expectedTarget) { - assert.strictEqual(ownerDump.owns.source, ownerDump); - assert.strictEqual(ownerDump.owns.target, expectedTarget); - } - - // Check root_sink/* dumps. - var rootSink = d.memoryAllocatorDumps[3]; - checkDump(rootSink, 'root_sink', '100', undefined, 1, undefined, 2); - var childSink = rootSink.children[0]; - checkDump(childSink, 'root_sink/child_sink', '200', rootSink, 1, undefined, - 1); - var descendantSink = childSink.children[0]; - checkDump(descendantSink, 'root_sink/child_sink/descendant_sink', '300', - childSink, 0, undefined, 2); - - // Check strong_root/* dumps. - var strongRoot = d.memoryAllocatorDumps[4]; - checkDump(strongRoot, 'strong_root', '4', undefined, 0, rootSink.ownedBy[0], - 0); - - // Check inferred_strong_root/* dumps. - var inferredStrongRoot = d.memoryAllocatorDumps[0]; - checkDump(inferredStrongRoot, 'inferred_strong_root', undefined, undefined, - 1, undefined, 0); - var child2Strong = inferredStrongRoot.children[0]; - checkDump(child2Strong, 'inferred_strong_root/child2_strong', '9', - inferredStrongRoot, 0, childSink.ownedBy[0], 0); - - // Check inferred_strong_root2/* dumps. - var inferredStrongRoot2 = d.memoryAllocatorDumps[1]; - checkDump(inferredStrongRoot2, 'inferred_strong_root2', undefined, - undefined, 1, undefined, 0); - var inferredStrongChild = inferredStrongRoot2.children[0]; - checkDump(inferredStrongChild, - 'inferred_strong_root2/inferred_strong_child', undefined, - inferredStrongRoot2, 2, undefined, 0); - var desc1Strong = inferredStrongChild.children[0]; - checkDump(desc1Strong, - 'inferred_strong_root2/inferred_strong_child/desc1_strong', '11', - inferredStrongChild, 0, descendantSink.ownedBy[0], 0); - var desc3Strong = inferredStrongChild.children[1]; - checkDump(desc3Strong, - 'inferred_strong_root2/inferred_strong_child/desc3_strong', '13', - inferredStrongChild, 0, descendantSink.ownedBy[1], 0); - - // Check strong_root2/* dumps. - var strongRoot2 = d.memoryAllocatorDumps[5]; - checkDump(strongRoot2, 'strong_root2', '15', undefined, 0, - rootSink.ownedBy[1], 0); - - // Check inferred_strong_root3/* dumps. - var inferredStrongRoot3 = d.memoryAllocatorDumps[2]; - checkDump(inferredStrongRoot3, 'inferred_strong_root3', undefined, - undefined, 0, undefined, 0); - - // Check the links. - checkOwnsLink(strongRoot, rootSink); - checkOwnsLink(child2Strong, childSink); - checkOwnsLink(desc1Strong, descendantSink); - checkOwnsLink(desc3Strong, descendantSink); - checkOwnsLink(strongRoot2, rootSink); - - // Check that the removed weak dumps are not indexed. - [ - 'weak_root', - 'weak_root/removed_child', - 'weak_root/inferred_removed_child', - 'weak_root/inferred_removed_child/removed_descendant', - 'strong_root/weak_child', - 'strong_root/inferred_weak_child/weak_descendant', - 'inferred_weak_root', - 'inferred_weak_root/inferred_weak_child', - 'inferred_weak_root/inferred_weak_child/weak_descendant', - 'inferred_strong_root/child1_weak', - 'inferred_strong_root/child3_weak', - 'inferred_strong_root2/inferred_strong_child/desc2_weak', - 'inferred_strong_root2/weak_child', - 'strong_root2/weak_child', - 'strong_root2/removed_descendant', - 'removed_root', - 'removed_root/removed_child', - 'inferred_strong_root3/removed_child' - ].forEach(function(fullName) { - assert.isUndefined(d.getMemoryAllocatorDumpByFullName(fullName)); - }); - }); - - test('importMemoryDumps_levelsOfDetail', function() { - function checkLevelsOfDetail(pmdSpecifications, expectedGlobalLevelOfDetail, - expectedProcessLevelsOfDetail, expectedHasWarnings) { - var events = []; - pmdSpecifications.forEach(function(singlePmdSpecifications, pid) { - singlePmdSpecifications.forEach(function(singlePmdSpecification) { - var dumps = {}; - if (singlePmdSpecification.levelOfDetail !== undefined) - dumps.level_of_detail = singlePmdSpecification.levelOfDetail; - if (singlePmdSpecification.vmRegions) { - dumps.process_mmaps = { - vm_regions: [ - { sa: 'f0', sz: '150', pf: 6, mf: '[stack]', bs: { pss: 'ff'} } - ] - }; - } - events.push({ - name: 'process_' + pid, - pid: pid, - ts: 10, - ph: 'v', - id: '0x0001', - args: { - dumps: dumps - } - }); - }); - }); - var model = makeModel(events); - - // Check GlobalMemoryDump level of detail. - assert.lengthOf(model.globalMemoryDumps, 1); - assert.strictEqual(model.globalMemoryDumps[0].levelOfDetail, - expectedGlobalLevelOfDetail); - - // Check ProcessMemoryDumps levels of detail. - assert.lengthOf(Object.keys(model.processes), - expectedProcessLevelsOfDetail.length); - for (var i = 0; i < expectedProcessLevelsOfDetail.length; i++) { - var process = model.getProcess(i); - assert.lengthOf(process.memoryDumps, 1); - assert.strictEqual(process.memoryDumps[0].levelOfDetail, - expectedProcessLevelsOfDetail[i]); - } - - assert.strictEqual(model.hasImportWarnings, expectedHasWarnings); - } - - // Legacy trace events (without levels of detail). - checkLevelsOfDetail([[{}]], LIGHT, [LIGHT], false); - checkLevelsOfDetail([[{ vmRegions: true }]], DETAILED, [DETAILED], false); - checkLevelsOfDetail( - [ - [{}] /* raw composable PMD1 events */, - [{}, {}] /* raw composable PMD2 events */ - ], - LIGHT /* expected GMD level of detail */, - [LIGHT, LIGHT] /* expected PMD levels of detail */, - false /* no warnings expected */); - checkLevelsOfDetail( - [ - [{}, { vmRegions: true }, {}], - [{ vmRegions: true }, {}] - ], - DETAILED, [DETAILED, DETAILED], false); - - // Well-formed traces events (VM regions should be irrelevant). - checkLevelsOfDetail( - [ - [{ levelOfDetail: 'light'}], - [{ levelOfDetail: 'light', vmRegions: true }] - ], - LIGHT, [LIGHT, LIGHT], false); - checkLevelsOfDetail( - [ - [ - { levelOfDetail: 'detailed' }, { levelOfDetail: 'detailed' } - ], - [ - { levelOfDetail: 'detailed', vmRegions: true } - ], - [ - { levelOfDetail: 'detailed' }, - { levelOfDetail: 'detailed', vmRegions: true }, - { levelOfDetail: 'detailed' } - ] - ], - DETAILED, [DETAILED, DETAILED, DETAILED], false); - - // Not so well-formed trace events. - checkLevelsOfDetail( - [ - [{}, { levelOfDetail: 'detailed'}, {}] - ], - DETAILED, [DETAILED], true); - checkLevelsOfDetail( - [ - [{ levelOfDetail: 'light' }], - [{}], - [{ levelOfDetail: 'detailed' }], - [{ levelOfDetail: 'light' }]], - DETAILED, [LIGHT, LIGHT, DETAILED, LIGHT], true); - checkLevelsOfDetail( - [ - [{ levelOfDetail: 'light' }, { levelOfDetail: 'detailed' }], - [{}], - [{ levelOfDetail: 'light' }, {}]], - DETAILED, [DETAILED, LIGHT, LIGHT], true); - checkLevelsOfDetail( - [ - [{ levelOfDetail: 'invalid' }, { levelOfDetail: 'light' }], - [{ levelOfDetail: 'invalid' }]], - LIGHT, [LIGHT, LIGHT], true); - }); - - test('importMemoryDumps_heapDumps_oldFormat', function() { - var events = [ // Intentionally shuffled. - { - pid: 21, - ts: 9, - ph: 'v', - id: '0123', - args: { - dumps: { - heaps: { - partition_alloc: { - entries: [ - { size: '1000' }, - { bt: '0', size: 'abc' } - ] - } - } - } - } - }, - { - pid: 42, - ph: 'M', - name: 'stackFrames', - args: { - stackFrames: { - '0': { name: 'MessageLoop::RunTask' }, - '1': { name: 'TimerBase::run', parent: '0' }, - 'TWO': { name: 'ScheduledAction::execute', 'parent': '1' }, - '3': { name: 'FunctionCall', parent: 'TWO' }, - '4': { name: 'UpdateLayoutTree', parent: '1' }, - '5': { name: 'MessageLoop::JogTask' } - } - } - }, - { - pid: 42, - ph: 'M', - name: 'typeNames', - args: { - typeNames: { - // GCC. - '22': '[unknown]', - '23': 'testing::ManuallyAnnotatedMockClass', - '24': 'const char* WTF::getStringWithTypeName() [with T = ' + - 'blink::Event]', - '25': 'blink::ContextLifecycleObserver*', - '26': 'const char* WTF::getStringWithTypeName() [with T = ' + - 'blink::WebFrame*]' - } - } - }, - { - pid: 42, - ts: 10, - ph: 'v', - id: '0123', - args: { - dumps: { - process_totals: { - resident_set_bytes: '0' - }, - heaps: { - partition_alloc: { - entries: [ - { type: '24', size: '2e6fc8' }, - { size: '5cdf91' }, - { type: '25', size: '1737e4' }, - { bt: '', size: '5b6cd6' }, - { bt: '4', size: '18f0' }, - { bt: '3', size: 'e3a8' } - ] - }, - malloc: { - entries: [ - { size: '789' }, - { bt: '0', size: '123' }, - { bt: '5', size: '456' }, - { type: '25', size: 'cd' } - ] - } - } - } - } - }, - { - pid: 21, - ph: 'M', - name: 'stackFrames', - args: { - stackFrames: { - // Intentionally in reverse order. - '0': { name: 'FrameView::layout', parent: '1' }, - '1': { name: 'MessageLoop::RunTask' } - } - } - }, - { - pid: 21, - ts: 12, - ph: 'v', - id: '0987', - args: { - dumps: { - heaps: { - partition_alloc: { - entries: [ - { size: '2000' }, - { bt: '0', size: 'def' } - ] - } - } - } - } - } - ]; - var m = makeModel(events); - var p1 = m.getProcess(21); - var p2 = m.getProcess(42); - assert.lengthOf(m.globalMemoryDumps, 2); - assert.lengthOf(p1.memoryDumps, 2); - assert.lengthOf(p2.memoryDumps, 1); - - // Stack frames. - assert.deepEqual( - tr.b.mapItems(m.stackFrames, function(id, f) { return f.title }), - { - 'p21:0': 'FrameView::layout', - 'p21:0:self': '<self>', - 'p21:1': 'MessageLoop::RunTask', - 'p42::self': '<self>', - 'p42:0': 'MessageLoop::RunTask', - 'p42:0:self': '<self>', - 'p42:1': 'TimerBase::run', - 'p42:TWO': 'ScheduledAction::execute', - 'p42:3': 'FunctionCall', - 'p42:3:self': '<self>', - 'p42:4': 'UpdateLayoutTree', - 'p42:4:self': '<self>', - 'p42:5': 'MessageLoop::JogTask', - 'p42:5:self': '<self>' - }); - - // 1. Process 21, first dump. - var pmd1 = p1.memoryDumps[0]; - var hds1 = pmd1.heapDumps; - assert.sameMembers(Object.keys(hds1), ['partition_alloc']); - - var partitionAllocDump1 = hds1['partition_alloc']; - assert.strictEqual(partitionAllocDump1.processMemoryDump, pmd1); - assert.equal(partitionAllocDump1.allocatorName, 'partition_alloc'); - var partitionAllocEntries1 = partitionAllocDump1.entries; - assert.lengthOf(partitionAllocEntries1, 2); - checkHeapEntry(partitionAllocEntries1[0], partitionAllocDump1, 4096, - undefined /* root */, undefined /* sum over all types */); - checkHeapEntry(partitionAllocEntries1[1], partitionAllocDump1, 2748, - ['<self>', 'FrameView::layout', 'MessageLoop::RunTask']); - - // 2. Process 21, second dump. - var pmd2 = p1.memoryDumps[1]; - var hds2 = pmd2.heapDumps; - assert.sameMembers(Object.keys(hds2), ['partition_alloc']); - - var partitionAllocDump2 = hds2['partition_alloc']; - assert.strictEqual(partitionAllocDump2.processMemoryDump, pmd2); - assert.equal(partitionAllocDump2.allocatorName, 'partition_alloc'); - var partitionAllocEntries2 = partitionAllocDump2.entries; - assert.lengthOf(partitionAllocEntries2, 2); - checkHeapEntry(partitionAllocEntries2[0], partitionAllocDump2, 8192, - undefined /* root */, undefined /* sum over all types */); - checkHeapEntry(partitionAllocEntries2[1], partitionAllocDump2, 3567, - ['<self>', 'FrameView::layout', 'MessageLoop::RunTask'], - undefined /* sum over all types */); - - // All heap dumps in Process 21 should use the same stack frames. - assert.strictEqual( - getFrame(partitionAllocEntries1[1], 0), - getFrame(partitionAllocEntries2[1], 0)); - - // 3. Process 42. - var pmd3 = p2.memoryDumps[0]; - var hds3 = pmd3.heapDumps; - assert.sameMembers(Object.keys(hds3), ['partition_alloc', 'malloc']); - - var partitionAllocDump3 = hds3['partition_alloc']; - assert.strictEqual(partitionAllocDump3.processMemoryDump, pmd3); - assert.equal(partitionAllocDump3.allocatorName, 'partition_alloc'); - var partitionAllocEntries3 = partitionAllocDump3.entries; - assert.lengthOf(partitionAllocEntries3, 6); - checkHeapEntry(partitionAllocEntries3[0], partitionAllocDump3, 3043272, - undefined /* root */, 'blink::Event'); - checkHeapEntry(partitionAllocEntries3[1], partitionAllocDump3, 6086545, - undefined /* root */, undefined /* sum over all types */); - checkHeapEntry(partitionAllocEntries3[2], partitionAllocDump3, 1521636, - undefined /* root */, 'blink::ContextLifecycleObserver*'); - checkHeapEntry(partitionAllocEntries3[3], partitionAllocDump3, 5991638, - ['<self>'], undefined /* sum over all types */); - checkHeapEntry(partitionAllocEntries3[4], partitionAllocDump3, 6384, - ['<self>', 'UpdateLayoutTree', 'TimerBase::run', - 'MessageLoop::RunTask'], undefined /* sum over all types */); - checkHeapEntry(partitionAllocEntries3[5], partitionAllocDump3, 58280, - ['<self>', 'FunctionCall', 'ScheduledAction::execute', 'TimerBase::run', - 'MessageLoop::RunTask'], undefined /* sum over all types */); - - var mallocDump3 = hds3['malloc']; - assert.strictEqual(mallocDump3.processMemoryDump, pmd3); - assert.equal(mallocDump3.allocatorName, 'malloc'); - var mallocEntries3 = mallocDump3.entries; - assert.lengthOf(mallocEntries3, 4); - checkHeapEntry(mallocEntries3[0], mallocDump3, 1929, undefined /* root */, - undefined /* sum over all types */); - checkHeapEntry(mallocEntries3[1], mallocDump3, 291, - ['<self>', 'MessageLoop::RunTask'], undefined /* sum over all types */); - checkHeapEntry(mallocEntries3[2], mallocDump3, 1110, - ['<self>', 'MessageLoop::JogTask'], undefined /* sum over all types */); - checkHeapEntry(mallocEntries3[3], mallocDump3, 205, undefined /* root */, - 'blink::ContextLifecycleObserver*'); - - // All heap dumps in Process 42 should use the same stack frames. - assert.strictEqual( - getFrame(partitionAllocEntries3[5], 3), - getFrame(partitionAllocEntries3[4], 2)); - assert.strictEqual( - getFrame(mallocEntries3[1], 1), - getFrame(partitionAllocEntries3[4], 3)); - }); - - test('importMemoryDumps_heapDumps_newFormat', function() { - var events = [ // Intentionally shuffled. - { - pid: 21, - ts: 9, - ph: 'v', - id: '0123', - args: { - dumps: { - heaps: { - partition_alloc: { - entries: [ - { bt: '', type: '25', size: '1000' }, - { bt: 'A', size: 'abc' } - ] - } - } - } - } - }, - { - pid: 42, - ph: 'M', - name: 'stackFrames', - args: { - stackFrames: { - '-1': { name: '<self>' }, - '0': { name: 'MessageLoop::RunTask' }, - '0.5': { name: '<self>', parent: '0' }, - '1': { name: 'TimerBase::run', parent: '0' }, - 'TWO': { name: 'ScheduledAction::execute', 'parent': '1' }, - '2.72': { name: '<self>', 'parent': 'TWO' }, - '3': { name: 'FunctionCall', parent: 'TWO' }, - '\u03C0': { name: '<self>', parent: '3' }, - '4': { name: 'UpdateLayoutTree', parent: '1' }, - 'FOUR-AND-A-BIT': { name: '<self>', parent: '4' }, - '5': { name: 'MessageLoop::JogTask' }, - 'NaN': { name: '<self>', parent: '5' } - } - } - }, - { - pid: 42, - ph: 'M', - name: 'typeNames', - args: { - typeNames: { - // Clang. - '22': '[unknown]', - '23': 'testing::ManuallyAnnotatedMockClass', - '24': 'const char *WTF::getStringWithTypeName() [T = ' + - 'blink::Event]', - '25': 'blink::ContextLifecycleObserver *', - '26': 'const char *WTF::getStringWithTypeName() [T = ' + - 'blink::WebFrame *]' - } - } - }, - { - pid: 42, - ts: 10, - ph: 'v', - id: '0123', - args: { - dumps: { - process_totals: { - resident_set_bytes: '0' - }, - heaps: { - partition_alloc: { - entries: [ - { bt: '' /* root */, size: '5cdf91' }, - { bt: '' /* root */, type: '24', size: '2e6fc8' }, - { bt: '' /* root */, type: '25', size: '1737e4' }, - { bt: '-1', type: '22', size: '5b6cd6' }, - { bt: 'FOUR-AND-A-BIT', size: '18f0', count: '100' }, - { bt: 'FOUR-AND-A-BIT', type: '26', size: 'c78' }, - { bt: '\u03C0', size: 'e3a8' } - ] - }, - malloc: { - entries: [ - { bt: '', size: '789', count: '50' }, - { bt: '0.5', size: '123', count: '60' }, - { bt: 'NaN', size: '456', count: '70' }, - { bt: '3', type: '25', size: 'cd', count: '80' } - ] - } - } - } - } - }, - { - pid: 21, - ph: 'M', - name: 'stackFrames', - args: { - stackFrames: { - // Intentionally in reverse order. - 'A': { name: '<self>', parent: '0' }, - '0': { name: 'FrameView::layout', parent: '1' }, - '1': { name: 'MessageLoop::RunTask' } - } - } - }, - { - pid: 21, - ts: 12, - ph: 'v', - id: '0987', - args: { - dumps: { - heaps: { - winheap: { - entries: [] // Intentionally empty. - }, - partition_alloc: { - entries: [ - { bt: '', size: '2000' }, - { bt: 'A', type: '25', size: 'def' }, - { bt: '3' /* invalid */, size: 'aaa' }, - { bt: 'A', type: '24' /* invalid */, size: 'bbb' }, - { bt: '0', size: 'fff' } - ] - } - } - } - } - }, - { - pid: 21, - ph: 'M', - name: 'typeNames', - args: { - typeNames: { - // Microsoft Visual C++. - '25': 'const char *__cdecl WTF::getStringWithTypeName<class ' + - 'v8::FunctionCallbackInfo<class v8::Value>>(void)' - } - } - }, - { - pid: 63, - ph: 'M', - name: 'stackFrames', - args: { - stackFrames: {} // Intentionally empty. - } - }, - { - pid: 63, - ph: 'M', - name: 'typeNames', - args: { - typeNames: {} // Intentionally empty. - } - }, - { - pid: 63, - ts: 13, - ph: 'v', - id: '0987', - args: { - dumps: { - heaps: { - winheap: { - entries: [ - { bt: '', size: '10000' } - ] - } - } - } - } - }, - { - pid: 84, - ph: 'M', - name: 'stackFrames', - args: { - stackFrames: { - '5': { name: 'MessageLoop::WalkTask' } - } - } - }, - { - pid: 84, - ph: 'M', - name: 'typeNames', - args: { - typeNames: { - '0': '[unknown]', - '1': 'base::All', - '3': 'content::Manually', - '4': 'net::Annotated' - } - } - }, - { - pid: 84, - ts: 14, - ph: 'v', - id: '0987', - args: { - dumps: { - heaps: { - malloc: { - entries: [ - { bt: '5', type: '3', size: 'abcd' } - ] - } - } - } - } - } - ]; - var m = makeModel(events); - var p1 = m.getProcess(21); - var p2 = m.getProcess(42); - var p3 = m.getProcess(63); - var p4 = m.getProcess(84); - assert.lengthOf(m.globalMemoryDumps, 2); - assert.lengthOf(p1.memoryDumps, 2); - assert.lengthOf(p2.memoryDumps, 1); - assert.lengthOf(p3.memoryDumps, 1); - assert.lengthOf(p4.memoryDumps, 1); - - // Stack frames. - assert.deepEqual( - tr.b.mapItems(m.stackFrames, function(id, f) { return f.title }), - { - 'p21:0': 'FrameView::layout', - 'p21:A': '<self>', - 'p21:1': 'MessageLoop::RunTask', - 'p42:-1': '<self>', - 'p42:0': 'MessageLoop::RunTask', - 'p42:0.5': '<self>', - 'p42:1': 'TimerBase::run', - 'p42:TWO': 'ScheduledAction::execute', - 'p42:2.72': '<self>', - 'p42:3': 'FunctionCall', - 'p42:\u03C0': '<self>', - 'p42:4': 'UpdateLayoutTree', - 'p42:FOUR-AND-A-BIT': '<self>', - 'p42:5': 'MessageLoop::JogTask', - 'p42:NaN': '<self>', - 'p84:5': 'MessageLoop::WalkTask' - }); - - // 1. Process 21, first dump. - var pmd1 = p1.memoryDumps[0]; - var hds1 = pmd1.heapDumps; - assert.sameMembers(Object.keys(hds1), ['partition_alloc']); - - var partitionAllocDump1 = hds1['partition_alloc']; - assert.strictEqual(partitionAllocDump1.processMemoryDump, pmd1); - assert.equal(partitionAllocDump1.allocatorName, 'partition_alloc'); - var partitionAllocEntries1 = partitionAllocDump1.entries; - assert.lengthOf(partitionAllocEntries1, 2); - checkHeapEntry(partitionAllocEntries1[0], partitionAllocDump1, 4096, - undefined /* root */, - 'class v8::FunctionCallbackInfo<class v8::Value>'); - checkHeapEntry(partitionAllocEntries1[1], partitionAllocDump1, 2748, - ['<self>', 'FrameView::layout', 'MessageLoop::RunTask'], - undefined /* sum over all types */); - - // 2. Process 21, second dump. - var pmd2 = p1.memoryDumps[1]; - var hds2 = pmd2.heapDumps; - assert.sameMembers(Object.keys(hds2), ['partition_alloc']); - - var partitionAllocDump2 = hds2['partition_alloc']; - assert.strictEqual(partitionAllocDump2.processMemoryDump, pmd2); - assert.equal(partitionAllocDump2.allocatorName, 'partition_alloc'); - var partitionAllocEntries2 = partitionAllocDump2.entries; - assert.lengthOf(partitionAllocEntries2, 3); - checkHeapEntry(partitionAllocEntries2[0], partitionAllocDump2, 8192, - undefined /* root */, undefined /* sum over all types */); - checkHeapEntry(partitionAllocEntries2[1], partitionAllocDump2, 3567, - ['<self>', 'FrameView::layout', 'MessageLoop::RunTask'], - 'class v8::FunctionCallbackInfo<class v8::Value>'); - checkHeapEntry(partitionAllocEntries2[2], partitionAllocDump2, 4095, - ['FrameView::layout', 'MessageLoop::RunTask'], - undefined /* sum over all types */); - - // All heap dumps in Process 21 should use the same stack frames. - assert.strictEqual( - getFrame(partitionAllocEntries1[1], 0), - getFrame(partitionAllocEntries2[1], 0)); - assert.strictEqual( - getFrame(partitionAllocEntries2[2], 0), - getFrame(partitionAllocEntries2[1], 1)); - - // 3. Process 42. - var pmd3 = p2.memoryDumps[0]; - var hds3 = pmd3.heapDumps; - assert.sameMembers(Object.keys(hds3), ['partition_alloc', 'malloc']); - - var partitionAllocDump3 = hds3['partition_alloc']; - assert.strictEqual(partitionAllocDump3.processMemoryDump, pmd3); - assert.equal(partitionAllocDump3.allocatorName, 'partition_alloc'); - var partitionAllocEntries3 = partitionAllocDump3.entries; - assert.lengthOf(partitionAllocEntries3, 7); - checkHeapEntry(partitionAllocEntries3[0], partitionAllocDump3, 6086545, - undefined /* root */, undefined /* sum over all types */); - checkHeapEntry(partitionAllocEntries3[1], partitionAllocDump3, 3043272, - undefined /* root */, 'blink::Event'); - checkHeapEntry(partitionAllocEntries3[2], partitionAllocDump3, 1521636, - undefined /* root */, 'blink::ContextLifecycleObserver *'); - checkHeapEntry(partitionAllocEntries3[3], partitionAllocDump3, 5991638, - ['<self>'], '[unknown]'); - checkHeapEntry(partitionAllocEntries3[4], partitionAllocDump3, 6384, - ['<self>', 'UpdateLayoutTree', 'TimerBase::run', - 'MessageLoop::RunTask'], undefined /* sum over all types */, 256); - checkHeapEntry(partitionAllocEntries3[5], partitionAllocDump3, 3192, - ['<self>', 'UpdateLayoutTree', 'TimerBase::run', - 'MessageLoop::RunTask'], 'blink::WebFrame *'); - checkHeapEntry(partitionAllocEntries3[6], partitionAllocDump3, 58280, - ['<self>', 'FunctionCall', 'ScheduledAction::execute', 'TimerBase::run', - 'MessageLoop::RunTask'], undefined /* sum over all types */); - - var mallocDump3 = hds3['malloc']; - assert.strictEqual(mallocDump3.processMemoryDump, pmd3); - assert.equal(mallocDump3.allocatorName, 'malloc'); - var mallocEntries3 = mallocDump3.entries; - assert.lengthOf(mallocEntries3, 4); - checkHeapEntry(mallocEntries3[0], mallocDump3, 1929, undefined /* root */, - undefined /* sum over all types */, 80); - checkHeapEntry(mallocEntries3[1], mallocDump3, 291, - ['<self>', 'MessageLoop::RunTask'], undefined /* sum over all types */, - 96); - checkHeapEntry(mallocEntries3[2], mallocDump3, 1110, - ['<self>', 'MessageLoop::JogTask'], undefined /* sum over all types */, - 112); - checkHeapEntry(mallocEntries3[3], mallocDump3, 205, - ['FunctionCall', 'ScheduledAction::execute', 'TimerBase::run', - 'MessageLoop::RunTask'], 'blink::ContextLifecycleObserver *', 128); - - // All heap dumps in Process 42 should use the same stack frames. - assert.strictEqual( - getFrame(partitionAllocEntries3[5], 0), - getFrame(partitionAllocEntries3[4], 0)); - assert.strictEqual( - getFrame(partitionAllocEntries3[6], 3), - getFrame(partitionAllocEntries3[4], 2)); - assert.strictEqual( - getFrame(mallocEntries3[1], 1), - getFrame(partitionAllocEntries3[4], 3)); - assert.strictEqual( - getFrame(mallocEntries3[3], 0), - getFrame(partitionAllocEntries3[6], 1)); - - // 4. Process 63. - var pmd4 = p3.memoryDumps[0]; - var hds4 = pmd4.heapDumps; - assert.sameMembers(Object.keys(hds4), ['winheap']); - - var winheapDump = hds4['winheap']; - assert.strictEqual(winheapDump.processMemoryDump, pmd4); - assert.equal(winheapDump.allocatorName, 'winheap'); - var winheapEntries = winheapDump.entries; - assert.lengthOf(winheapEntries, 1); - checkHeapEntry(winheapEntries[0], winheapDump, 65536, - undefined /* root */, undefined /* sum over all types */); - - // 5. Process 84. - var pmd5 = p4.memoryDumps[0]; - var hds5 = pmd5.heapDumps; - assert.sameMembers(Object.keys(hds5), ['malloc']); - - var mallocDump4 = hds5['malloc']; - assert.strictEqual(mallocDump4.processMemoryDump, pmd5); - assert.equal(mallocDump4.allocatorName, 'malloc'); - var mallocEntries4 = mallocDump4.entries; - assert.lengthOf(mallocEntries4, 1); - checkHeapEntry(mallocEntries4[0], mallocDump4, 43981, - ['MessageLoop::WalkTask'], 'content::Manually'); - }); - - test('importMemoryDumps_composableDumps', function() { - // Split PMD1 over multiple PMD trace events, all of which should be merged - // by the importer. Also inject some PMD trace events with different PIDs - // or dump IDs, which should *not* be merged with the rest. - var events = [ - { // Heap dumps. - pid: 42, - ts: 10000, - ph: 'v', - id: '0x0001', - args: { - dumps: { - level_of_detail: 'light', - heaps: { - partition_alloc: { - entries: [ - { bt: '99', type: '888', size: '500' } - ] - } - } - } - } - }, - { // PMD2 with a different dump id (should not be merged). - pid: 42, - ts: 10003, // Same PID, so it will end up in the same process. - ph: 'v', - id: '0x0002', - args: { - dumps: { - level_of_detail: 'detailed', - allocators: { - 'local1': { - guid: '3', - attrs: { - A: {type: 'scalar', units: 'bytes', value: '0xBAD'} - } - }, - 'global/shared1': { - guid: '4', - attrs: { - A: {type: 'string', units: '', value: 'brown'} - } - } - }, - allocators_graph: [ - { - source: '4', - target: '3', - type: 'ownership' - } - ] - } - } - }, - { // Stack frames (required for heap dumps). - pid: 42, - ph: 'M', - name: 'stackFrames', - args: { - stackFrames: { - '99': { name: 'MessageLoop::RunTask' } - } - } - }, - { // Allocator dumps. - pid: 42, - ts: 10001, - ph: 'v', - id: '0x0001', - args: { - dumps: { - level_of_detail: 'light', - allocators: { - 'local1': { - guid: '3', - attrs: { - A: {type: 'string', units: '', value: 'blue'} - } - }, - 'global/shared1': { - guid: '7', - attrs: { - A: {type: 'string', units: '', value: 'purple'} - } - }, - 'global/shared2': { - guid: '8', - attrs: { - A: {type: 'string', units: '', value: 'cyan'} - } - } - } - } - } - }, - { // PMD3 with a different PID (should not be merged). - pid: 68, - ts: 9999, - ph: 'v', - id: '0x0001', // Same dump ID, so it will end up in the same GMD. - args: { - dumps: { - process_mmaps: { - vm_regions: [ - { - sa: '350', - sz: '250', - pf: 5, - mf: '/dev/ashmem/dalvik', - bs: { - pd: 'cd' - } - } - ] - } - } - } - }, - { // VM regions. - pid: 42, - ts: 10005, - ph: 'v', - id: '0x0001', - args: { - dumps: { - level_of_detail: 'light', - process_mmaps: { - vm_regions: [ - { - sa: 'f0', - sz: '150', - pf: 6, - mf: '[stack:20310]', - bs: { - pss: '9e' - } - } - ] - } - } - } - }, - { // Totals. - pid: 42, - ts: 10003, - ph: 'v', - id: '0x0001', - args: { - dumps: { - level_of_detail: 'light', - process_totals: { - resident_set_bytes: '100', - private_bytes: '80' // OS-specific total. - } - } - } - }, - { // Allocator dump edges. - pid: 42, - ts: 10004, - ph: 'v', - id: '0x0001', - args: { - dumps: { - level_of_detail: 'light', - allocators_graph: [ - { - source: '4', - target: '8', - type: 'retention' - } - ] - } - } - }, - { // Object type names (required for heap dumps). - pid: 42, - ph: 'M', - name: 'typeNames', - args: { - typeNames: { - // GCC. - '888': 'const char* WTF::getStringWithTypeName() [with T = ' + - 'cc::SurfaceFactory]' - } - } - }, - { // Allocator dumps and dump edges (should be merged). - pid: 42, - ts: 10002, - ph: 'v', - id: '0x0001', - args: { - dumps: { - level_of_detail: 'light', - allocators: { - 'local1': { - guid: '3', - attrs: { - B: {type: 'string', units: '', value: 'red'} - } - }, - 'local2': { - guid: '4', - attrs: { - B: {type: 'string', units: '', value: 'yellow'} - } - }, - 'global/shared1': { - guid: '7', - attrs: { - B: {type: 'string', units: '', value: 'green'} - } - } - }, - allocators_graph: [ - { - source: '3', - target: '7', - type: 'ownership', - importance: 1 - } - ] - } - } - } - ]; - var m = makeModel(events, false); - - function checkDumpTime(dump, expectedStart, expectedDuration) { - assert.closeTo(dump.start, expectedStart / 1000, 1e-5); - assert.closeTo(dump.duration, expectedDuration / 1000, 1e-5); - } - - function checkLinkCounts(allocatorDump, expectedHasOwns, - expectedOwnedByCount, expectedRetainsCount, expectedRetainedByCount) { - assert.strictEqual(allocatorDump.owns !== undefined, expectedHasOwns); - assert.lengthOf(allocatorDump.ownedBy, expectedOwnedByCount); - assert.lengthOf(allocatorDump.retains, expectedRetainsCount); - assert.lengthOf(allocatorDump.retainedBy, expectedRetainedByCount); - } - - // Check the overall structure of the model and memory dumps. - assert.sameMembers(Object.keys(m.processes), ['42', '68']); - assert.lengthOf(m.globalMemoryDumps, 2); - var gmd1 = m.globalMemoryDumps[0]; - assert.strictEqual(gmd1.model, m); - checkDumpTime(gmd1, 9999, 6); - var gmd2 = m.globalMemoryDumps[1]; - assert.strictEqual(gmd2.model, m); - checkDumpTime(gmd2, 10003, 0); - - var p1 = m.getProcess(42); - assert.lengthOf(p1.memoryDumps, 2); - var pmd1 = p1.memoryDumps[0]; - checkDumpTime(pmd1, 10000, 5); - assert.strictEqual(pmd1.globalMemoryDump, gmd1); - assert.strictEqual(pmd1.process, p1); - var pmd2 = p1.memoryDumps[1]; - checkDumpTime(pmd2, 10003, 0); - assert.strictEqual(pmd2.globalMemoryDump, gmd2); - assert.strictEqual(pmd2.process, p1); - - var p2 = m.getProcess(68); - assert.lengthOf(p2.memoryDumps, 1); - var pmd3 = p2.memoryDumps[0]; - checkDumpTime(pmd3, 9999, 0); - assert.strictEqual(pmd3.globalMemoryDump, gmd1); - assert.strictEqual(pmd3.process, p2); - - assert.deepEqual(gmd1.processMemoryDumps, {42: pmd1, 68: pmd3}); - assert.deepEqual(gmd2.processMemoryDumps, {42: pmd2}); - - // Check the composed dump. - assert.strictEqual(pmd1.levelOfDetail, LIGHT); - - var totals = pmd1.totals; - assert.strictEqual(totals.residentBytes, 256); - assert.isUndefined(totals.peakResidentBytes); - assert.isUndefined(totals.arePeakResidentBytesResettable); - assert.deepEqual(totals.platformSpecific, {private_bytes: 128}); - - var vmRegions = pmd1.vmRegions; - checkVMRegions(vmRegions, [ - { - mappedFile: '[stack:20310]', - startAddress: 240, - sizeInBytes: 336, - protectionFlags: VMRegion.PROTECTION_FLAG_READ | - VMRegion.PROTECTION_FLAG_WRITE, - byteStats: { - proportionalResident: 158 - } - } - ]); - - var memoryAllocatorDumps = pmd1.memoryAllocatorDumps; - assert.lengthOf(memoryAllocatorDumps, 2); - - var local1Dump = pmd1.getMemoryAllocatorDumpByFullName('local1'); - assert.strictEqual(memoryAllocatorDumps[0], local1Dump); - assert.strictEqual(local1Dump.fullName, 'local1'); - assert.isUndefined(local1Dump.parent); - assert.lengthOf(local1Dump.children, 0); - checkDumpNumericsAndDiagnostics(local1Dump, {}, - { 'A': 'blue', 'B': 'red' }); - checkLinkCounts(local1Dump, true /* owns */, 0 /* owned by */, - 0 /* retains */, 0 /* retained by */); - - var local2Dump = pmd1.getMemoryAllocatorDumpByFullName('local2'); - assert.strictEqual(memoryAllocatorDumps[1], local2Dump); - assert.strictEqual(local2Dump.fullName, 'local2'); - assert.isUndefined(local2Dump.parent); - assert.lengthOf(local2Dump.children, 0); - checkDumpNumericsAndDiagnostics(local2Dump, {}, { 'B': 'yellow' }); - checkLinkCounts(local2Dump, false /* owns */, 0 /* owned by */, - 1 /* retains */, 0 /* retained by */); - - var heapDumps = pmd1.heapDumps; - assert.sameMembers(Object.keys(heapDumps), ['partition_alloc']); - var heapDump = heapDumps['partition_alloc']; - assert.strictEqual(heapDump.processMemoryDump, pmd1); - assert.strictEqual(heapDump.allocatorName, 'partition_alloc'); - var entries = heapDump.entries; - assert.lengthOf(entries, 1); - assert.strictEqual(entries[0].heapDump, heapDump); - assert.strictEqual(entries[0].leafStackFrame.title, 'MessageLoop::RunTask'); - assert.strictEqual(entries[0].objectTypeName, 'cc::SurfaceFactory'); - assert.strictEqual(entries[0].size, 1280); - - // Check the other dumps. - assert.strictEqual(pmd2.levelOfDetail, DETAILED); - assert.isUndefined(pmd2.vmRegions); - assert.lengthOf(pmd2.memoryAllocatorDumps, 1); - var otherLocal1Dump = pmd2.getMemoryAllocatorDumpByFullName('local1'); - assert.strictEqual(otherLocal1Dump, pmd2.memoryAllocatorDumps[0]); - assert.strictEqual(otherLocal1Dump.fullName, 'local1'); - assert.isUndefined(otherLocal1Dump.parent); - checkDumpNumericsAndDiagnostics(otherLocal1Dump, { 'A': 2989 }, {}); - assert.isUndefined(pmd2.heapDumps); - checkLinkCounts(otherLocal1Dump, false /* owns */, 1 /* owned by */, - 0 /* retains */, 0 /* retained by */); - - assert.strictEqual(pmd3.levelOfDetail, DETAILED); - var otherVmRegions = pmd3.vmRegions; - checkVMRegions(otherVmRegions, [ - { - mappedFile: '/dev/ashmem/dalvik', - startAddress: 848, - sizeInBytes: 592, - protectionFlags: VMRegion.PROTECTION_FLAG_READ | - VMRegion.PROTECTION_FLAG_EXECUTE, - byteStats: { - privateDirtyResident: 205 - } - } - ]); - assert.lengthOf(pmd3.memoryAllocatorDumps, 0); - assert.isUndefined(pmd3.heapDumps); - - // Check the global dumps. - assert.lengthOf(gmd1.memoryAllocatorDumps, 2); - var shared1Dump = gmd1.getMemoryAllocatorDumpByFullName('shared1'); - assert.strictEqual(shared1Dump, gmd1.memoryAllocatorDumps[0]); - assert.strictEqual(shared1Dump.fullName, 'shared1'); - assert.isUndefined(shared1Dump.parent); - checkDumpNumericsAndDiagnostics(shared1Dump, {}, - { 'A': 'purple', 'B': 'green' }); - checkLinkCounts(shared1Dump, false /* owns */, 1 /* owned by */, - 0 /* retains */, 0 /* retained by */); - var shared2Dump = gmd1.getMemoryAllocatorDumpByFullName('shared2'); - assert.strictEqual(shared2Dump, gmd1.memoryAllocatorDumps[1]); - assert.strictEqual(shared2Dump.fullName, 'shared2'); - assert.isUndefined(shared2Dump.parent); - checkDumpNumericsAndDiagnostics(shared2Dump, {}, { 'A': 'cyan' }); - checkLinkCounts(shared2Dump, false /* owns */, 0 /* owned by */, - 0 /* retains */, 1 /* retained by */); - - assert.lengthOf(gmd2.memoryAllocatorDumps, 1); - var otherShared1Dump = gmd2.getMemoryAllocatorDumpByFullName('shared1'); - assert.strictEqual(otherShared1Dump, gmd2.memoryAllocatorDumps[0]); - assert.strictEqual(otherShared1Dump.fullName, 'shared1'); - assert.isUndefined(otherShared1Dump.parent); - checkDumpNumericsAndDiagnostics(otherShared1Dump, {}, { 'A': 'brown' }); - checkLinkCounts(otherShared1Dump, true /* owns */, 0 /* owned by */, - 0 /* retains */, 0 /* retained by */); - - // Check the edges. - var ownershipLink = local1Dump.owns; - assert.strictEqual(shared1Dump.ownedBy[0], ownershipLink); - assert.strictEqual(ownershipLink.source, local1Dump); - assert.strictEqual(ownershipLink.target, shared1Dump); - assert.strictEqual(ownershipLink.importance, 1); - - var retentionLink = local2Dump.retains[0]; - assert.strictEqual(shared2Dump.retainedBy[0], retentionLink); - assert.strictEqual(retentionLink.source, local2Dump); - assert.strictEqual(retentionLink.target, shared2Dump); - assert.isUndefined(retentionLink.importance); - - var otherOwnershipLink = otherShared1Dump.owns; - assert.strictEqual(otherLocal1Dump.ownedBy[0], otherOwnershipLink); - assert.strictEqual(otherOwnershipLink.source, otherShared1Dump); - assert.strictEqual(otherOwnershipLink.target, otherLocal1Dump); - assert.isUndefined(otherOwnershipLink.importance); - }); - - test('importThreadInstantSliceWithStackFrame', function() { - var eventData = { - traceEvents: [ - { name: 'a', args: {}, pid: 1, ts: 0, cat: 'baz', tid: 2, ph: 'I', s: 't', sf: 7 } // @suppress longLineCheck - ], - stackFrames: { - '1': { - category: 'm1', - name: 'main' - }, - '7': { - category: 'm2', - name: 'frame7', - parent: '1' - } - } - }; - - var m = makeModel(eventData); - - var p = m.processes[1]; - var t = p.threads[2]; - assert.isDefined(t); - assert.equal(t.sliceGroup.slices.length, 1); - - var s0 = t.sliceGroup.slices[0]; - assert.equal(s0.startStackFrame.title, 'frame7'); - assert.isUndefined(s0.endStackFrame); - }); - - test('importDurationEventsWithStackFrames', function() { - var eventData = { - traceEvents: [ - { name: 'a', args: {}, pid: 1, ts: 0, cat: 'baz', tid: 2, ph: 'B', sf: 7 }, // @suppress longLineCheck - { name: 'b', args: {}, pid: 1, ts: 5, cat: 'baz', tid: 2, ph: 'E', sf: 8 } // @suppress longLineCheck - ], - stackFrames: { - '1': { - category: 'm1', - name: 'main' - }, - '7': { - category: 'm2', - name: 'frame7', - parent: '1' - }, - '8': { - category: 'm2', - name: 'frame8', - parent: '1' - } - } - }; - - var m = makeModel(eventData); - - var p = m.processes[1]; - var t = p.threads[2]; - assert.isDefined(t); - assert.equal(t.sliceGroup.slices.length, 1); - - var s0 = t.sliceGroup.slices[0]; - assert.equal(s0.startStackFrame.title, 'frame7'); - assert.equal(s0.endStackFrame.title, 'frame8'); - }); - - test('annotationParsing', function() { - var yComponents1 = [{stableId: '52.53', yPercentOffset: 0.5}, - {stableId: '52', yPercentOffset: 0.3}]; - var yComponents2 = [{stableId: '52.53', yPercentOffset: 0.7}, - {stableId: '52', yPercentOffset: 0.4}]; - var location1 = new tr.model.Location(0.1, yComponents1); - var location2 = new tr.model.Location(0.2, yComponents2); - - var eventData = { traceEvents: [ - {name: 'a', args: {}, pid: 52, ts: 524, cat: 'foo', tid: 53, ph: 'B'}], - traceAnnotations: [ - {typeName: 'xmarker', args: {timestamp: 12}}, - {typeName: 'rect', args: { - start: location1.toDict(), end: location2.toDict()}}, - {typeName: 'comment_box', args: {text: 'test', - location: location1.toDict()}} - ]}; - - var m = makeModel(eventData); - var annotations = m.getAllAnnotations(); - assert.equal(annotations.length, 3); - - assert.isTrue(annotations[0] instanceof tr.model.XMarkerAnnotation); - assert.equal(annotations[0].timestamp, 12); - - assert.isTrue(annotations[1] instanceof tr.model.RectAnnotation); - assert.deepEqual(annotations[1].startLocation, location1); - assert.deepEqual(annotations[1].endLocation, location2); - - assert.isTrue( - annotations[2] instanceof tr.model.CommentBoxAnnotation); - assert.equal(annotations[2].text, 'test'); - assert.deepEqual(annotations[2].location, location1); - }); - - test('importDisplayTimeUnit', function() { - var eventData = { - traceEvents: [], - displayTimeUnit: 'ns' - }; - var m = makeModel(JSON.stringify(eventData)); - assert.equal(m.intrinsicTimeUnit, tr.v.TimeDisplayModes.ns); - }); - - test('extractBattorSubTraces', function() { - var battorLog = '# BattOr\n# voltage range [0.000000, 7196.484161] mV\n' + - '#current range [11.898481, 2110.900916] mA\n' + - '# sample_rate=10000Hz, gain=30.257143x\n' + - '# filpot_pos=3, amppot_pos=35, timer_ovf=399, timer_div=4 ovs_bits=0\n' + // @suppress longLineCheck - '0.0 1040.3 3984.2\n' + - '0.1 1081.3 3987.8\n' + - '0.2 1092.6 3987.8\n' + - '0.3 1070.0 3987.8\n' + - '0.4 1017.7 3994.8\n'; - - var eventData = { - traceEvents: [ - { name: 'a', args: {}, pid: 1, ts: 0, cat: 'baz', tid: 2, ph: 'B', sf: 7 }, // @suppress longLineCheck - { name: 'b', args: {}, pid: 1, ts: 5, cat: 'baz', tid: 2, ph: 'E', sf: 8 } // @suppress longLineCheck - ], - powerTraceAsString: battorLog - }; - - var m = makeModel(eventData); - var importer = new tr.e.importer.TraceEventImporter(m, eventData); - var subTraces = importer.extractSubtraces(); - assert.isTrue(subTraces instanceof Array); - assert.equal(subTraces.length, 1); - assert.equal(subTraces[0], battorLog); - }); - - test('metadataParsing', function() { - var metadataValue = {value: {}}; - var eventData = { - traceEvents: [ - { name: 'a', args: {}, pid: 1, ts: 0, cat: 'baz', tid: 2, ph: 'B', sf: 7 }, // @suppress longLineCheck - { name: 'b', args: {}, pid: 1, ts: 5, cat: 'baz', tid: 2, ph: 'E', sf: 8 } // @suppress longLineCheck - ], - metadata: metadataValue - }; - - var m = makeModel(eventData); - assert.isTrue(m.metadata instanceof Array); - assert.equal(m.metadata.length, 1); - assert.equal(m.metadata[0].name, 'metadata'); - assert.equal(m.metadata[0].value, metadataValue); - }); - - test('importTraceConfigAsMetadata', function() { - var traceConfigData = { - enable_argument_filter: false, - enable_sampling: false, - enable_systrace: false, - record_mode: 'record-until-full' - }; - - var eventData = { - traceEvents: [ - { name: 'TraceConfig', args: { value: traceConfigData }, - pid: 2, ts: 0, tid: 1, ph: 'M', cat: '__metadata' }, - ], - }; - - var m = makeModel(eventData); - assert.isTrue(m.metadata instanceof Array); - assert.equal(m.metadata.length, 1); - assert.equal(m.metadata[0].name, 'TraceConfig'); - assert.equal(m.metadata[0].value, traceConfigData); - }); - - test('importMarks', function() { - var eventData = { - traceEvents: [ - { name: 'mark1', args: {}, pid: 1, tid: 2, ts: 0, tts: 0, cat: 'blink.user_timing', ph: 'R' }, // @suppress longLineCheck - { name: 'mark2', args: {}, pid: 1, tid: 2, ts: 10, tts: 10, cat: 'blink.user_timing', ph: 'R' } // @suppress longLineCheck - ] - }; - - var m = makeModel(eventData); - - var p = m.processes[1]; - var t = p.threads[2]; - assert.lengthOf(t.sliceGroup.slices, 2); - - var s0 = t.sliceGroup.slices[0]; - assert.equal(s0.title, 'mark1'); - assert.equal(s0.start, 0); - - var s1 = t.sliceGroup.slices[1]; - assert.equal(s1.title, 'mark2'); - assert.equal(s1.start, .01); - }); - - test('createNestableAsyncSlicesForUserTimingWithoutArgs', function() { - /** - * Structure of this async slices - * - * Group A: - * - * |__________| - * a1 - * - * Group B: - * - * |______________________________| - * b1 - * |__________||_| - * b2 b4 - * |_| - * b3 - **/ - var events = [ - { - name: 'A:a1', - args: {params: ''}, - pid: 1, - ts: 100, - cat: 'blink.user_timing', - tid: 2, - id: 3, - ph: 'b' - }, - { - name: 'A:a1', - args: {params: ''}, - pid: 1, - ts: 110, - cat: 'blink.user_timing', - tid: 2, - id: 3, - ph: 'e' - }, - { - name: 'B:b1', - args: {params: ''}, - pid: 1, - ts: 120, - cat: 'blink.user_timing', - tid: 2, - id: 4, - ph: 'b' - }, - { - name: 'B:b2', - args: {params: ''}, - pid: 1, - ts: 130, - cat: 'blink.user_timing', - tid: 2, - id: 5, - ph: 'b' - }, - { - name: 'B:b3', - args: {params: ''}, - pid: 1, - ts: 131, - cat: 'blink.user_timing', - tid: 2, - id: 5, - ph: 'b' - }, - { - name: 'B:b3', - args: {params: ''}, - pid: 1, - ts: 132, - cat: 'blink.user_timing', - tid: 2, - id: 5, - ph: 'e' - }, - { - name: 'B:b2', - args: {params: ''}, - pid: 1, - ts: 140, - cat: 'blink.user_timing', - tid: 2, - id: 5, - ph: 'e' - }, - { - name: 'B:b4', - args: {params: ''}, - pid: 1, - ts: 141, - cat: 'blink.user_timing', - tid: 2, - id: 5, - ph: 'b' - }, - { - name: 'B:b4', - args: {params: ''}, - pid: 1, - ts: 142, - cat: 'blink.user_timing', - tid: 2, - id: 5, - ph: 'e' - }, - { - name: 'B:b1', - args: {params: ''}, - pid: 1, - ts: 150, - cat: 'blink.user_timing', - tid: 2, - id: 4, - ph: 'e' - } - ]; - - var m = makeModel(events); - assert(m.numProcesses, 1); - var p = m.processes[1]; - assert.isDefined(p); - assert.equal(p.numThreads, 1); - var t = p.threads[2]; - var asyncSliceGroup = t.asyncSliceGroup; - assert.equal(asyncSliceGroup.length, 2); - for (var i = 0; i < asyncSliceGroup.length; ++i) { - assert.isTrue(asyncSliceGroup.slices[i] instanceof MeasureAsyncSlice); - } - - var groupA = asyncSliceGroup.slices[0]; - assert.equal(groupA.viewSubGroupTitle, 'A'); - assert.equal(groupA.title, 'a1'); - assert.equal(groupA.subSlices.length, 0); - var groupB = asyncSliceGroup.slices[1]; - assert.equal(groupB.viewSubGroupTitle, 'B'); - assert.equal(groupB.title, 'b1'); - assert.equal(groupB.subSlices.length, 2); - var groupBSubSlice1 = groupB.subSlices[0]; - assert.equal(groupBSubSlice1.viewSubGroupTitle, 'B'); - assert.equal(groupBSubSlice1.title, 'b2'); - assert.equal(groupBSubSlice1.subSlices.length, 1); - assert.equal(groupBSubSlice1.subSlices[0].viewSubGroupTitle, 'B'); - assert.equal(groupBSubSlice1.subSlices[0].title, 'b3'); - assert.equal(groupBSubSlice1.subSlices[0].subSlices.length, 0); - var groupBSubSlice2 = groupB.subSlices[1]; - assert.equal(groupBSubSlice2.viewSubGroupTitle, 'B'); - assert.equal(groupBSubSlice2.title, 'b4'); - assert.equal(groupBSubSlice2.subSlices.length, 0); - }); - - test('createNestableAsyncSlicesForUserTimingWithArgs', function() { - /** - * Structure of this async slices - * - * Group A: - * - * |__________| |__________| - * a1 a2 - * - * a1.args = {a: 1} - * a2.args = {a: 2, b: 2} - **/ - var events = [ - { - name: 'A:a1/eyJhIjoxfQ==', - args: {params: ''}, - pid: 1, - ts: 100, - cat: 'blink.user_timing', - tid: 2, - id: 3, - ph: 'b' - }, - { - name: 'A:a1/eyJhIjoxfQ==', - args: {params: ''}, - pid: 1, - ts: 110, - cat: 'blink.user_timing', - tid: 2, - id: 3, - ph: 'e' - }, - { - name: 'A:a2/eyJhIjoyLCJiIjoyfQ==', - args: {params: ''}, - pid: 1, - ts: 120, - cat: 'blink.user_timing', - tid: 2, - id: 4, - ph: 'b' - }, - { - name: 'A:a2/eyJhIjoyLCJiIjoyfQ==', - args: {params: ''}, - pid: 1, - ts: 130, - cat: 'blink.user_timing', - tid: 2, - id: 4, - ph: 'e' - } - ]; - - var m = makeModel(events); - assert(m.numProcesses, 1); - var p = m.processes[1]; - assert.isDefined(p); - assert.equal(p.numThreads, 1); - var t = p.threads[2]; - var asyncSliceGroup = t.asyncSliceGroup; - assert.equal(asyncSliceGroup.length, 2); - for (var i = 0; i < asyncSliceGroup.length; ++i) { - assert.isTrue(asyncSliceGroup.slices[i] instanceof MeasureAsyncSlice); - } - - var a1 = asyncSliceGroup.slices[0]; - assert.equal(a1.viewSubGroupTitle, 'A'); - assert.equal(a1.title, 'a1'); - assert.equal(a1.subSlices.length, 0); - assert.deepEqual(a1.args, {a: 1}); - var a2 = asyncSliceGroup.slices[1]; - assert.equal(a2.viewSubGroupTitle, 'A'); - assert.equal(a2.title, 'a2'); - assert.equal(a2.subSlices.length, 0); - assert.deepEqual(a2.args, {a: 2, b: 2}); - }); - - test('UserTimingAsyncSlicesWithNormalAsyncSlices', function() { - /** - * Structure of user timing async slices - * - * Group A: - * - * |__________| - * a1 - * |__| - * a2 - * - * B - * |__| - * B - * C - * |_| - * C - **/ - var events = [ - { - name: 'A:a1', args: {params: ''}, pid: 1, ts: 1, - cat: 'blink.user_timing', tid: 2, id: 3, ph: 'b' - }, - { - name: 'A:a1', args: {params: ''}, pid: 1, ts: 11, - cat: 'blink.user_timing', tid: 2, id: 3, ph: 'e' - }, - { - name: 'A:a2', args: {params: ''}, pid: 1, ts: 2, - cat: 'blink.user_timing', tid: 2, id: 4, ph: 'b' - }, - { - name: 'A:a2', args: {params: ''}, pid: 1, ts: 4, - cat: 'blink.user_timing', tid: 2, id: 4, ph: 'e' - }, - { - name: 'B', args: {}, pid: 1, ts: 9, cat: 'foo', - tid: 2, ph: 'b', id: 5 - }, - { - name: 'B', args: {}, pid: 1, ts: 11, cat: 'foo', - tid: 2, ph: 'e', id: 5 - }, - { - name: 'C', args: {}, pid: 1, ts: 12, cat: 'foo', - tid: 2, ph: 'b', id: 6 - }, - { - name: 'C', args: {}, pid: 1, ts: 13, cat: 'foo', - tid: 2, ph: 'e', id: 6 - } - ]; - - var m = makeModel(events); - assert(m.numProcesses, 1); - var p = m.processes[1]; - assert.isDefined(p); - assert.equal(p.numThreads, 1); - var t = p.threads[2]; - var asyncSliceGroup = t.asyncSliceGroup; - assert.equal(asyncSliceGroup.length, 3); - assert.isTrue(asyncSliceGroup.slices[0] instanceof MeasureAsyncSlice); - assert.isFalse(asyncSliceGroup.slices[1] instanceof MeasureAsyncSlice); - assert.isFalse(asyncSliceGroup.slices[2] instanceof MeasureAsyncSlice); - - var a1 = asyncSliceGroup.slices[0]; - assert.equal(a1.viewSubGroupTitle, 'A'); - assert.equal(a1.title, 'a1'); - assert.equal(a1.subSlices.length, 1); - var a2 = a1.subSlices[0]; - assert.equal(a2.viewSubGroupTitle, 'A'); - assert.equal(a2.title, 'a2'); - assert.equal(a2.subSlices.length, 0); - var B = asyncSliceGroup.slices[1]; - assert.equal(B.viewSubGroupTitle, 'B'); - assert.equal(B.title, 'B'); - assert.equal(B.subSlices.length, 0); - var C = asyncSliceGroup.slices[2]; - assert.equal(C.viewSubGroupTitle, 'C'); - assert.equal(C.title, 'C'); - assert.equal(C.subSlices.length, 0); - }); - - test('clockSync_requesterWithoutMetadata', function() { - var events = [{ - name: 'clock_sync', args: {sync_id: 'abc', issue_ts: 5000}, - pid: 1, ts: 15000, cat: '__metadata', tid: 2, ph: 'c' - }]; - - var io = new tr.importer.ImportOptions(); - var m = new tr.Model(); - var i = new tr.importer.Import(m, io); - - m.clockSyncManager.addClockSyncMarker( - ClockDomainId.LINUX_FTRACE_GLOBAL, 'abc', 15); - - i.importTraces([events]); - - // The clock sync happened in UNKNOWN_CHROME_LEGACY at 10ms and in - // LINUX_FTRACE_GLOBAL at 15ms. The transformer should shift the ftrace - // timestamps back by 5ms. - assert.strictEqual( - m.clockSyncManager.getModelTimeTransformer( - ClockDomainId.UNKNOWN_CHROME_LEGACY)(5), - 5); - assert.strictEqual( - m.clockSyncManager.getModelTimeTransformer( - ClockDomainId.LINUX_FTRACE_GLOBAL)(15), - 10); - assert.isFalse(m.hasImportWarnings); - }); - - test('clockSync_requesterWithMetadata', function() { - var events = { - traceEvents: [{ - name: 'clock_sync', args: {sync_id: 'abc', issue_ts: 5}, - pid: 1, ts: 15, cat: '__metadata', tid: 2, ph: 'c' - }], - metadata: { - 'clock-domain': ClockDomainId.BATTOR - } - }; - - var m = makeModel(events); - - // Make sure that our clock domain was chosen as the model. - assert.equal( - m.clockSyncManager.getModelTimeTransformer(ClockDomainId.BATTOR)(.005), - .005); - assert.isFalse(m.hasImportWarnings); - }); - - test('clockSync_recipient', function() { - var events = { - traceEvents: [{ - name: 'clock_sync', args: {sync_id: 'abc'}, pid: 1, ts: 15000, - cat: '__metadata', tid: 2, ph: 'c' - }], - metadata: { - 'clock-domain': ClockDomainId.TELEMETRY - } - }; - - var m = makeModel(events); - - m.clockSyncManager.addClockSyncMarker( - ClockDomainId.LINUX_CLOCK_MONOTONIC, 'abc', 10); - - assert.equal( - m.clockSyncManager.getModelTimeTransformer( - ClockDomainId.TELEMETRY)(15), - 10); - assert.equal( - m.clockSyncManager.getModelTimeTransformer( - ClockDomainId.LINUX_CLOCK_MONOTONIC)(10), - 10); - }); - - test('clockSync_missingSyncId', function() { - var events = [{ - name: 'clock_sync', args: {issue_ts: 5}, - pid: 1, ts: 15, cat: '__metadata', tid: 2, ph: 'c' - }]; - - var m = makeModel(events); - - assert.isTrue(m.hasImportWarnings); - }); - - // TODO(nduca): one slice, two threads - // TODO(nduca): one slice, two pids - -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/codemap.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/codemap.html deleted file mode 100644 index b7d80554373..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/codemap.html +++ /dev/null @@ -1,382 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/extras/importer/v8/splaytree.html"> - -<script> -'use strict'; - -/** - * @fileoverview Map addresses to dynamically created functions. - */ -tr.exportTo('tr.e.importer.v8', function() { - /** - * Constructs a mapper that maps addresses into code entries. - * - * @constructor - */ - function CodeMap() { - /** - * Dynamic code entries. Used for JIT compiled code. - */ - this.dynamics_ = new tr.e.importer.v8.SplayTree(); - - /** - * Name generator for entries having duplicate names. - */ - this.dynamicsNameGen_ = new tr.e.importer.v8.CodeMap.NameGenerator(); - - /** - * Static code entries. Used for statically compiled code. - */ - this.statics_ = new tr.e.importer.v8.SplayTree(); - - /** - * Libraries entries. Used for the whole static code libraries. - */ - this.libraries_ = new tr.e.importer.v8.SplayTree(); - - /** - * Map of memory pages occupied with static code. - */ - this.pages_ = []; - }; - - /** - * The number of alignment bits in a page address. - */ - CodeMap.PAGE_ALIGNMENT = 12; - - /** - * Page size in bytes. - */ - CodeMap.PAGE_SIZE = 1 << CodeMap.PAGE_ALIGNMENT; - - /** - * Adds a dynamic (i.e. moveable and discardable) code entry. - * - * @param {number} start The starting address. - * @param {CodeMap.CodeEntry} codeEntry Code entry object. - */ - CodeMap.prototype.addCode = function(start, codeEntry) { - this.deleteAllCoveredNodes_(this.dynamics_, start, start + codeEntry.size); - this.dynamics_.insert(start, codeEntry); - }; - - /** - * Moves a dynamic code entry. Throws an exception if there is no dynamic - * code entry with the specified starting address. - * - * @param {number} from The starting address of the entry being moved. - * @param {number} to The destination address. - */ - CodeMap.prototype.moveCode = function(from, to) { - var removedNode = this.dynamics_.remove(from); - this.deleteAllCoveredNodes_(this.dynamics_, to, - to + removedNode.value.size); - this.dynamics_.insert(to, removedNode.value); - }; - - /** - * Discards a dynamic code entry. Throws an exception if there is no dynamic - * code entry with the specified starting address. - * - * @param {number} start The starting address of the entry being deleted. - */ - CodeMap.prototype.deleteCode = function(start) { - var removedNode = this.dynamics_.remove(start); - }; - - /** - * Adds a library entry. - * - * @param {number} start The starting address. - * @param {CodeMap.CodeEntry} codeEntry Code entry object. - */ - CodeMap.prototype.addLibrary = function( - start, codeEntry) { - this.markPages_(start, start + codeEntry.size); - this.libraries_.insert(start, codeEntry); - }; - - /** - * Adds a static code entry. - * - * @param {number} start The starting address. - * @param {CodeMap.CodeEntry} codeEntry Code entry object. - */ - CodeMap.prototype.addStaticCode = function( - start, codeEntry) { - this.statics_.insert(start, codeEntry); - }; - - /** - * @private - */ - CodeMap.prototype.markPages_ = function(start, end) { - for (var addr = start; addr <= end; - addr += CodeMap.PAGE_SIZE) { - this.pages_[addr >>> CodeMap.PAGE_ALIGNMENT] = 1; - } - }; - - /** - * @private - */ - CodeMap.prototype.deleteAllCoveredNodes_ = function(tree, start, end) { - var to_delete = []; - var addr = end - 1; - while (addr >= start) { - var node = tree.findGreatestLessThan(addr); - if (!node) break; - var start2 = node.key, end2 = start2 + node.value.size; - if (start2 < end && start < end2) to_delete.push(start2); - addr = start2 - 1; - } - for (var i = 0, l = to_delete.length; i < l; ++i) tree.remove(to_delete[i]); - }; - - /** - * @private - */ - CodeMap.prototype.isAddressBelongsTo_ = function(addr, node) { - return addr >= node.key && addr < (node.key + node.value.size); - }; - - /** - * @private - */ - CodeMap.prototype.findInTree_ = function(tree, addr) { - var node = tree.findGreatestLessThan(addr); - return node && this.isAddressBelongsTo_(addr, node) ? node.value : null; - }; - - /** - * Finds a code entry that contains the specified address in static libraries. - * - * @param {number} addr Address. - */ - CodeMap.prototype.findEntryInLibraries = function(addr) { - var pageAddr = addr >>> CodeMap.PAGE_ALIGNMENT; - if (pageAddr in this.pages_) - return this.findInTree_(this.libraries_, addr); - return undefined; - }; - - /** - * Finds a code entry that contains the specified address. Both static and - * dynamic code entries are considered. - * - * @param {number} addr Address. - */ - CodeMap.prototype.findEntry = function(addr) { - var pageAddr = addr >>> CodeMap.PAGE_ALIGNMENT; - if (pageAddr in this.pages_) { - // Static code entries can contain "holes" of unnamed code. - // In this case, the whole library is assigned to this address. - return this.findInTree_(this.statics_, addr) || - this.findInTree_(this.libraries_, addr); - } - var min = this.dynamics_.findMin(); - var max = this.dynamics_.findMax(); - if (max != null && addr < (max.key + max.value.size) && addr >= min.key) { - var dynaEntry = this.findInTree_(this.dynamics_, addr); - if (dynaEntry == null) return null; - // Dedupe entry name. - if (!dynaEntry.nameUpdated_) { - dynaEntry.name = this.dynamicsNameGen_.getName(dynaEntry.name); - dynaEntry.nameUpdated_ = true; - } - return dynaEntry; - } - return null; - }; - - /** - * Returns a dynamic code entry using its starting address. - * - * @param {number} addr Address. - */ - CodeMap.prototype.findDynamicEntryByStartAddress = - function(addr) { - var node = this.dynamics_.find(addr); - return node ? node.value : null; - }; - - /** - * Returns an array of all dynamic code entries. - */ - CodeMap.prototype.getAllDynamicEntries = function() { - return this.dynamics_.exportValues(); - }; - - /** - * Returns an array of pairs of all dynamic code entries and their addresses. - */ - CodeMap.prototype.getAllDynamicEntriesWithAddresses = function() { - return this.dynamics_.exportKeysAndValues(); - }; - - /** - * Returns an array of all static code entries. - */ - CodeMap.prototype.getAllStaticEntries = function() { - return this.statics_.exportValues(); - }; - - /** - * Returns an array of all libraries entries. - */ - CodeMap.prototype.getAllLibrariesEntries = function() { - return this.libraries_.exportValues(); - }; - - /** - * Enum for code state regarding its dynamic optimization. - * - * @enum {number} - */ - CodeMap.CodeState = { - COMPILED: 0, - OPTIMIZABLE: 1, - OPTIMIZED: 2 - }; - - /** - * Creates a code entry object. - * - * @param {number} size Code entry size in bytes. - * @param {string=} opt_name Code entry name. - * @constructor - */ - CodeMap.CodeEntry = function(size, opt_name, opt_type) { - this.id = tr.b.GUID.allocateSimple(); - this.size = size; - this.name_ = opt_name || ''; - this.type = opt_type || ''; - this.nameUpdated_ = false; - }; - - CodeMap.CodeEntry.prototype = { - __proto__: Object.prototype, - - get name() { - return this.name_; - }, - - set name(value) { - this.name_ = value; - }, - - toString: function() { - this.name_ + ': ' + this.size.toString(16); - } - }; - - CodeMap.CodeEntry.TYPE = { - SHARED_LIB: 'SHARED_LIB', - CPP: 'CPP' - }; - - /** - * Creates a dynamic code entry. - * - * @param {number} size Code size. - * @param {string} type Code type. - * @param {CodeMap.FunctionEntry} func Shared function entry. - * @param {CodeMap.CodeState} state Code optimization state. - * @constructor - */ - CodeMap.DynamicFuncCodeEntry = function(size, type, func, state) { - CodeMap.CodeEntry.call(this, size, '', type); - this.func = func; - this.state = state; - }; - - CodeMap.DynamicFuncCodeEntry.STATE_PREFIX = ['', '~', '*']; - - CodeMap.DynamicFuncCodeEntry.prototype = { - __proto__: CodeMap.CodeEntry.prototype, - - /** - * Returns node name. - */ - get name() { - return CodeMap.DynamicFuncCodeEntry.STATE_PREFIX[this.state] + - this.func.name; - }, - - set name(value) { - this.name_ = value; - }, - - /** - * Returns raw node name (without type decoration). - */ - getRawName: function() { - return this.func.getName(); - }, - - isJSFunction: function() { - return true; - }, - - toString: function() { - return this.type + ': ' + this.name + ': ' + this.size.toString(16); - } - }; - - /** - * Creates a shared function object entry. - * - * @param {string} name Function name. - * @constructor - */ - CodeMap.FunctionEntry = function(name) { - CodeMap.CodeEntry.call(this, 0, name); - }; - - CodeMap.FunctionEntry.prototype = { - __proto__: CodeMap.CodeEntry.prototype, - - /** - * Returns node name. - */ - get name() { - var name = this.name_; - if (name.length == 0) { - name = '<anonymous>'; - } else if (name.charAt(0) == ' ') { - // An anonymous function with location: " aaa.js:10". - name = '<anonymous>' + name; - } - return name; - }, - - set name(value) { - this.name_ = value; - } - }; - - CodeMap.NameGenerator = function() { - this.knownNames_ = {}; - }; - - CodeMap.NameGenerator.prototype.getName = function(name) { - if (!(name in this.knownNames_)) { - this.knownNames_[name] = 0; - return name; - } - var count = ++this.knownNames_[name]; - return name + ' {' + count + '}'; - }; - return { - CodeMap: CodeMap - }; -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/log_reader.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/log_reader.html deleted file mode 100644 index 9b10ab69b96..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/log_reader.html +++ /dev/null @@ -1,213 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/base/base.html"> -<script> -'use strict'; - -/** - * @fileoverview Log Reader is used to process log file produced by V8. - */ -tr.exportTo('tr.e.importer.v8', function() { - /** - * Creates a CSV lines parser. - */ - function CsvParser() { }; - - /** - * A regex for matching a CSV field. - * @private - */ - CsvParser.CSV_FIELD_RE_ = /^"((?:[^"]|"")*)"|([^,]*)/; - - /** - * A regex for matching a double quote. - * @private - */ - CsvParser.DOUBLE_QUOTE_RE_ = /""/g; - - /** - * Parses a line of CSV-encoded values. Returns an array of fields. - * - * @param {string} line Input line. - */ - CsvParser.prototype.parseLine = function(line) { - var fieldRe = CsvParser.CSV_FIELD_RE_; - var doubleQuoteRe = CsvParser.DOUBLE_QUOTE_RE_; - var pos = 0; - var endPos = line.length; - var fields = []; - if (endPos > 0) { - do { - var fieldMatch = fieldRe.exec(line.substr(pos)); - if (typeof fieldMatch[1] === 'string') { - var field = fieldMatch[1]; - pos += field.length + 3; // Skip comma and quotes. - fields.push(field.replace(doubleQuoteRe, '"')); - } else { - // The second field pattern will match anything, thus - // in the worst case the match will be an empty string. - var field = fieldMatch[2]; - pos += field.length + 1; // Skip comma. - fields.push(field); - } - } while (pos <= endPos); - } - return fields; - }; - - /** - * Base class for processing log files. - * - * @param {Array.<Object>} dispatchTable A table used for parsing and - * processing log records. - * - * @constructor - */ - function LogReader(dispatchTable) { - /** - * @type {Array.<Object>} - */ - this.dispatchTable_ = dispatchTable; - - /** - * Current line. - * @type {number} - */ - this.lineNum_ = 0; - - /** - * CSV lines parser. - * @type {CsvParser} - */ - this.csvParser_ = new CsvParser(); - }; - - /** - * Used for printing error messages. - * - * @param {string} str Error message. - */ - LogReader.prototype.printError = function(str) { - // Do nothing. - }; - - /** - * Processes a portion of V8 profiler event log. - * - * @param {string} chunk A portion of log. - */ - LogReader.prototype.processLogChunk = function(chunk) { - this.processLog_(chunk.split('\n')); - }; - - /** - * Processes a line of V8 profiler event log. - * - * @param {string} line A line of log. - */ - LogReader.prototype.processLogLine = function(line) { - this.processLog_([line]); - }; - - /** - * Processes stack record. - * - * @param {number} pc Program counter. - * @param {number} func JS Function. - * @param {Array.<string>} stack String representation of a stack. - * @return {Array.<number>} Processed stack. - */ - LogReader.prototype.processStack = function(pc, func, stack) { - var fullStack = func ? [pc, func] : [pc]; - var prevFrame = pc; - for (var i = 0, n = stack.length; i < n; ++i) { - var frame = stack[i]; - var firstChar = frame.charAt(0); - if (firstChar == '+' || firstChar == '-') { - // An offset from the previous frame. - prevFrame += parseInt(frame, 16); - fullStack.push(prevFrame); - // Filter out possible 'overflow' string. - } else if (firstChar != 'o') { - fullStack.push(parseInt(frame, 16)); - } - } - return fullStack; - }; - - /** - * Returns whether a particular dispatch must be skipped. - * - * @param {!Object} dispatch Dispatch record. - * @return {boolean} True if dispatch must be skipped. - */ - LogReader.prototype.skipDispatch = function(dispatch) { - return false; - }; - - /** - * Does a dispatch of a log record. - * - * @param {Array.<string>} fields Log record. - * @private - */ - LogReader.prototype.dispatchLogRow_ = function(fields) { - // Obtain the dispatch. - var command = fields[0]; - if (!(command in this.dispatchTable_)) return; - - var dispatch = this.dispatchTable_[command]; - - if (dispatch === null || this.skipDispatch(dispatch)) { - return; - } - - // Parse fields. - var parsedFields = []; - for (var i = 0; i < dispatch.parsers.length; ++i) { - var parser = dispatch.parsers[i]; - if (parser === null) { - parsedFields.push(fields[1 + i]); - } else if (typeof parser == 'function') { - parsedFields.push(parser(fields[1 + i])); - } else { - // var-args - parsedFields.push(fields.slice(1 + i)); - break; - } - } - - // Run the processor. - dispatch.processor.apply(this, parsedFields); - }; - - /** - * Processes log lines. - * - * @param {Array.<string>} lines Log lines. - * @private - */ - LogReader.prototype.processLog_ = function(lines) { - for (var i = 0, n = lines.length; i < n; ++i, ++this.lineNum_) { - var line = lines[i]; - if (!line) { - continue; - } - try { - var fields = this.csvParser_.parseLine(line); - this.dispatchLogRow_(fields); - } catch (e) { - this.printError('line ' + (this.lineNum_ + 1) + ': ' + - (e.message || e)); - } - } - }; - return { - LogReader: LogReader - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/splaytree.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/splaytree.html deleted file mode 100644 index 05f803765db..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/splaytree.html +++ /dev/null @@ -1,306 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2012 The Chromium Authors. All rights reserved. -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/base/base.html"> -<script> -'use strict'; - -/** - * @fileoverview Splay tree used by CodeMap. - */ -tr.exportTo('tr.e.importer.v8', function() { - /** - * Constructs a Splay tree. A splay tree is a self-balancing binary - * search tree with the additional property that recently accessed - * elements are quick to access again. It performs basic operations - * such as insertion, look-up and removal in O(log(n)) amortized time. - * - * @constructor - */ - function SplayTree() { }; - - /** - * Pointer to the root node of the tree. - * - * @type {SplayTree.Node} - * @private - */ - SplayTree.prototype.root_ = null; - - /** - * @return {boolean} Whether the tree is empty. - */ - SplayTree.prototype.isEmpty = function() { - return !this.root_; - }; - - /** - * Inserts a node into the tree with the specified key and value if - * the tree does not already contain a node with the specified key. If - * the value is inserted, it becomes the root of the tree. - * - * @param {number} key Key to insert into the tree. - * @param {*} value Value to insert into the tree. - */ - SplayTree.prototype.insert = function(key, value) { - if (this.isEmpty()) { - this.root_ = new SplayTree.Node(key, value); - return; - } - // Splay on the key to move the last node on the search path for - // the key to the root of the tree. - this.splay_(key); - if (this.root_.key == key) { - return; - } - var node = new SplayTree.Node(key, value); - if (key > this.root_.key) { - node.left = this.root_; - node.right = this.root_.right; - this.root_.right = null; - } else { - node.right = this.root_; - node.left = this.root_.left; - this.root_.left = null; - } - this.root_ = node; - }; - - - /** - * Removes a node with the specified key from the tree if the tree - * contains a node with this key. The removed node is returned. If the - * key is not found, an exception is thrown. - * - * @param {number} key Key to find and remove from the tree. - * @return {SplayTree.Node} The removed node. - */ - SplayTree.prototype.remove = function(key) { - if (this.isEmpty()) { - throw Error('Key not found: ' + key); - } - this.splay_(key); - if (this.root_.key != key) { - throw Error('Key not found: ' + key); - } - var removed = this.root_; - if (!this.root_.left) { - this.root_ = this.root_.right; - } else { - var right = this.root_.right; - this.root_ = this.root_.left; - // Splay to make sure that the new root has an empty right child. - this.splay_(key); - // Insert the original right child as the right child of the new - // root. - this.root_.right = right; - } - return removed; - }; - - - /** - * Returns the node having the specified key or null if the tree doesn't - * contain a node with the specified key. - * - * - * @param {number} key Key to find in the tree. - * @return {SplayTree.Node} Node having the specified key. - */ - SplayTree.prototype.find = function(key) { - if (this.isEmpty()) { - return null; - } - this.splay_(key); - return this.root_.key == key ? this.root_ : null; - }; - - /** - * @return {SplayTree.Node} Node having the minimum key value. - */ - SplayTree.prototype.findMin = function() { - if (this.isEmpty()) { - return null; - } - var current = this.root_; - while (current.left) { - current = current.left; - } - return current; - }; - - /** - * @return {SplayTree.Node} Node having the maximum key value. - */ - SplayTree.prototype.findMax = function(opt_startNode) { - if (this.isEmpty()) { - return null; - } - var current = opt_startNode || this.root_; - while (current.right) { - current = current.right; - } - return current; - }; - - /** - * @return {SplayTree.Node} Node having the maximum key value that - * is less or equal to the specified key value. - */ - SplayTree.prototype.findGreatestLessThan = function(key) { - if (this.isEmpty()) { - return null; - } - // Splay on the key to move the node with the given key or the last - // node on the search path to the top of the tree. - this.splay_(key); - // Now the result is either the root node or the greatest node in - // the left subtree. - if (this.root_.key <= key) { - return this.root_; - } else if (this.root_.left) { - return this.findMax(this.root_.left); - } else { - return null; - } - }; - - /** - * @return {Array<*>} An array containing all the values of tree's nodes - * paired with keys. - * - */ - SplayTree.prototype.exportKeysAndValues = function() { - var result = []; - this.traverse_(function(node) { result.push([node.key, node.value]); }); - return result; - }; - - /** - * @return {Array<*>} An array containing all the values of tree's nodes. - */ - SplayTree.prototype.exportValues = function() { - var result = []; - this.traverse_(function(node) { result.push(node.value); }); - return result; - }; - - /** - * Perform the splay operation for the given key. Moves the node with - * the given key to the top of the tree. If no node has the given - * key, the last node on the search path is moved to the top of the - * tree. This is the simplified top-down splaying algorithm from: - * "Self-adjusting Binary Search Trees" by Sleator and Tarjan - * - * @param {number} key Key to splay the tree on. - * @private - */ - SplayTree.prototype.splay_ = function(key) { - if (this.isEmpty()) { - return; - } - // Create a dummy node. The use of the dummy node is a bit - // counter-intuitive: The right child of the dummy node will hold - // the L tree of the algorithm. The left child of the dummy node - // will hold the R tree of the algorithm. Using a dummy node, left - // and right will always be nodes and we avoid special cases. - var dummy, left, right; - dummy = left = right = new SplayTree.Node(null, null); - var current = this.root_; - while (true) { - if (key < current.key) { - if (!current.left) { - break; - } - if (key < current.left.key) { - // Rotate right. - var tmp = current.left; - current.left = tmp.right; - tmp.right = current; - current = tmp; - if (!current.left) { - break; - } - } - // Link right. - right.left = current; - right = current; - current = current.left; - } else if (key > current.key) { - if (!current.right) { - break; - } - if (key > current.right.key) { - // Rotate left. - var tmp = current.right; - current.right = tmp.left; - tmp.left = current; - current = tmp; - if (!current.right) { - break; - } - } - // Link left. - left.right = current; - left = current; - current = current.right; - } else { - break; - } - } - // Assemble. - left.right = current.left; - right.left = current.right; - current.left = dummy.right; - current.right = dummy.left; - this.root_ = current; - }; - - /** - * Performs a preorder traversal of the tree. - * - * @param {function(SplayTree.Node)} f Visitor function. - * @private - */ - SplayTree.prototype.traverse_ = function(f) { - var nodesToVisit = [this.root_]; - while (nodesToVisit.length > 0) { - var node = nodesToVisit.shift(); - if (node == null) { - continue; - } - f(node); - nodesToVisit.push(node.left); - nodesToVisit.push(node.right); - } - }; - - /** - * Constructs a Splay tree node. - * - * @param {number} key Key. - * @param {*} value Value. - */ - SplayTree.Node = function(key, value) { - this.key = key; - this.value = value; - }; - - /** - * @type {SplayTree.Node} - */ - SplayTree.Node.prototype.left = null; - - /** - * @type {SplayTree.Node} - */ - SplayTree.Node.prototype.right = null; - - return { - SplayTree: SplayTree - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/v8_log_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/v8_log_importer.html deleted file mode 100644 index 0fa1a9992c2..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/v8_log_importer.html +++ /dev/null @@ -1,375 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/base/color_scheme.html"> -<link rel="import" href="/tracing/extras/importer/v8/codemap.html"> -<link rel="import" href="/tracing/extras/importer/v8/log_reader.html"> -<link rel="import" href="/tracing/importer/importer.html"> -<link rel="import" href="/tracing/model/model.html"> -<link rel="import" href="/tracing/model/slice.html"> - -<script> - -'use strict'; - -/** - * @fileoverview V8LogImporter imports v8.log files into the provided model. - */ -tr.exportTo('tr.e.importer.v8', function() { - var CodeEntry = tr.e.importer.v8.CodeMap.CodeEntry; - var CodeMap = tr.e.importer.v8.CodeMap; - var ColorScheme = tr.b.ColorScheme; - var DynamicFuncCodeEntry = tr.e.importer.v8.CodeMap.DynamicFuncCodeEntry; - var FunctionEntry = tr.e.importer.v8.CodeMap.FunctionEntry; - - function V8LogImporter(model, eventData) { - this.importPriority = 3; - this.model_ = model; - - this.logData_ = eventData; - - this.code_map_ = new CodeMap(); - this.v8_timer_thread_ = undefined; - this.v8_thread_ = undefined; - - this.root_stack_frame_ = new tr.model.StackFrame( - undefined, 'v8-root-stack-frame', 'v8-root-stack-frame', 0); - - // We reconstruct the stack timeline from ticks. - this.v8_stack_timeline_ = new Array(); - } - - var kV8BinarySuffixes = ['/d8', '/libv8.so']; - - - var TimerEventDefaultArgs = { - 'V8.Execute': { pause: false, no_execution: false}, - 'V8.External': { pause: false, no_execution: true}, - 'V8.CompileFullCode': { pause: true, no_execution: true}, - 'V8.RecompileSynchronous': { pause: true, no_execution: true}, - 'V8.RecompileParallel': { pause: false, no_execution: false}, - 'V8.CompileEval': { pause: true, no_execution: true}, - 'V8.Parse': { pause: true, no_execution: true}, - 'V8.PreParse': { pause: true, no_execution: true}, - 'V8.ParseLazy': { pause: true, no_execution: true}, - 'V8.GCScavenger': { pause: true, no_execution: true}, - 'V8.GCCompactor': { pause: true, no_execution: true}, - 'V8.GCContext': { pause: true, no_execution: true} - }; - - /** - * @return {boolean} Whether obj is a V8 log string. - */ - V8LogImporter.canImport = function(eventData) { - if (typeof(eventData) !== 'string' && !(eventData instanceof String)) - return false; - - return eventData.substring(0, 11) == 'v8-version,' || - eventData.substring(0, 12) == 'timer-event,' || - eventData.substring(0, 5) == 'tick,' || - eventData.substring(0, 15) == 'shared-library,' || - eventData.substring(0, 9) == 'profiler,' || - eventData.substring(0, 14) == 'code-creation,'; - }; - - V8LogImporter.prototype = { - - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'V8LogImporter'; - }, - - processTimerEvent_: function(name, start, length) { - var args = TimerEventDefaultArgs[name]; - if (args === undefined) return; - start /= 1000; // Convert to milliseconds. - length /= 1000; - var colorId = ColorScheme.getColorIdForGeneralPurposeString(name); - var slice = new tr.model.Slice('v8', name, colorId, start, - args, length); - this.v8_timer_thread_.sliceGroup.pushSlice(slice); - }, - - processTimerEventStart_: function(name, start) { - var args = TimerEventDefaultArgs[name]; - if (args === undefined) return; - start /= 1000; // Convert to milliseconds. - this.v8_timer_thread_.sliceGroup.beginSlice('v8', name, start, args); - }, - - processTimerEventEnd_: function(name, end) { - end /= 1000; // Convert to milliseconds. - this.v8_timer_thread_.sliceGroup.endSlice(end); - }, - - processCodeCreateEvent_: function(type, kind, address, size, name, - maybe_func) { - function parseState(s) { - switch (s) { - case '': return CodeMap.CodeState.COMPILED; - case '~': return CodeMap.CodeState.OPTIMIZABLE; - case '*': return CodeMap.CodeState.OPTIMIZED; - } - throw new Error('unknown code state: ' + s); - } - - if (maybe_func.length) { - var funcAddr = parseInt(maybe_func[0]); - var state = parseState(maybe_func[1]); - var func = this.code_map_.findDynamicEntryByStartAddress(funcAddr); - if (!func) { - func = new FunctionEntry(name); - func.kind = kind; - this.code_map_.addCode(funcAddr, func); - } else if (func.name !== name) { - // Function object has been overwritten with a new one. - func.name = name; - } - var entry = this.code_map_.findDynamicEntryByStartAddress(address); - if (entry) { - if (entry.size === size && entry.func === func) { - // Entry state has changed. - entry.state = state; - } - } else { - entry = new DynamicFuncCodeEntry(size, type, func, state); - entry.kind = kind; - this.code_map_.addCode(address, entry); - } - } else { - var code_entry = new CodeEntry(size, name); - code_entry.kind = kind; - this.code_map_.addCode(address, code_entry); - } - }, - - processCodeMoveEvent_: function(from, to) { - this.code_map_.moveCode(from, to); - }, - - processCodeDeleteEvent_: function(address) { - this.code_map_.deleteCode(address); - }, - - processSharedLibrary_: function(name, start, end) { - var code_entry = new CodeEntry(end - start, name, - CodeEntry.TYPE.SHARED_LIB); - code_entry.kind = -3; // External code kind. - for (var i = 0; i < kV8BinarySuffixes.length; i++) { - var suffix = kV8BinarySuffixes[i]; - if (name.indexOf(suffix, name.length - suffix.length) >= 0) { - code_entry.kind = -1; // V8 runtime code kind. - break; - } - } - this.code_map_.addLibrary(start, code_entry); - }, - - processCppSymbol_: function(address, size, name) { - var code_entry = new CodeEntry(size, name, CodeEntry.TYPE.CPP); - code_entry.kind = -1; - this.code_map_.addStaticCode(address, code_entry); - }, - - processTickEvent_: function(pc, start, is_external_callback, - tos_or_external_callback, vmstate, stack) { - start /= 1000; - - function findChildWithEntryID(stackFrame, entryID) { - for (var i = 0; i < stackFrame.children.length; i++) { - if (stackFrame.children[i].entryID == entryID) - return stackFrame.children[i]; - } - return undefined; - } - - function processStack(pc, func, stack) { - var fullStack = func ? [pc, func] : [pc]; - var prevFrame = pc; - for (var i = 0, n = stack.length; i < n; ++i) { - var frame = stack[i]; - var firstChar = frame.charAt(0); - if (firstChar === '+' || firstChar === '-') { - // An offset from the previous frame. - prevFrame += parseInt(frame, 16); - fullStack.push(prevFrame); - // Filter out possible 'overflow' string. - } else if (firstChar !== 'o') { - fullStack.push(parseInt(frame, 16)); - } - // Otherwise, they will be skipped. - } - return fullStack; - } - - if (is_external_callback) { - // Don't use PC when in external callback code, as it can point - // inside callback's code, and we will erroneously report - // that a callback calls itself. Instead use tos_or_external_callback, - // as simply resetting PC will produce unaccounted ticks. - pc = tos_or_external_callback; - tos_or_external_callback = 0; - } else if (tos_or_external_callback) { - // Find out, if top of stack was pointing inside a JS function - // meaning that we have encountered a frameless invocation. - var funcEntry = this.code_map_.findEntry(tos_or_external_callback); - if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction()) - tos_or_external_callback = 0; - } - - var processedStack = processStack(pc, tos_or_external_callback, stack); - var lastStackFrame = this.root_stack_frame_; - // v8 log stacks are inverted, leaf first and the root at the end. - processedStack = processedStack.reverse(); - for (var i = 0, n = processedStack.length; i < n; i++) { - var frame = processedStack[i]; - if (!frame) - break; - var entry = this.code_map_.findEntry(frame); - - if (!entry && i !== 0) { - continue; - } - - var sourceInfo = undefined; - if (entry && entry.type === CodeEntry.TYPE.CPP) { - var libEntry = this.code_map_.findEntryInLibraries(frame); - if (libEntry) - sourceInfo = libEntry.name; - } - - var entryID = entry ? entry.id : 'Unknown'; - var childFrame = findChildWithEntryID(lastStackFrame, entryID); - if (childFrame === undefined) { - var entryName = entry ? entry.name : 'Unknown'; - lastStackFrame = new tr.model.StackFrame( - lastStackFrame, 'v8sf-' + tr.b.GUID.allocateSimple(), entryName, - ColorScheme.getColorIdForGeneralPurposeString(entryName), - sourceInfo); - lastStackFrame.entryID = entryID; - this.model_.addStackFrame(lastStackFrame); - } else { - lastStackFrame = childFrame; - } - } - - if (lastStackFrame !== this.root_stack_frame_) { - var sample = new tr.model.Sample( - undefined, this.v8_thread_, 'V8 PC', - start, lastStackFrame, 1); - this.model_.samples.push(sample); - } - }, - - processDistortion_: function(distortion_in_picoseconds) { - // Do nothing. - }, - - processPlotRange_: function(start, end) { - // Do nothing. - }, - - processV8Version_: function(major, minor, build, patch, candidate) { - // Do nothing. - }, - - /** - * Walks through the events_ list and outputs the structures discovered to - * model_. - */ - importEvents: function() { - var logreader = new tr.e.importer.v8.LogReader( - { 'timer-event' : { - parsers: [null, parseInt, parseInt], - processor: this.processTimerEvent_.bind(this) - }, - 'shared-library': { - parsers: [null, parseInt, parseInt], - processor: this.processSharedLibrary_.bind(this) - }, - 'timer-event-start' : { - parsers: [null, parseInt], - processor: this.processTimerEventStart_.bind(this) - }, - 'timer-event-end' : { - parsers: [null, parseInt], - processor: this.processTimerEventEnd_.bind(this) - }, - 'code-creation': { - parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'], - processor: this.processCodeCreateEvent_.bind(this) - }, - 'code-move': { - parsers: [parseInt, parseInt], - processor: this.processCodeMoveEvent_.bind(this) - }, - 'code-delete': { - parsers: [parseInt], - processor: this.processCodeDeleteEvent_.bind(this) - }, - 'cpp': { - parsers: [parseInt, parseInt, null], - processor: this.processCppSymbol_.bind(this) - }, - 'tick': { - parsers: [parseInt, parseInt, parseInt, parseInt, parseInt, - 'var-args'], - processor: this.processTickEvent_.bind(this) - }, - 'distortion': { - parsers: [parseInt], - processor: this.processDistortion_.bind(this) - }, - 'plot-range': { - parsers: [parseInt, parseInt], - processor: this.processPlotRange_.bind(this) - }, - 'v8-version': { - parsers: [parseInt, parseInt, parseInt, parseInt, parseInt], - processor: this.processV8Version_.bind(this) - } - }); - - this.v8_timer_thread_ = - this.model_.getOrCreateProcess(-32).getOrCreateThread(1); - this.v8_timer_thread_.name = 'V8 Timers'; - this.v8_thread_ = - this.model_.getOrCreateProcess(-32).getOrCreateThread(2); - this.v8_thread_.name = 'V8'; - - var lines = this.logData_.split('\n'); - for (var i = 0; i < lines.length; i++) { - logreader.processLogLine(lines[i]); - } - - // The processing of samples adds all the root stack frame to - // this.root_stack_frame_. But, we don't want that stack frame in the real - // model. So get rid of it. - this.root_stack_frame_.removeAllChildren(); - - function addSlices(slices, thread) { - for (var i = 0; i < slices.length; i++) { - var duration = slices[i].end - slices[i].start; - var slice = new tr.model.Slice('v8', slices[i].name, - ColorScheme.getColorIdForGeneralPurposeString(slices[i].name), - slices[i].start, {}, duration); - thread.sliceGroup.pushSlice(slice); - addSlices(slices[i].children, thread); - } - } - addSlices(this.v8_stack_timeline_, this.v8_thread_); - } - }; - - tr.importer.Importer.register(V8LogImporter); - - return { - V8LogImporter: V8LogImporter - }; -}); -</script> diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/v8_log_importer_test.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/v8_log_importer_test.html deleted file mode 100644 index fdbe447ca60..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/v8/v8_log_importer_test.html +++ /dev/null @@ -1,305 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/core/test_utils.html"> -<link rel="import" href="/tracing/extras/importer/v8/v8_log_importer.html"> - -<script> - -'use strict'; - -tr.b.unittest.testSuite(function() { - var V8LogImporter = tr.e.importer.v8.V8LogImporter; - - function newModel(events) { - return tr.c.TestUtils.newModelWithEvents([events], { - shiftWorldToZero: false - }); - } - - test('tickEventInSharedLibrary', function() { - var lines = [ - 'shared-library,"/usr/lib/libc++.1.dylib",0x99d8aae0,0x99dce729', - 'tick,0x99d8aae4,12158,0,0x0,5']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var t = p.findAllThreadsNamed('V8')[0]; - assert.equal(t.samples.length, 1); - assert.equal(t.samples[0].title, 'V8 PC'); - assert.equal(t.samples[0].start, 12158 / 1000); - assert.equal(t.samples[0].leafStackFrame.title, '/usr/lib/libc++.1.dylib'); - }); - - test('tickEventInGeneratedCode', function() { - var lines = [ - 'shared-library,"/usr/lib/libc++.1.dylib",0x99d8aae0,0x99dce729', - 'code-creation,Stub,2,0x5b60ce80,1259,"StringAddStub"', - 'tick,0x5b60ce84,12158,0,0x0,5']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var threads = p.findAllThreadsNamed('V8'); - var t = threads[0]; - assert.equal(t.samples.length, 1); - assert.equal(t.samples[0].leafStackFrame.title, 'StringAddStub'); - }); - - test('tickEventInUknownCode', function() { - var lines = [ - 'shared-library,"/usr/lib/libc++.1.dylib",0x99d8aae0,0x99dce729', - 'code-creation,Stub,2,0x5b60ce80,1259,"StringAddStub"', - 'tick,0x4,0xbff02f08,12158,0,0x0,5']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var threads = p.findAllThreadsNamed('V8'); - var t = threads[0]; - assert.equal(t.samples.length, 1); - assert.equal(t.samples[0].leafStackFrame.title, 'Unknown'); - }); - - test('tickEventWithStack', function() { - var lines = [ - 'code-creation,LazyCompile,0,0x2905d0c0,1800,"InstantiateFunction native apinatives.js:26:29",0x56b19124,', // @suppress longLineCheck - 'tick,0x7fc6fe34,528674,0,0x3,0,0x2905d304']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var t = p.findAllThreadsNamed('V8')[0]; - assert.equal(t.samples.length, 1); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29'], - t.samples[0].getUserFriendlyStackTrace()); - }); - - test('twoTickEventsWithStack', function() { - var lines = [ - 'code-creation,LazyCompile,0,0x2905d0c0,1800,"InstantiateFunction native apinatives.js:26:29",0x56b19124,', // @suppress longLineCheck - 'tick,0x7fc6fe34,528674,0,0x3,0,0x2905d304', - 'tick,0x7fd2a534,536213,0,0x81d8d080,0,0x2905d304']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var t = p.findAllThreadsNamed('V8')[0]; - assert.equal(t.samples.length, 2); - assert.equal(t.samples[0].start, 528674 / 1000); - assert.equal(t.samples[1].start, 536213 / 1000); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29'], - t.samples[0].getUserFriendlyStackTrace()); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29'], - t.samples[1].getUserFriendlyStackTrace()); - assert.equal(t.samples[0].leafStackFrame, - t.samples[1].leafStackFrame); - }); - - test('twoTickEventsWithTwoStackFrames', function() { - var lines = [ - 'code-creation,LazyCompile,0,0x2904d560,876,"Instantiate native apinatives.js:9:21",0x56b190c8,~', // @suppress longLineCheck - 'code-creation,LazyCompile,0,0x2905d0c0,1800,"InstantiateFunction native apinatives.js:26:29",0x56b19124,', // @suppress longLineCheck - 'tick,0x7fc6fe34,528674,0,0x3,0,0x2905d304,0x2904d6e8', - 'tick,0x7fd2a534,536213,0,0x81d8d080,0,0x2905d304,0x2904d6e8']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var t = p.findAllThreadsNamed('V8')[0]; - assert.equal(t.samples.length, 2); - - assert.equal(t.samples[0].start, 528674 / 1000); - assert.equal(t.samples[1].start, 536213 / 1000); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29', - '~Instantiate native apinatives.js:9:21'], - t.samples[0].getUserFriendlyStackTrace()); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29', - '~Instantiate native apinatives.js:9:21'], - t.samples[1].getUserFriendlyStackTrace()); - - var childStackFrame = t.samples[0].leafStackFrame; - assert.equal(childStackFrame, t.samples[1].leafStackFrame); - assert.equal(childStackFrame.children.length, 0); - - var parentStackFrame = childStackFrame.parentFrame; - assert.equal(parentStackFrame.children.length, 1); - assert.equal(childStackFrame, parentStackFrame.children[0]); - - }); - - test('threeTickEventsWithTwoStackFrames', function() { - var lines = [ - 'code-creation,LazyCompile,0,0x2904d560,876,"Instantiate native apinatives.js:9:21",0x56b190c8,~', // @suppress longLineCheck - 'code-creation,LazyCompile,0,0x2905d0c0,1800,"InstantiateFunction native apinatives.js:26:29",0x56b19124,', // @suppress longLineCheck - 'tick,0x7fd7f75c,518328,0,0x81d86da8,2,0x2904d6e8', - 'tick,0x7fc6fe34,528674,0,0x3,0,0x2905d304,0x2904d6e8', - 'tick,0x7fd2a534,536213,0,0x81d8d080,0,0x2905d304,0x2904d6e8']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var threads = p.findAllThreadsNamed('V8'); - - var t = threads[0]; - assert.equal(t.samples.length, 3); - assert.equal(t.samples[0].start, 518328 / 1000); - assert.equal(t.samples[1].start, 528674 / 1000); - assert.equal(t.samples[2].start, 536213 / 1000); - assert.deepEqual( - ['~Instantiate native apinatives.js:9:21'], - t.samples[0].getUserFriendlyStackTrace()); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29', - '~Instantiate native apinatives.js:9:21'], - t.samples[1].getUserFriendlyStackTrace()); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29', - '~Instantiate native apinatives.js:9:21'], - t.samples[2].getUserFriendlyStackTrace()); - - var topLevelStackFrame = t.samples[0].leafStackFrame; - var childStackFrame = t.samples[1].leafStackFrame; - assert.equal(t.samples[2].leafStackFrame, childStackFrame); - assert.equal(topLevelStackFrame, childStackFrame.parentFrame); - assert.equal(topLevelStackFrame.children.length, 1); - assert.equal(childStackFrame.children.length, 0); - assert.equal(childStackFrame, topLevelStackFrame.children[0]); - }); - - test('twoSubStacks', function() { - var lines = [ - 'code-creation,LazyCompile,0,0x2904d560,876,"Instantiate native apinatives.js:9:21",0x56b190c8,~', // @suppress longLineCheck - 'code-creation,LazyCompile,0,0x2905d0c0,1800,"InstantiateFunction native apinatives.js:26:29",0x56b19124,', // @suppress longLineCheck - 'tick,0x7fd7f75c,518328,0,0x81d86da8,2,0x2904d6e8', - 'tick,0x7fc6fe34,528674,0,0x3,0,0x2905d304,0x2904d6e8', - 'tick,0x7fd2a534,536213,0,0x81d8d080,0,0x2905d304,0x2904d6e8', - 'code-creation,Script,0,0x2906a7c0,792,"http://www.google.com/",0x5b12fe50,~', // @suppress longLineCheck - 'tick,0xb6f51d30,794049,0,0xb6f7b368,2,0x2906a914', - 'tick,0xb6f51d30,799146,0,0xb6f7b368,0,0x2906a914' - ]; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var threads = p.findAllThreadsNamed('V8'); - var t = threads[0]; - assert.equal(t.samples.length, 5); - - assert.equal(t.samples[0].start, 518328 / 1000); - assert.equal(t.samples[1].start, 528674 / 1000); - assert.equal(t.samples[2].start, 536213 / 1000); - assert.equal(t.samples[3].start, 794049 / 1000); - assert.equal(t.samples[4].start, 799146 / 1000); - - assert.deepEqual( - ['~Instantiate native apinatives.js:9:21'], - t.samples[0].getUserFriendlyStackTrace()); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29', - '~Instantiate native apinatives.js:9:21'], - t.samples[1].getUserFriendlyStackTrace()); - assert.deepEqual( - ['InstantiateFunction native apinatives.js:26:29', - '~Instantiate native apinatives.js:9:21'], - t.samples[2].getUserFriendlyStackTrace()); - assert.deepEqual(['~http://www.google.com/'], - t.samples[3].getUserFriendlyStackTrace()); - assert.deepEqual(['~http://www.google.com/'], - t.samples[4].getUserFriendlyStackTrace()); - - var firsStackTopLevelStackFrame = t.samples[0].leafStackFrame; - var firsStackChildStackFrame = t.samples[1].leafStackFrame; - assert.equal(firsStackChildStackFrame, t.samples[2].leafStackFrame); - assert.equal(firsStackTopLevelStackFrame, - firsStackChildStackFrame.parentFrame); - assert.equal(firsStackTopLevelStackFrame.children.length, 1); - assert.equal(firsStackChildStackFrame.children.length, 0); - assert.equal(firsStackChildStackFrame, - firsStackTopLevelStackFrame.children[0]); - - var secondStackStackFrame = t.samples[3].leafStackFrame; - assert.equal(secondStackStackFrame, t.samples[4].leafStackFrame); - assert.equal(secondStackStackFrame.children.length, 0); - assert.isUndefined(secondStackStackFrame.parentFrame); - }); - - test('timerEventSliceCreation', function() { - var lines = ['timer-event,"V8.External",38189483,3']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var threads = p.findAllThreadsNamed('V8 Timers'); - assert.isDefined(threads); - assert.equal(threads.length, 1); - var t = threads[0]; - assert.equal(t.sliceGroup.length, 1); - }); - - test('processThreadCreation', function() { - var lines = ['timer-event,"V8.External",38189483,3']; - var m = newModel(lines.join('\n')); - assert.isDefined(m); - var p = m.processes[-32]; - assert.isDefined(p); - var threads = p.findAllThreadsNamed('V8 Timers'); - assert.isDefined(threads); - assert.equal(1, threads.length); - var t = threads[0]; - assert.equal('V8 Timers', t.name); - }); - - test('canImport', function() { - assert.isTrue(V8LogImporter.canImport( - 'timer-event,"V8.External",38189483,3')); - assert.isTrue(V8LogImporter.canImport('v8-version,4,3,66,0,0')); - assert.isFalse(V8LogImporter.canImport('')); - assert.isFalse(V8LogImporter.canImport([])); - }); - - test('CppSymbolsProcess', function() { - var lines = [ - 'shared-library,"/usr/loca/v8/out/native/d8",0x00400000, 0x01860000', - 'cpp,0x00600000,100,"v8::internal::Heap::AllocateByteArray"', - 'cpp,0x00700000,100,"v8::internal::Utf8StringKey::AsHandle"', - 'tick,0x00600010,121,0,0x0,5', - 'tick,0x00700010,122,0,0x0,5', - 'tick,0x00800010,123,0,0x0,5']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var t = p.findAllThreadsNamed('V8')[0]; - assert.equal(t.samples.length, 3); - assert.equal(t.samples[0].leafStackFrame.title, - 'v8::internal::Heap::AllocateByteArray /usr/loca/v8/out/native/d8'); // @suppress longLineCheck - assert.equal(t.samples[1].leafStackFrame.title, - 'v8::internal::Utf8StringKey::AsHandle /usr/loca/v8/out/native/d8'); // @suppress longLineCheck - assert.equal(t.samples[2].leafStackFrame.title, - '/usr/loca/v8/out/native/d8'); - }); - - test('CppSymbolsWithJsStack', function() { - var lines = [ - 'shared-library,"/usr/loca/v8/out/native/d8",0x00400000, 0x01860000', - 'cpp,0x00600000,100,"v8::internal::Heap::AllocateByteArray"', - 'cpp,0x00700000,100,"v8::internal::Utf8StringKey::AsHandle"', - 'code-creation,LazyCompile,0,0x2905d0c0,1800,"InstantiateFunction native apinatives.js:26:29",0x56b19124,', // @suppress longLineCheck - 'tick,0x00700010,1,0,0x3,0,0x2905d304', - 'tick,0x00600010,3,0,0x3,0,0x2905d306', - 'tick,0x00800010,5,0,0x3,0,0x2905d306', - 'tick,0x01860010,5,0,0x3,0,0x2905d306']; - var m = newModel(lines.join('\n')); - var p = m.processes[-32]; - var t = p.findAllThreadsNamed('V8')[0]; - assert.equal(t.samples.length, 4); - assert.deepEqual(t.samples[0].stackTrace.map(r => r.title), [ - 'v8::internal::Utf8StringKey::AsHandle /usr/loca/v8/out/native/d8', - 'InstantiateFunction native apinatives.js:26:29' - ]); - assert.deepEqual(t.samples[1].stackTrace.map(r => r.title), [ - 'v8::internal::Heap::AllocateByteArray /usr/loca/v8/out/native/d8', - 'InstantiateFunction native apinatives.js:26:29' - ]); - assert.deepEqual(t.samples[2].stackTrace.map(r => r.title), [ - '/usr/loca/v8/out/native/d8', - 'InstantiateFunction native apinatives.js:26:29' - ]); - assert.deepEqual(t.samples[3].stackTrace.map(r => r.title), [ - 'InstantiateFunction native apinatives.js:26:29' - ]); - }); -}); -</script> - diff --git a/chromium/third_party/catapult/tracing/tracing/extras/importer/zip_importer.html b/chromium/third_party/catapult/tracing/tracing/extras/importer/zip_importer.html deleted file mode 100644 index 9f1a2aa95b0..00000000000 --- a/chromium/third_party/catapult/tracing/tracing/extras/importer/zip_importer.html +++ /dev/null @@ -1,69 +0,0 @@ -<!DOCTYPE html> -<!-- -Copyright (c) 2013 The Chromium Authors. All rights reserved. -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/extras/importer/jszip.html"> -<link rel="import" href="/tracing/extras/importer/gzip_importer.html"> -<link rel="import" href="/tracing/importer/importer.html"> -<link rel="import" href="/tracing/model/model.html"> - -<script> -'use strict'; - -/** - * @fileoverview ZipImporter inflates zip compressed data and passes it along - * to an actual importer. - */ -tr.exportTo('tr.e.importer', function() { - function ZipImporter(model, eventData) { - if (eventData instanceof ArrayBuffer) - eventData = new Uint8Array(eventData); - this.model_ = model; - this.eventData_ = eventData; - } - - /** - * @param {eventData} string Possibly zip compressed data. - * @return {boolean} Whether eventData looks like zip compressed data. - */ - ZipImporter.canImport = function(eventData) { - var header; - if (eventData instanceof ArrayBuffer) - header = new Uint8Array(eventData.slice(0, 2)); - else if (typeof(eventData) === 'string' || eventData instanceof String) - header = [eventData.charCodeAt(0), eventData.charCodeAt(1)]; - else - return false; - return header[0] === 'P'.charCodeAt(0) && header[1] === 'K'.charCodeAt(0); - }; - - ZipImporter.prototype = { - __proto__: tr.importer.Importer.prototype, - - get importerName() { - return 'ZipImporter'; - }, - - isTraceDataContainer: function() { - return true; - }, - - extractSubtraces: function() { - var zip = new JSZip(this.eventData_); - var subtraces = []; - for (var idx in zip.files) - subtraces.push(zip.files[idx].asBinary()); - return subtraces; - } - }; - - tr.importer.Importer.register(ZipImporter); - - return { - ZipImporter: ZipImporter - }; -}); -</script> |