Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (201685 => 201686)
--- trunk/Source/WebInspectorUI/ChangeLog 2016-06-04 20:59:57 UTC (rev 201685)
+++ trunk/Source/WebInspectorUI/ChangeLog 2016-06-04 21:09:55 UTC (rev 201686)
@@ -1,3 +1,60 @@
+2016-06-04 Matt Baker <[email protected]>
+
+ Web Inspector: discontinuous recordings should have discontinuities in the timeline memory graph
+ https://bugs.webkit.org/show_bug.cgi?id=158052
+ <rdar://problem/26516695>
+
+ Reviewed by Joseph Pecoraro.
+
+ Add gaps to the overview and category line charts where discontinuities
+ exist in the timeline recording.
+
+ * UserInterface/Models/Timeline.js:
+ (WebInspector.Timeline.prototype.recordsInTimeRange):
+ Replaces `_visibleRecords` methods found in various views.
+
+ * UserInterface/Models/TimelineRecording.js:
+ (WebInspector.TimelineRecording.prototype.reset):
+ (WebInspector.TimelineRecording.prototype.addDiscontinuity):
+ (WebInspector.TimelineRecording.prototype.discontinuitiesInTimeRange):
+ Allow discontinuities to be added to the recording, and have a means to
+ look up gaps within a time range.
+
+ * UserInterface/Views/HeapAllocationsTimelineOverviewGraph.js:
+ (WebInspector.HeapAllocationsTimelineOverviewGraph.prototype._visibleRecords): Deleted.
+ Replaced by Timeline helper method.
+
+ * UserInterface/Views/MemoryTimelineOverviewGraph.js:
+ (WebInspector.MemoryTimelineOverviewGraph.prototype.layout.insertDiscontinuity):
+ (WebInspector.MemoryTimelineOverviewGraph.prototype.layout):
+ Insert zero-points into the chart at discontinuity boundaries to create
+ gaps. Data points for records immediately before or after a gap are extended
+ to the edge of the discontinuity.
+
+ (WebInspector.MemoryTimelineOverviewGraph.prototype._visibleRecords): Deleted.
+ Replaced by Timeline helper method.
+
+ * UserInterface/Views/MemoryTimelineView.js:
+ (WebInspector.MemoryTimelineView.prototype.layout):
+ Insert zero-points into each category chart at discontinuity boundaries
+ to create gaps.
+
+ Insert zero-points into the chart to create gaps.
+ (WebInspector.MemoryTimelineView.prototype._visibleRecords): Deleted.
+ Replaced by Timeline helper method.
+
+ * UserInterface/Views/TimelineOverview.js:
+ (WebInspector.TimelineOverview.prototype.discontinuitiesInTimeRange):
+ Forward to the TimelineRecording, which isn't exposed to clients.
+
+ * UserInterface/Views/TimelineRecordingContentView.js:
+ (WebInspector.TimelineRecordingContentView):
+ (WebInspector.TimelineRecordingContentView.prototype._capturingStarted):
+ (WebInspector.TimelineRecordingContentView.prototype._capturingStopped):
+ (WebInspector.TimelineRecordingContentView.prototype._recordingReset):
+ Track discontinuities (recording stop followed by a start) and add them
+ to the current recording.
+
2016-06-03 Brian Burg <[email protected]>
Web Inspector: add a keyboard shortcut to close the current tab bar item
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Timeline.js (201685 => 201686)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Timeline.js 2016-06-04 20:59:57 UTC (rev 201685)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Timeline.js 2016-06-04 21:09:55 UTC (rev 201686)
@@ -103,6 +103,18 @@
this.dispatchEventToListeners(WebInspector.Timeline.Event.Refreshed);
}
+ recordsInTimeRange(startTime, endTime, includeRecordBeforeStart)
+ {
+ let lowerIndex = this._records.lowerBound(startTime, (time, record) => time - record.timestamp);
+ let upperIndex = this._records.upperBound(endTime, (time, record) => time - record.timestamp);
+
+ // Include the record right before the start time.
+ if (includeRecordBeforeStart && lowerIndex > 0)
+ lowerIndex--;
+
+ return this._records.slice(lowerIndex, upperIndex);
+ }
+
// Private
_updateTimesIfNeeded(record)
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js (201685 => 201686)
--- trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js 2016-06-04 20:59:57 UTC (rev 201685)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js 2016-06-04 21:09:55 UTC (rev 201686)
@@ -159,6 +159,7 @@
this._eventMarkers = [];
this._startTime = NaN;
this._endTime = NaN;
+ this._discontinuities = [];
this._topDownCallingContextTree.reset();
this._bottomUpCallingContextTree.reset();
@@ -282,6 +283,16 @@
memoryTimeline.addMemoryPressureEvent(memoryPressureEvent);
}
+ addDiscontinuity(startTime, endTime)
+ {
+ this._discontinuities.push({startTime, endTime});
+ }
+
+ discontinuitiesInTimeRange(startTime, endTime)
+ {
+ return this._discontinuities.filter((item) => item.startTime < endTime && item.endTime > startTime);
+ }
+
computeElapsedTime(timestamp)
{
if (!timestamp || isNaN(timestamp))
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineOverviewGraph.js (201685 => 201686)
--- trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineOverviewGraph.js 2016-06-04 20:59:57 UTC (rev 201685)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineOverviewGraph.js 2016-06-04 21:09:55 UTC (rev 201686)
@@ -57,7 +57,7 @@
this._selectedImageElement = null;
// This may display records past the current time marker.
- let visibleRecords = this._visibleRecords(this.startTime, this.endTime);
+ let visibleRecords = this._heapAllocations.recordsInTimeRange(this.startTime, this.endTime);
if (!visibleRecords.length)
return;
@@ -114,14 +114,6 @@
this._selectedImageElement = imageElement;
}
- _visibleRecords(startTime, endTime)
- {
- let records = this._heapAllocationsTimeline.records;
- let lowerIndex = records.lowerBound(startTime, (time, record) => time - record.timestamp);
- let upperIndex = records.upperBound(endTime, (time, record) => time - record.timestamp);
- return records.slice(lowerIndex, upperIndex);
- }
-
_heapAllocationTimelineRecordAdded(event)
{
this.needsLayout();
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineOverviewGraph.js (201685 => 201686)
--- trunk/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineOverviewGraph.js 2016-06-04 20:59:57 UTC (rev 201685)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineOverviewGraph.js 2016-06-04 21:09:55 UTC (rev 201686)
@@ -133,7 +133,13 @@
element.remove();
}
- let visibleRecords = this._visibleRecords(graphStartTime, visibleEndTime);
+ let discontinuities = this.timelineOverview.discontinuitiesInTimeRange(graphStartTime, visibleEndTime);
+
+ // Don't include the record before the graph start if the graph start is within a gap.
+ let includeRecordBeforeStart = !discontinuities.length || discontinuities[0].startTime > graphStartTime;
+
+ // FIXME: <https://webkit.org/b/153759> Web Inspector: Memory Timelines should better extend to future data
+ let visibleRecords = this._memoryTimeline.recordsInTimeRange(graphStartTime, visibleEndTime, includeRecordBeforeStart);
if (!visibleRecords.length)
return;
@@ -148,19 +154,59 @@
}
// Extend the first record to the start so it doesn't look like we originate at zero size.
- if (visibleRecords[0] === this._memoryTimeline.records[0])
+ if (visibleRecords[0] === this._memoryTimeline.records[0] && (!discontinuities.length || discontinuities[0].startTime > visibleRecords[0].startTime))
this._chart.addPointSet(0, pointSetForRecord(visibleRecords[0]));
+ function insertDiscontinuity(previousRecord, discontinuity, nextRecord)
+ {
+ console.assert(previousRecord || nextRecord);
+ if (!(previousRecord || nextRecord))
+ return;
+
+ let xStart = xScale(discontinuity.startTime);
+ let xEnd = xScale(discontinuity.endTime);
+
+ // Extend the previous record to the start of the discontinuity.
+ if (previousRecord)
+ this._chart.addPointSet(xStart, pointSetForRecord(previousRecord));
+
+ let zeroValues = Array((previousRecord || nextRecord).categories.length).fill(yScale(0));
+ this._chart.addPointSet(xStart, zeroValues);
+
+ if (nextRecord) {
+ this._chart.addPointSet(xEnd, zeroValues);
+ this._chart.addPointSet(xEnd, pointSetForRecord(nextRecord));
+ } else {
+ // Extend the discontinuity to the visible end time to prevent
+ // drawing artifacts when the next record arrives.
+ this._chart.addPointSet(xScale(visibleEndTime), zeroValues);
+ }
+ }
+
// Points for visible records.
+ let previousRecord = null;
for (let record of visibleRecords) {
+ if (discontinuities.length && discontinuities[0].endTime < record.startTime) {
+ let discontinuity = discontinuities.shift();
+ insertDiscontinuity.call(this, previousRecord, discontinuity, record);
+ }
+
let x = xScale(record.startTime);
this._chart.addPointSet(x, pointSetForRecord(record));
+
+ previousRecord = record;
}
- // Extend the last value to current / end time.
- let lastRecord = visibleRecords.lastValue;
- let x = Math.floor(xScale(visibleEndTime));
- this._chart.addPointSet(x, pointSetForRecord(lastRecord));
+ if (discontinuities.length)
+ insertDiscontinuity.call(this, previousRecord, discontinuities[0], null);
+ else {
+ // Extend the last value to current / end time.
+ let lastRecord = visibleRecords.lastValue;
+ if (lastRecord.startTime <= visibleEndTime) {
+ let x = Math.floor(xScale(visibleEndTime));
+ this._chart.addPointSet(x, pointSetForRecord(lastRecord));
+ }
+ }
this._chart.updateLayout();
}
@@ -194,22 +240,6 @@
return events.slice(lowerIndex, upperIndex);
}
- _visibleRecords(startTime, endTime)
- {
- let records = this._memoryTimeline.records;
- let lowerIndex = records.lowerBound(startTime, (time, record) => time - record.timestamp);
- let upperIndex = records.upperBound(endTime, (time, record) => time - record.timestamp);
-
- // Include the record right before the start time in case it extends into this range.
- if (lowerIndex > 0)
- lowerIndex--;
- // FIXME: <https://webkit.org/b/153759> Web Inspector: Memory Timelines should better extend to future data
- // if (upperIndex !== records.length)
- // upperIndex++;
-
- return records.slice(lowerIndex, upperIndex);
- }
-
_memoryTimelineRecordAdded(event)
{
let memoryTimelineRecord = event.data.record;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineView.js (201685 => 201686)
--- trunk/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineView.js 2016-06-04 20:59:57 UTC (rev 201685)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/MemoryTimelineView.js 2016-06-04 21:09:55 UTC (rev 201686)
@@ -29,6 +29,8 @@
{
super(timeline, extraArguments);
+ this._recording = extraArguments.recording;
+
console.assert(timeline.type === WebInspector.TimelineRecord.Type.Memory, timeline);
this.element.classList.add("memory");
@@ -175,7 +177,13 @@
let graphCurrentTime = this.currentTime;
let visibleEndTime = Math.min(this.endTime, this.currentTime);
- let visibleRecords = this._visibleRecords(graphStartTime, visibleEndTime);
+ let discontinuities = this._recording.discontinuitiesInTimeRange(graphStartTime, visibleEndTime);
+
+ // Don't include the record before the graph start if the graph start is within a gap.
+ let includeRecordBeforeStart = !discontinuities.length || discontinuities[0].startTime > graphStartTime;
+
+ // FIXME: <https://webkit.org/b/153759> Web Inspector: Memory Timelines should better extend to future data
+ let visibleRecords = this.representedObject.recordsInTimeRange(graphStartTime, visibleEndTime, includeRecordBeforeStart);
if (!visibleRecords.length)
return;
@@ -205,14 +213,35 @@
for (let record of visibleRecords) {
let time = record.startTime;
+ let discontinuity = null;
+ if (discontinuities.length && discontinuities[0].endTime < time)
+ discontinuity = discontinuities.shift();
+
for (let category of record.categories) {
let categoryData = categoryDataMap[category.type];
+
+ if (discontinuity) {
+ if (categoryData.dataPoints.length) {
+ let previousDataPoint = categoryData.dataPoints.lastValue;
+ categoryData.dataPoints.push({time: discontinuity.startTime, size: previousDataPoint.size});
+ }
+
+ categoryData.dataPoints.push({time: discontinuity.startTime, size: 0});
+ categoryData.dataPoints.push({time: discontinuity.endTime, size: 0});
+ categoryData.dataPoints.push({time: discontinuity.endTime, size: category.size});
+ }
+
categoryData.dataPoints.push({time, size: category.size});
categoryData.max = Math.max(categoryData.max, category.size);
categoryData.min = Math.min(categoryData.min, category.size);
}
}
+ // If the graph end time is inside a gap, the last data point should
+ // only be extended to the start of the discontinuity.
+ if (discontinuities.length)
+ visibleEndTime = discontinuities[0].startTime;
+
function layoutCategoryView(categoryView, categoryData) {
let {dataPoints, min, max} = categoryData;
@@ -314,22 +343,6 @@
totalElement.textContent = (percent === 100 ? percent : (percent - 0.05).toFixed(1)) + "%";
}
- _visibleRecords(startTime, endTime)
- {
- let records = this.representedObject.records;
- let lowerIndex = records.lowerBound(startTime, (time, record) => time - record.timestamp);
- let upperIndex = records.upperBound(endTime, (time, record) => time - record.timestamp);
-
- // Include the record right before the start time in case it extends into this range.
- if (lowerIndex > 0)
- lowerIndex--;
- // FIXME: <https://webkit.org/b/153759> Web Inspector: Memory Timelines should better extend to future data
- // if (upperIndex !== records.length)
- // upperIndex++;
-
- return records.slice(lowerIndex, upperIndex);
- }
-
_initializeCategoryViews(record)
{
console.assert(!this._didInitializeCategories, "Should only initialize category views once");
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js (201685 => 201686)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js 2016-06-04 20:59:57 UTC (rev 201685)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js 2016-06-04 21:09:55 UTC (rev 201686)
@@ -422,6 +422,11 @@
}
}
+ discontinuitiesInTimeRange(startTime, endTime)
+ {
+ return this._recording.discontinuitiesInTimeRange(startTime, endTime);
+ }
+
// Protected
get timelineRuler()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js (201685 => 201686)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js 2016-06-04 20:59:57 UTC (rev 201685)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js 2016-06-04 21:09:55 UTC (rev 201686)
@@ -71,6 +71,7 @@
this._updating = false;
this._currentTime = NaN;
+ this._discontinuityStartTime = NaN;
this._lastUpdateTimestamp = NaN;
this._startTimeNeedsReset = true;
this._renderingFrameTimeline = null;
@@ -470,9 +471,18 @@
{
this._updateProgressView();
+ let startTime = event.data.startTime;
if (!this._updating)
- this._startUpdatingCurrentTime(event.data.startTime);
+ this._startUpdatingCurrentTime(startTime);
this._clearTimelineNavigationItem.enabled = !this._recording.readonly;
+
+ // A discontinuity occurs when the recording is stopped and resumed at
+ // a future time. Capturing started signals the end of the current
+ // discontinuity, if one exists.
+ if (!isNaN(this._discontinuityStartTime)) {
+ this._recording.addDiscontinuity(this._discontinuityStartTime, startTime);
+ this._discontinuityStartTime = NaN;
+ }
}
_capturingStopped(event)
@@ -484,6 +494,8 @@
if (this.currentTimelineView)
this._updateTimelineViewTimes(this.currentTimelineView);
+
+ this._discontinuityStartTime = event.data.endTime || this._currentTime;
}
_debuggerPaused(event)
@@ -603,6 +615,7 @@
_recordingReset(event)
{
this._currentTime = NaN;
+ this._discontinuityStartTime = NaN;
if (!this._updating) {
// Force the time ruler and views to reset to 0.