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

Unified Diff: Source/devtools/front_end/timeline/TimelineModel.js

Issue 313333002: Extract implementation based on timeline events into TimelineModelImpl (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/timeline/TimelineModelImpl.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/devtools/front_end/timeline/TimelineModel.js
diff --git a/Source/devtools/front_end/timeline/TimelineModel.js b/Source/devtools/front_end/timeline/TimelineModel.js
index f913ee67db964d32260343be6cb8cdccd43f0847..6b02f2a249e8645dc804b38b6bbadaa65673a887 100644
--- a/Source/devtools/front_end/timeline/TimelineModel.js
+++ b/Source/devtools/front_end/timeline/TimelineModel.js
@@ -31,24 +31,14 @@
/**
* @constructor
* @extends {WebInspector.Object}
- * @param {!WebInspector.TimelineManager} timelineManager
+ * @param {!WebInspector.Target} target
*/
-WebInspector.TimelineModel = function(timelineManager)
+WebInspector.TimelineModel = function(target)
{
- this._timelineManager = timelineManager;
this._filters = [];
- this._bindings = new WebInspector.TimelineModel.InterRecordBindings();
-
- this.reset();
-
- this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._onRecordAdded, this);
- this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStarted, this._onStarted, this);
- this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStopped, this._onStopped, this);
- this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineProgress, this._onProgress, this);
+ this._target = target;
}
-WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000;
-
WebInspector.TimelineModel.RecordType = {
Root: "Root",
Program: "Program",
@@ -157,7 +147,7 @@ WebInspector.TimelineModel.prototype = {
*/
target: function()
{
- return this._timelineManager.target();
+ return this._target;
},
/**
@@ -165,7 +155,7 @@ WebInspector.TimelineModel.prototype = {
*/
loadedFromFile: function()
{
- return this._loadedFromFile;
+ return false;
},
/**
@@ -234,49 +224,10 @@ WebInspector.TimelineModel.prototype = {
this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordFilterChanged);
},
- /**
- * @param {boolean} captureStacks
- * @param {boolean} captureMemory
- */
- startRecording: function(captureStacks, captureMemory)
- {
- this._clientInitiatedRecording = true;
- this.reset();
- var maxStackFrames = captureStacks ? 30 : 0;
- this._bufferEvents = WebInspector.experimentsSettings.timelineNoLiveUpdate.isEnabled();
- var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEnabled();
- var liveEvents = [ WebInspector.TimelineModel.RecordType.BeginFrame,
- WebInspector.TimelineModel.RecordType.DrawFrame,
- WebInspector.TimelineModel.RecordType.RequestMainThreadFrame,
- WebInspector.TimelineModel.RecordType.ActivateLayerTree ];
- this._timelineManager.start(maxStackFrames, this._bufferEvents, liveEvents.join(","), captureMemory, includeGPUEvents, this._fireRecordingStarted.bind(this));
- },
-
- stopRecording: function()
- {
- if (!this._clientInitiatedRecording) {
- this._timelineManager.start(undefined, undefined, undefined, undefined, undefined, stopTimeline.bind(this));
- return;
- }
-
- /**
- * Console started this one and we are just sniffing it. Initiate recording so that we
- * could stop it.
- * @this {WebInspector.TimelineModel}
- */
- function stopTimeline()
- {
- this._timelineManager.stop(this._fireRecordingStopped.bind(this));
- }
-
- this._clientInitiatedRecording = false;
- this._timelineManager.stop(this._fireRecordingStopped.bind(this));
- },
-
willStartRecordingTraceEvents: function()
{
this.reset();
- this._fireRecordingStarted();
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStarted);
},
/**
@@ -302,7 +253,7 @@ WebInspector.TimelineModel.prototype = {
if (event.endTime)
recordStack.push(record);
}
- this._fireRecordingStopped(null, null);
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped);
},
/**
@@ -328,109 +279,11 @@ WebInspector.TimelineModel.prototype = {
},
/**
- * @param {!WebInspector.Event} event
- */
- _onRecordAdded: function(event)
- {
- if (this._collectionEnabled)
- this._addRecord(/** @type {!TimelineAgent.TimelineEvent} */(event.data));
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onStarted: function(event)
- {
- if (event.data) {
- // Started from console.
- this._fireRecordingStarted();
- }
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onStopped: function(event)
- {
- if (event.data) {
- // Stopped from console.
- this._fireRecordingStopped(null, null);
- }
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onProgress: function(event)
- {
- this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingProgress, event.data);
- },
-
- _fireRecordingStarted: function()
- {
- this._collectionEnabled = true;
- this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStarted);
- },
-
- /**
- * @param {?Protocol.Error} error
- * @param {?ProfilerAgent.CPUProfile} cpuProfile
- */
- _fireRecordingStopped: function(error, cpuProfile)
- {
- this._bufferEvents = false;
- this._collectionEnabled = false;
- if (cpuProfile)
- WebInspector.TimelineJSProfileProcessor.mergeJSProfileIntoTimeline(this, cpuProfile);
- this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped);
- },
-
- /**
* @return {boolean}
*/
bufferEvents: function()
{
- return this._bufferEvents;
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} payload
- */
- _addRecord: function(payload)
- {
- this._internStrings(payload);
- this._payloads.push(payload);
-
- var record = this._innerAddRecord(payload, null);
- this._updateBoundaries(record);
- this._records.push(record);
- if (record.type() === WebInspector.TimelineModel.RecordType.Program)
- this._mainThreadTasks.push(record);
- if (record.type() === WebInspector.TimelineModel.RecordType.GPUTask)
- this._gpuThreadTasks.push(record);
-
- this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAdded, record);
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} payload
- * @param {?WebInspector.TimelineModel.Record} parentRecord
- * @return {!WebInspector.TimelineModel.Record}
- * @this {!WebInspector.TimelineModel}
- */
- _innerAddRecord: function(payload, parentRecord)
- {
- var record = new WebInspector.TimelineModel.RecordImpl(this, payload, parentRecord);
- if (WebInspector.TimelineUIUtils.isEventDivider(record))
- this._eventDividerRecords.push(record);
-
- for (var i = 0; payload.children && i < payload.children.length; ++i)
- this._innerAddRecord.call(this, payload.children[i], record);
-
- record._calculateAggregatedStats();
- if (parentRecord)
- parentRecord._selfTime -= record.endTime() - record.startTime();
- return record;
+ return false;
},
/**
@@ -439,10 +292,7 @@ WebInspector.TimelineModel.prototype = {
*/
loadFromFile: function(file, progress)
{
- var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this, progress);
- var fileReader = this._createFileReader(file, delegate);
- var loader = new WebInspector.TimelineModelLoader(this, fileReader, progress);
- fileReader.start(loader);
+ throw new Error("Not implemented");
},
/**
@@ -451,51 +301,20 @@ WebInspector.TimelineModel.prototype = {
*/
loadFromURL: function(url, progress)
{
- var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this, progress);
- var urlReader = new WebInspector.ChunkedXHRReader(url, delegate);
- var loader = new WebInspector.TimelineModelLoader(this, urlReader, progress);
- urlReader.start(loader);
- },
-
- _createFileReader: function(file, delegate)
- {
- return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineModel.TransferChunkLengthBytes, delegate);
- },
-
- _createFileWriter: function()
- {
- return new WebInspector.FileOutputStream();
+ throw new Error("Not implemented");
},
saveToFile: function()
{
- var now = new Date();
- var fileName = "TimelineRawData-" + now.toISO8601Compact() + ".json";
- var stream = this._createFileWriter();
-
- /**
- * @param {boolean} accepted
- * @this {WebInspector.TimelineModel}
- */
- function callback(accepted)
- {
- if (!accepted)
- return;
- var saver = new WebInspector.TimelineSaver(stream);
- saver.save(this._payloads, window.navigator.appVersion);
- }
- stream.open(fileName, callback.bind(this));
+ throw new Error("Not implemented");
},
reset: function()
{
this._loadedFromFile = false;
this._records = [];
- this._payloads = [];
- this._stringPool = {};
this._minimumRecordTime = -1;
this._maximumRecordTime = -1;
- this._bindings._reset();
/** @type {!Array.<!WebInspector.TimelineModel.Record>} */
this._mainThreadTasks = [];
/** @type {!Array.<!WebInspector.TimelineModel.Record>} */
@@ -559,51 +378,9 @@ WebInspector.TimelineModel.prototype = {
return this._eventDividerRecords;
},
- /**
- * @param {!TimelineAgent.TimelineEvent} record
- */
- _internStrings: function(record)
- {
- for (var name in record) {
- var value = record[name];
- if (typeof value !== "string")
- continue;
-
- var interned = this._stringPool[value];
- if (typeof interned === "string")
- record[name] = interned;
- else
- this._stringPool[value] = value;
- }
-
- var children = record.children;
- for (var i = 0; children && i < children.length; ++i)
- this._internStrings(children[i]);
- },
-
__proto__: WebInspector.Object.prototype
}
-
-/**
- * @constructor
- */
-WebInspector.TimelineModel.InterRecordBindings = function() {
- this._reset();
-}
-
-WebInspector.TimelineModel.InterRecordBindings.prototype = {
- _reset: function()
- {
- this._sendRequestRecords = {};
- this._timerRecords = {};
- this._requestAnimationFrameRecords = {};
- this._layoutInvalidate = {};
- this._lastScheduleStyleRecalculation = {};
- this._webSocketCreateRecords = {};
- }
-}
-
/**
* @interface
*/
@@ -928,288 +705,6 @@ WebInspector.TimelineModel.TraceEventRecord.prototype = {
/**
* @constructor
- * @implements {WebInspector.TimelineModel.Record}
- * @param {!WebInspector.TimelineModel} model
- * @param {!TimelineAgent.TimelineEvent} timelineEvent
- * @param {?WebInspector.TimelineModel.Record} parentRecord
- */
-WebInspector.TimelineModel.RecordImpl = function(model, timelineEvent, parentRecord)
-{
- this._model = model;
- var bindings = this._model._bindings;
- this._aggregatedStats = {};
- this._record = timelineEvent;
- this._children = [];
- if (parentRecord) {
- this.parent = parentRecord;
- parentRecord.children().push(this);
- }
-
- this._selfTime = this.endTime() - this.startTime();
-
- var recordTypes = WebInspector.TimelineModel.RecordType;
- switch (timelineEvent.type) {
- case recordTypes.ResourceSendRequest:
- // Make resource receive record last since request was sent; make finish record last since response received.
- bindings._sendRequestRecords[timelineEvent.data["requestId"]] = this;
- break;
-
- case recordTypes.ResourceReceiveResponse:
- case recordTypes.ResourceReceivedData:
- case recordTypes.ResourceFinish:
- this._initiator = bindings._sendRequestRecords[timelineEvent.data["requestId"]];
- break;
-
- case recordTypes.TimerInstall:
- bindings._timerRecords[timelineEvent.data["timerId"]] = this;
- break;
-
- case recordTypes.TimerFire:
- this._initiator = bindings._timerRecords[timelineEvent.data["timerId"]];
- break;
-
- case recordTypes.RequestAnimationFrame:
- bindings._requestAnimationFrameRecords[timelineEvent.data["id"]] = this;
- break;
-
- case recordTypes.FireAnimationFrame:
- this._initiator = bindings._requestAnimationFrameRecords[timelineEvent.data["id"]];
- break;
-
- case recordTypes.ScheduleStyleRecalculation:
- bindings._lastScheduleStyleRecalculation[this.frameId()] = this;
- break;
-
- case recordTypes.RecalculateStyles:
- this._initiator = bindings._lastScheduleStyleRecalculation[this.frameId()];
- break;
-
- case recordTypes.InvalidateLayout:
- // Consider style recalculation as a reason for layout invalidation,
- // but only if we had no earlier layout invalidation records.
- var layoutInitator = this;
- if (!bindings._layoutInvalidate[this.frameId()] && parentRecord.type() === recordTypes.RecalculateStyles)
- layoutInitator = parentRecord._initiator;
- bindings._layoutInvalidate[this.frameId()] = layoutInitator;
- break;
-
- case recordTypes.Layout:
- this._initiator = bindings._layoutInvalidate[this.frameId()];
- bindings._layoutInvalidate[this.frameId()] = null;
- if (this.stackTrace())
- this.addWarning(WebInspector.UIString("Forced synchronous layout is a possible performance bottleneck."));
- break;
-
- case recordTypes.WebSocketCreate:
- bindings._webSocketCreateRecords[timelineEvent.data["identifier"]] = this;
- break;
-
- case recordTypes.WebSocketSendHandshakeRequest:
- case recordTypes.WebSocketReceiveHandshakeResponse:
- case recordTypes.WebSocketDestroy:
- this._initiator = bindings._webSocketCreateRecords[timelineEvent.data["identifier"]];
- break;
- }
-}
-
-WebInspector.TimelineModel.RecordImpl.prototype = {
- /**
- * @return {?Array.<!ConsoleAgent.CallFrame>}
- */
- callSiteStackTrace: function()
- {
- return this._initiator ? this._initiator.stackTrace() : null;
- },
-
- /**
- * @return {?WebInspector.TimelineModel.Record}
- */
- initiator: function()
- {
- return this._initiator;
- },
-
- /**
- * @return {!WebInspector.Target}
- */
- target: function()
- {
- return this._model.target();
- },
-
- /**
- * @return {number}
- */
- selfTime: function()
- {
- return this._selfTime;
- },
-
- /**
- * @return {!Array.<!WebInspector.TimelineModel.Record>}
- */
- children: function()
- {
- return this._children;
- },
-
- /**
- * @return {!WebInspector.TimelineCategory}
- */
- category: function()
- {
- return WebInspector.TimelineUIUtils.categoryForRecord(this);
- },
-
- /**
- * @return {string}
- */
- title: function()
- {
- return WebInspector.TimelineUIUtils.recordTitle(this, this._model);
- },
-
- /**
- * @return {number}
- */
- startTime: function()
- {
- return this._record.startTime;
- },
-
- /**
- * @return {string|undefined}
- */
- thread: function()
- {
- return this._record.thread;
- },
-
- /**
- * @return {number}
- */
- endTime: function()
- {
- return this._endTime || this._record.endTime || this._record.startTime;
- },
-
- /**
- * @param {number} endTime
- */
- setEndTime: function(endTime)
- {
- this._endTime = endTime;
- },
-
- /**
- * @return {!Object}
- */
- data: function()
- {
- return this._record.data;
- },
-
- /**
- * @return {string}
- */
- type: function()
- {
- return this._record.type;
- },
-
- /**
- * @return {string}
- */
- frameId: function()
- {
- return this._record.frameId || "";
- },
-
- /**
- * @return {?Array.<!ConsoleAgent.CallFrame>}
- */
- stackTrace: function()
- {
- if (this._record.stackTrace && this._record.stackTrace.length)
- return this._record.stackTrace;
- return null;
- },
-
- /**
- * @param {string} key
- * @return {?Object}
- */
- getUserObject: function(key)
- {
- if (!this._userObjects)
- return null;
- return this._userObjects.get(key);
- },
-
- /**
- * @param {string} key
- * @param {?Object|undefined} value
- */
- setUserObject: function(key, value)
- {
- if (!this._userObjects)
- this._userObjects = new StringMap();
- this._userObjects.put(key, value);
- },
-
- _calculateAggregatedStats: function()
- {
- this._aggregatedStats = {};
-
- for (var index = this._children.length; index; --index) {
- var child = this._children[index - 1];
- for (var category in child._aggregatedStats)
- this._aggregatedStats[category] = (this._aggregatedStats[category] || 0) + child._aggregatedStats[category];
- }
- this._aggregatedStats[this.category().name] = (this._aggregatedStats[this.category().name] || 0) + this._selfTime;
- },
-
- /**
- * @return {!Object.<string, number>}
- */
- aggregatedStats: function()
- {
- return this._aggregatedStats;
- },
-
- /**
- * @param {string} message
- */
- addWarning: function(message)
- {
- if (!this._warnings)
- this._warnings = [];
- this._warnings.push(message);
- },
-
- /**
- * @return {?Array.<string>}
- */
- warnings: function()
- {
- return this._warnings;
- },
-
- /**
- * @param {!RegExp} regExp
- * @return {boolean}
- */
- testContentMatching: function(regExp)
- {
- var tokens = [this.title()];
- for (var key in this._record.data)
- tokens.push(this._record.data[key])
- return regExp.test(tokens.join("|"));
- }
-}
-
-/**
- * @constructor
*/
WebInspector.TimelineModel.Filter = function()
{
@@ -1235,194 +730,6 @@ WebInspector.TimelineModel.Filter.prototype = {
/**
* @constructor
- * @implements {WebInspector.OutputStream}
- * @param {!WebInspector.TimelineModel} model
- * @param {!{cancel: function()}} reader
- * @param {!WebInspector.Progress} progress
- */
-WebInspector.TimelineModelLoader = function(model, reader, progress)
-{
- this._model = model;
- this._reader = reader;
- this._progress = progress;
- this._buffer = "";
- this._firstChunk = true;
-}
-
-WebInspector.TimelineModelLoader.prototype = {
- /**
- * @param {string} chunk
- */
- write: function(chunk)
- {
- var data = this._buffer + chunk;
- var lastIndex = 0;
- var index;
- do {
- index = lastIndex;
- lastIndex = WebInspector.TextUtils.findBalancedCurlyBrackets(data, index);
- } while (lastIndex !== -1)
-
- var json = data.slice(0, index) + "]";
- this._buffer = data.slice(index);
-
- if (!index)
- return;
-
- // Prepending "0" to turn string into valid JSON.
- if (!this._firstChunk)
- json = "[0" + json;
-
- var items;
- try {
- items = /** @type {!Array.<!TimelineAgent.TimelineEvent>} */ (JSON.parse(json));
- } catch (e) {
- WebInspector.messageSink.addErrorMessage("Malformed timeline data.", true);
- this._model.reset();
- this._reader.cancel();
- this._progress.done();
- return;
- }
-
- if (this._firstChunk) {
- this._version = items[0];
- this._firstChunk = false;
- this._model.reset();
- }
-
- // Skip 0-th element - it is either version or 0.
- for (var i = 1, size = items.length; i < size; ++i)
- this._model._addRecord(items[i]);
- },
-
- close: function()
- {
- this._model._loadedFromFile = true;
- }
-}
-
-/**
- * @constructor
- * @implements {WebInspector.OutputStreamDelegate}
- * @param {!WebInspector.TimelineModel} model
- * @param {!WebInspector.Progress} progress
- */
-WebInspector.TimelineModelLoadFromFileDelegate = function(model, progress)
-{
- this._model = model;
- this._progress = progress;
-}
-
-WebInspector.TimelineModelLoadFromFileDelegate.prototype = {
- onTransferStarted: function()
- {
- this._progress.setTitle(WebInspector.UIString("Loading\u2026"));
- },
-
- /**
- * @param {!WebInspector.ChunkedReader} reader
- */
- onChunkTransferred: function(reader)
- {
- if (this._progress.isCanceled()) {
- reader.cancel();
- this._progress.done();
- this._model.reset();
- return;
- }
-
- var totalSize = reader.fileSize();
- if (totalSize) {
- this._progress.setTotalWork(totalSize);
- this._progress.setWorked(reader.loadedSize());
- }
- },
-
- onTransferFinished: function()
- {
- this._progress.done();
- },
-
- /**
- * @param {!WebInspector.ChunkedReader} reader
- * @param {!Event} event
- */
- onError: function(reader, event)
- {
- this._progress.done();
- this._model.reset();
- switch (event.target.error.code) {
- case FileError.NOT_FOUND_ERR:
- WebInspector.messageSink.addErrorMessage(WebInspector.UIString("File \"%s\" not found.", reader.fileName()), true);
- break;
- case FileError.NOT_READABLE_ERR:
- WebInspector.messageSink.addErrorMessage(WebInspector.UIString("File \"%s\" is not readable", reader.fileName()), true);
- break;
- case FileError.ABORT_ERR:
- break;
- default:
- WebInspector.messageSink.addErrorMessage(WebInspector.UIString("An error occurred while reading the file \"%s\"", reader.fileName()), true);
- }
- }
-}
-
-/**
- * @constructor
- * @param {!WebInspector.OutputStream} stream
- */
-WebInspector.TimelineSaver = function(stream)
-{
- this._stream = stream;
-}
-
-WebInspector.TimelineSaver.prototype = {
- /**
- * @param {!Array.<*>} payloads
- * @param {string} version
- */
- save: function(payloads, version)
- {
- this._payloads = payloads;
- this._recordIndex = 0;
- this._prologue = "[" + JSON.stringify(version);
-
- this._writeNextChunk(this._stream);
- },
-
- _writeNextChunk: function(stream)
- {
- const separator = ",\n";
- var data = [];
- var length = 0;
-
- if (this._prologue) {
- data.push(this._prologue);
- length += this._prologue.length;
- delete this._prologue;
- } else {
- if (this._recordIndex === this._payloads.length) {
- stream.close();
- return;
- }
- data.push("");
- }
- while (this._recordIndex < this._payloads.length) {
- var item = JSON.stringify(this._payloads[this._recordIndex]);
- var itemLength = item.length + separator.length;
- if (length + itemLength > WebInspector.TimelineModel.TransferChunkLengthBytes)
- break;
- length += itemLength;
- data.push(item);
- ++this._recordIndex;
- }
- if (this._recordIndex === this._payloads.length)
- data.push(data.pop() + "]");
- stream.write(data.join(separator), this._writeNextChunk.bind(this));
- }
-}
-
-/**
- * @constructor
*/
WebInspector.TimelineMergingRecordBuffer = function()
{
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/timeline/TimelineModelImpl.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698