Backed out changeset 8e4fdb45e6a8 (bug 1169439) for e10s dt test failures

This commit is contained in:
Carsten "Tomcat" Book 2015-06-03 08:42:17 +02:00
parent a028b2a171
commit 69e89d53b1
9 changed files with 526 additions and 288 deletions

View File

@ -280,43 +280,23 @@ const DOM = {
/**
* A series of collapsers used by the blueprint. These functions are
* invoked on a moving window of two markers.
*
* A function determining how markers are collapsed together.
* Invoked with 3 arguments: the current parent marker, the
* current marker and a method for peeking i markers ahead. If
* nothing is returned, the marker is added as a standalone entry
* in the waterfall. Otherwise, an object needs to be returned
* with the following properties:
* - toParent: The marker to be made a new parent. Can use the current
* marker, becoming a parent itself, or make a new marker-esque
* object.
* - collapse: Whether or not this current marker should be nested within
* the current parent.
* - finalize: Whether or not the current parent should be finalized and popped
* off the stack.
*/
const CollapseFunctions = {
/**
* Combines similar markers that are consecutive into a meta marker.
*/
identical: function (parent, curr, peek) {
let next = peek(1);
// If there is a parent marker currently being filled and the current marker
// should go into the parent marker, make it so.
if (parent && parent.name == curr.name) {
let finalize = next && next.name !== curr.name;
return { collapse: true, finalize };
return { toParent: parent.name };
}
// Otherwise if the current marker is the same type as the next marker type,
// create a new parent marker containing the current marker.
let next = peek(1);
if (next && curr.name == next.name) {
return { toParent: { name: curr.name, start: curr.start }, collapse: true };
return { toParent: curr.name };
}
},
/**
* Combines similar markers that are close to each other in time into a meta marker.
*/
adjacent: function (parent, curr, peek) {
let next = peek(1);
if (next && (next.start < curr.end || next.start - curr.end <= 10 /* ms */)) {
@ -324,29 +304,35 @@ const CollapseFunctions = {
}
},
/**
* Folds this marker in parent marker if parent marker fully eclipses
* the current markers' time.
*/
child: function (parent, curr, peek) {
DOMtoDOMJS: function (parent, curr, peek) {
// If the next marker is a JavaScript marker, create a new meta parent marker
// containing the current marker.
let next = peek(1);
// If this marker is consumed by current parent, collapse
if (parent && curr.end <= parent.end) {
let finalize = next && next.end > parent.end;
return { collapse: true, finalize };
if (next && next.name == "Javascript") {
return {
forceNew: true,
toParent: "meta::DOMEvent+JS",
withData: {
type: curr.type,
eventPhase: curr.eventPhase
},
};
}
},
/**
* Turns this marker into a parent marker if the next marker
* is fully eclipsed by the current marker.
*/
parent: function (parent, curr, peek) {
let next = peek(1);
// If the next marker is fully consumed by this marker, make
// it a parent (do not collapse, the marker becomes a parent).
if (next && curr.end >= next.end) {
return { toParent: curr };
JStoDOMJS: function (parent, curr, peek) {
// If there is a parent marker currently being filled, and it's the one
// created from a `DOMEvent` via `collapseDOMIntoDOMJS`, then the current
// marker has to go into that one.
if (parent && parent.name == "meta::DOMEvent+JS") {
return {
forceEnd: true,
toParent: "meta::DOMEvent+JS",
withData: {
stack: curr.stack,
endStack: curr.endStack
},
};
}
},
};

View File

@ -10,18 +10,15 @@
loader.lazyRequireGetter(this, "TIMELINE_BLUEPRINT",
"devtools/performance/markers", true);
// Unique ID for all markers
let uid = 0;
/**
* Collapses markers into a tree-like structure.
* Collapses markers into a tree-like structure. Currently, this only goes
* one level deep.
* @param object markerNode
* @param array markersList
* @param ?object blueprint
*/
function collapseMarkersIntoNode({ markerNode, markersList, blueprint }) {
let { getCurrentParentNode, collapseMarker, addParentNode, popParentNode } = createParentNodeFactory(markerNode);
blueprint = blueprint || TIMELINE_BLUEPRINT;
function collapseMarkersIntoNode({ markerNode, markersList }) {
let [getOrCreateParentNode, getCurrentParentNode, clearParentNode] = makeParentNodeFactory();
let uid = 0;
for (let i = 0, len = markersList.length; i < len; i++) {
let curr = markersList[i];
@ -31,111 +28,114 @@ function collapseMarkersIntoNode({ markerNode, markersList, blueprint }) {
curr.uid = ++uid;
let parentNode = getCurrentParentNode();
let def = blueprint[curr.name];
let collapse = def.collapseFunc || (() => null);
let blueprint = TIMELINE_BLUEPRINT[curr.name];
let collapse = blueprint.collapseFunc || (() => null);
let peek = distance => markersList[i + distance];
let foundParent = false;
let collapseInfo = collapse(parentNode, curr, peek);
if (collapseInfo) {
let { collapse, toParent, finalize } = collapseInfo;
let { toParent, withData, forceNew, forceEnd } = collapseInfo;
// If `toParent` is an object, use it as the next parent marker
if (typeof toParent === "object") {
addParentNode(toParent);
// If the `forceNew` prop is set on the collapse info, then a new parent
// marker needs to be created even if there is one already available.
if (forceNew) {
clearParentNode();
}
// If the `toParent` prop is set on the collapse info, then this marker
// can be collapsed into a higher-level parent marker.
if (toParent) {
let parentNode = getOrCreateParentNode({
uid: ++uid,
owner: markerNode,
name: toParent,
start: curr.start,
end: curr.end
});
if (collapse) {
collapseMarker(curr);
// A parent marker, even when created, will always have at least one
// child submarker (the one which caused it to be created).
parentNode.submarkers.push(curr);
// Optionally, additional data may be stapled on this parent marker.
for (let key in withData) {
parentNode[key] = withData[key];
}
}
// If the marker specifies this parent marker is full,
// pop it from the stack.
if (finalize) {
popParentNode();
// If the `forceEnd` prop is set on the collapse info, then the higher-level
// parent marker is full and should be finalized.
if (forceEnd) {
clearParentNode();
}
} else {
clearParentNode();
markerNode.submarkers.push(curr);
}
}
}
/**
* Creates a parent marker, which functions like a regular marker,
* Creates an empty parent marker, which functions like a regular marker,
* but is able to hold additional child markers.
*
* The marker is seeded with values from `marker`.
* @param object marker
* @param string name
* @param number uid
* @param number start [optional]
* @param number end [optional]
* @return object
*/
function makeParentMarkerNode (marker) {
let node = Object.create(null);
for (let prop in marker) {
node[prop] = marker[prop];
}
if (!node.uid) {
node.uid = ++uid;
}
node.submarkers = [];
return node;
function makeEmptyMarkerNode(name, uid, start, end) {
return {
name: name,
uid: uid,
start: start,
end: end,
submarkers: []
};
}
/**
* Takes a root marker node and creates a hash of functions used
* to manage the creation and nesting of additional parent markers.
*
* @param {object} root
* @return {object}
* Creates a factory for markers containing other markers.
* @return array[function]
*/
function createParentNodeFactory (root) {
let parentMarkers = [];
let factory = {
/**
* Pops the most recent parent node off the stack, finalizing it.
* Sets the `end` time based on the most recent child if not defined.
*/
popParentNode: () => {
if (parentMarkers.length === 0) {
throw new Error("Cannot pop parent markers when none exist.");
}
function makeParentNodeFactory() {
let marker;
let lastParent = parentMarkers.pop();
// If this finished parent marker doesn't have an end time,
// so probably a synthesized marker, use the last marker's end time.
if (lastParent.end == void 0) {
lastParent.end = lastParent.submarkers[lastParent.submarkers.length - 1].end;
return [
/**
* Gets the current parent marker for the given marker name. If it doesn't
* exist, it creates it and appends it to another parent marker.
* @param object owner
* @param string name
* @param number start
* @param number end
* @return object
*/
function getOrCreateParentNode({ owner, name, uid, start, end }) {
if (marker && marker.name == name) {
marker.end = end;
return marker;
} else {
marker = makeEmptyMarkerNode(name, uid, start, end);
owner.submarkers.push(marker);
return marker;
}
return lastParent;
},
/**
* Returns the most recent parent node.
* Gets the current marker marker.
* @return object
*/
getCurrentParentNode: () => parentMarkers.length ? parentMarkers[parentMarkers.length - 1] : null,
/**
* Push a new parent node onto the stack and nest it with the
* next most recent parent node, or root if no other parent nodes.
*/
addParentNode: (marker) => {
let parentMarker = makeParentMarkerNode(marker);
(factory.getCurrentParentNode() || root).submarkers.push(parentMarker);
parentMarkers.push(parentMarker);
function getCurrentParentNode() {
return marker;
},
/**
* Push this marker into the most recent parent node.
* Clears the current marker marker.
*/
collapseMarker: (marker) => {
if (parentMarkers.length === 0) {
throw new Error("Cannot collapse marker with no parents.");
}
factory.getCurrentParentNode().submarkers.push(marker);
function clearParentNode() {
marker = null;
}
};
return factory;
];
}
exports.makeParentMarkerNode = makeParentMarkerNode;
exports.makeEmptyMarkerNode = makeEmptyMarkerNode;
exports.collapseMarkersIntoNode = collapseMarkersIntoNode;

View File

@ -4,7 +4,7 @@
"use strict";
const { L10N } = require("devtools/performance/global");
const { Formatters, CollapseFunctions: collapse } = require("devtools/performance/marker-utils");
const { Formatters, CollapseFunctions } = require("devtools/performance/marker-utils");
/**
* A simple schema for mapping markers to the timeline UI. The keys correspond
@ -29,13 +29,15 @@ const { Formatters, CollapseFunctions: collapse } = require("devtools/performanc
* nothing is returned, the marker is added as a standalone entry
* in the waterfall. Otherwise, an object needs to be returned
* with the following properties:
* - toParent: The marker to be made a new parent. Can use the current
* marker, becoming a parent itself, or make a new marker-esque
* object.
* - collapse: Whether or not this current marker should be nested within
* the current parent.
* - finalize: Whether or not the current parent should be finalized and popped
* off the stack.
* - toParent: The parent marker name (needs to be an entry in
* the `TIMELINE_BLUEPRINT` itself).
* - withData: An object containing some properties to staple
* on the parent marker.
* - forceNew: True if a new parent marker needs to be created
* even though there is one currently available
* with the same name.
* - forceEnd: True if the current parent marker is full after
* this collapse operation and should be finalized.
* - fields: An optional array of marker properties you wish to display in the
* marker details view. For example, a field in the array such as
* { property: "aCauseName", label: "Cause" } would render a string
@ -59,20 +61,20 @@ const TIMELINE_BLUEPRINT = {
"Styles": {
group: 0,
colorName: "graphs-purple",
collapseFunc: collapse.child,
collapseFunc: CollapseFunctions.identical,
label: L10N.getStr("timeline.label.styles2"),
fields: Formatters.StylesFields,
},
"Reflow": {
group: 0,
colorName: "graphs-purple",
collapseFunc: collapse.child,
collapseFunc: CollapseFunctions.identical,
label: L10N.getStr("timeline.label.reflow2"),
},
"Paint": {
group: 0,
colorName: "graphs-green",
collapseFunc: collapse.child,
collapseFunc: CollapseFunctions.identical,
label: L10N.getStr("timeline.label.paint"),
},
@ -80,33 +82,38 @@ const TIMELINE_BLUEPRINT = {
"DOMEvent": {
group: 1,
colorName: "graphs-yellow",
collapseFunc: collapse.parent,
collapseFunc: CollapseFunctions.DOMtoDOMJS,
label: L10N.getStr("timeline.label.domevent"),
fields: Formatters.DOMEventFields,
},
"Javascript": {
group: 1,
colorName: "graphs-yellow",
collapseFunc: either(collapse.parent, collapse.child),
collapseFunc: either(CollapseFunctions.JStoDOMJS, CollapseFunctions.identical),
label: Formatters.JSLabel,
fields: Formatters.JSFields
},
"meta::DOMEvent+JS": {
colorName: "graphs-yellow",
label: Formatters.DOMJSLabel,
fields: Formatters.DOMJSFields,
},
"Parse HTML": {
group: 1,
colorName: "graphs-yellow",
collapseFunc: either(collapse.parent, collapse.child),
collapseFunc: CollapseFunctions.identical,
label: L10N.getStr("timeline.label.parseHTML"),
},
"Parse XML": {
group: 1,
colorName: "graphs-yellow",
collapseFunc: either(collapse.parent, collapse.child),
collapseFunc: CollapseFunctions.identical,
label: L10N.getStr("timeline.label.parseXML"),
},
"GarbageCollection": {
group: 1,
colorName: "graphs-red",
collapseFunc: either(collapse.parent, collapse.child),
collapseFunc: CollapseFunctions.adjacent,
label: Formatters.GCLabel,
fields: [
{ property: "causeName", label: "Reason:" },
@ -127,7 +134,6 @@ const TIMELINE_BLUEPRINT = {
"TimeStamp": {
group: 2,
colorName: "graphs-blue",
collapseFunc: collapse.child,
label: sublabelForProperty(L10N.getStr("timeline.label.timestamp"), "causeName"),
fields: [{
property: "causeName",

View File

@ -138,3 +138,4 @@ skip-if = e10s # GC events seem unreliable in multiprocess
[browser_timeline-waterfall-rerender.js]
[browser_timeline-waterfall-sidebar.js]
skip-if = os == 'linux' # Bug 1161817
[browser_waterfall-collapse.js]

View File

@ -0,0 +1,392 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the waterfall collapsing logic works properly.
*/
function test() {
const WaterfallUtils = devtools.require("devtools/performance/waterfall-utils");
let rootMarkerNode = WaterfallUtils.makeEmptyMarkerNode("(root)");
WaterfallUtils.collapseMarkersIntoNode({
markerNode: rootMarkerNode,
markersList: gTestMarkers
});
is(rootMarkerNode.toSource(), gExpectedOutput.toSource(),
"The markers didn't collapse properly.");
finish();
}
const gTestMarkers = [
// Test collapsing Style markers
{
start: 1,
end: 2,
name: "Styles"
},
{
start: 3,
end: 4,
name: "Styles"
},
// Test collapsing Reflow markers
{
start: 5,
end: 6,
name: "Reflow"
},
{
start: 7,
end: 8,
name: "Reflow"
},
// Test collapsing Paint markers
{
start: 9,
end: 10,
name: "Paint"
}, {
start: 11,
end: 12,
name: "Paint"
},
// Test standalone DOMEvent markers followed by a different marker
{
start: 13,
end: 14,
name: "DOMEvent",
eventPhase: 1,
type: "foo1"
},
{
start: 15,
end: 16,
name: "TimeStamp"
},
// Test a DOMEvent marker followed by a Javascript marker.
{
start: 17,
end: 18,
name: "DOMEvent",
eventPhase: 2,
type: "foo2"
}, {
start: 19,
end: 20,
name: "Javascript",
stack: 1,
endStack: 2
},
// Test another DOMEvent marker followed by a Javascript marker.
{
start: 21,
end: 22,
name: "DOMEvent",
eventPhase: 3,
type: "foo3"
}, {
start: 23,
end: 24,
name: "Javascript",
stack: 3,
endStack: 4
},
// Test a DOMEvent marker followed by multiple Javascript markers.
{
start: 25,
end: 26,
name: "DOMEvent",
eventPhase: 4,
type: "foo4"
}, {
start: 27,
end: 28,
name: "Javascript",
stack: 5,
endStack: 6
}, {
start: 29,
end: 30,
name: "Javascript",
stack: 7,
endStack: 8
}, {
start: 31,
end: 32,
name: "Javascript",
stack: 9,
endStack: 10
},
// Test multiple DOMEvent markers followed by multiple Javascript markers.
{
start: 33,
end: 34,
name: "DOMEvent",
eventPhase: 5,
type: "foo5"
}, {
start: 35,
end: 36,
name: "DOMEvent",
eventPhase: 6,
type: "foo6"
}, {
start: 37,
end: 38,
name: "DOMEvent",
eventPhase: 7,
type: "foo6"
}, {
start: 39,
end: 40,
name: "Javascript",
stack: 11,
endStack: 12
}, {
start: 41,
end: 42,
name: "Javascript",
stack: 13,
endStack: 14
}, {
start: 43,
end: 44,
name: "Javascript",
stack: 15,
endStack: 16
},
// Test a lonely marker at the end.
{
start: 45,
end: 46,
name: "GarbageCollection"
}
];
const gExpectedOutput = {
name: "(root)",
uid: (void 0),
start: (void 0),
end: (void 0),
submarkers: [{
name: "Styles",
uid: 2,
start: 1,
end: 4,
submarkers: [{
start: 1,
end: 2,
name: "Styles",
uid: 1
}, {
start: 3,
end: 4,
name: "Styles",
uid: 3
}]
}, {
name: "Reflow",
uid: 6,
start: 5,
end: 8,
submarkers: [{
start: 5,
end: 6,
name: "Reflow",
uid: 5
}, {
start: 7,
end: 8,
name: "Reflow",
uid: 7
}]
}, {
name: "Paint",
uid: 10,
start: 9,
end: 12,
submarkers: [{
start: 9,
end: 10,
name: "Paint",
uid: 9
}, {
start: 11,
end: 12,
name: "Paint",
uid: 11
}]
}, {
start: 13,
end: 14,
name: "DOMEvent",
eventPhase: 1,
type: "foo1",
uid: 13
}, {
start: 15,
end: 16,
name: "TimeStamp",
uid: 14
}, {
name: "meta::DOMEvent+JS",
uid: 16,
start: 17,
end: 20,
submarkers: [{
start: 17,
end: 18,
name: "DOMEvent",
eventPhase: 2,
type: "foo2",
uid: 15
}, {
start: 19,
end: 20,
name: "Javascript",
stack: 1,
endStack: 2,
uid: 17
}],
type: "foo2",
eventPhase: 2,
stack: 1,
endStack: 2
}, {
name: "meta::DOMEvent+JS",
uid: 20,
start: 21,
end: 24,
submarkers: [{
start: 21,
end: 22,
name: "DOMEvent",
eventPhase: 3,
type: "foo3",
uid: 19
}, {
start: 23,
end: 24,
name: "Javascript",
stack: 3,
endStack: 4,
uid: 21
}],
type: "foo3",
eventPhase: 3,
stack: 3,
endStack: 4
}, {
name: "meta::DOMEvent+JS",
uid: 24,
start: 25,
end: 28,
submarkers: [{
start: 25,
end: 26,
name: "DOMEvent",
eventPhase: 4,
type: "foo4",
uid: 23
}, {
start: 27,
end: 28,
name: "Javascript",
stack: 5,
endStack: 6,
uid: 25
}],
type: "foo4",
eventPhase: 4,
stack: 5,
endStack: 6
}, {
name: "Javascript",
uid: 28,
start: 29,
end: 32,
submarkers: [{
start: 29,
end: 30,
name: "Javascript",
stack: 7,
endStack: 8,
uid: 27
}, {
start: 31,
end: 32,
name: "Javascript",
stack: 9,
endStack: 10,
uid: 29
}]
}, {
start: 33,
end: 34,
name: "DOMEvent",
eventPhase: 5,
type: "foo5",
uid: 31
}, {
start: 35,
end: 36,
name: "DOMEvent",
eventPhase: 6,
type: "foo6",
uid: 32
}, {
name: "meta::DOMEvent+JS",
uid: 34,
start: 37,
end: 40,
submarkers: [{
start: 37,
end: 38,
name: "DOMEvent",
eventPhase: 7,
type: "foo6",
uid: 33
}, {
start: 39,
end: 40,
name: "Javascript",
stack: 11,
endStack: 12,
uid: 35
}],
type: "foo6",
eventPhase: 7,
stack: 11,
endStack: 12
}, {
name: "Javascript",
uid: 38,
start: 41,
end: 44,
submarkers: [{
start: 41,
end: 42,
name: "Javascript",
stack: 13,
endStack: 14,
uid: 37
}, {
start: 43,
end: 44,
name: "Javascript",
stack: 15,
endStack: 16,
uid: 39
}]
}, {
start: 45,
end: 46,
name: "GarbageCollection",
uid: 41
}]
};

View File

@ -1,67 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the waterfall collapsing logic works properly.
*/
function test() {
const WaterfallUtils = devtools.require("devtools/performance/waterfall-utils");
let rootMarkerNode = WaterfallUtils.makeParentMarkerNode({ name: "(root)" });
WaterfallUtils.collapseMarkersIntoNode({
markerNode: rootMarkerNode,
markersList: gTestMarkers
});
function compare (marker, expected) {
for (let prop in expected) {
if (prop === "submarkers") {
for (let i = 0; i < expected.submarkers.length; i++) {
compare(marker.submarkers[i], expected.submarkers[i]);
}
} else if (prop !== "uid") {
is(marker[prop], expected[prop], `${expected.name} matches ${prop}`);
}
}
}
compare(rootMarkerNode, gExpectedOutput);
finish();
}
const gTestMarkers = [
{ start: 1, end: 18, name: "DOMEvent" },
// Test that JS markers can fold in DOM events and have marker children
{ start: 2, end: 16, name: "Javascript" },
// Test all these markers can be children
{ start: 3, end: 4, name: "Paint" },
{ start: 5, end: 6, name: "Reflow" },
{ start: 7, end: 8, name: "Styles" },
{ start: 9, end: 9, name: "TimeStamp" },
{ start: 10, end: 11, name: "Parse HTML" },
{ start: 12, end: 13, name: "Parse XML" },
{ start: 14, end: 15, name: "GarbageCollection" },
// Test that JS markers can be parents without being a child of DOM events
{ start: 25, end: 30, name: "JavaScript" },
{ start: 26, end: 27, name: "Paint" },
];
const gExpectedOutput = {
name: "(root)", submarkers: [
{ start: 1, end: 18, name: "DOMEvent", submarkers: [
{ start: 2, end: 16, name: "Javascript", submarkers: [
{ start: 3, end: 4, name: "Paint" },
{ start: 5, end: 6, name: "Reflow" },
{ start: 7, end: 8, name: "Styles" },
{ start: 9, end: 9, name: "TimeStamp" },
{ start: 10, end: 11, name: "Parse HTML" },
{ start: 12, end: 13, name: "Parse XML" },
{ start: 14, end: 15, name: "GarbageCollection" },
]}
]},
{ start: 25, end: 30, name: "JavaScript", submarkers: [
{ start: 26, end: 27, name: "Paint" },
]}
]};

View File

@ -1,78 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the waterfall collapsing logic works properly for console.time/console.timeEnd
* markers, as they should ignore any sort of collapsing.
*/
function test() {
const WaterfallUtils = devtools.require("devtools/performance/waterfall-utils");
let rootMarkerNode = WaterfallUtils.makeParentMarkerNode({ name: "(root)" });
WaterfallUtils.collapseMarkersIntoNode({
markerNode: rootMarkerNode,
markersList: gTestMarkers
});
function compare (marker, expected) {
for (let prop in expected) {
if (prop === "submarkers") {
for (let i = 0; i < expected.submarkers.length; i++) {
compare(marker.submarkers[i], expected.submarkers[i]);
}
} else if (prop !== "uid") {
is(marker[prop], expected[prop], `${expected.name} matches ${prop}`);
}
}
}
compare(rootMarkerNode, gExpectedOutput);
finish();
}
const gTestMarkers = [
{ start: 2, end: 9, name: "Javascript" },
{ start: 3, end: 4, name: "Paint" },
// Time range starting in nest, ending outside
{ start: 5, end: 12, name: "ConsoleTime", causeName: "1" },
// Time range starting outside of nest, ending inside
{ start: 15, end: 21, name: "ConsoleTime", causeName: "2" },
{ start: 18, end: 22, name: "Javascript" },
{ start: 19, end: 20, name: "Paint" },
// Time range completely eclipsing nest
{ start: 30, end: 40, name: "ConsoleTime", causeName: "3" },
{ start: 34, end: 39, name: "Javascript" },
{ start: 35, end: 36, name: "Paint" },
// Time range completely eclipsed by nest
{ start: 50, end: 60, name: "Javascript" },
{ start: 54, end: 59, name: "ConsoleTime", causeName: "4" },
{ start: 56, end: 57, name: "Paint" },
];
const gExpectedOutput = {
name: "(root)", submarkers: [
{ start: 2, end: 9, name: "Javascript", submarkers: [
{ start: 3, end: 4, name: "Paint" }
]},
{ start: 5, end: 12, name: "ConsoleTime", causeName: "1" },
{ start: 15, end: 21, name: "ConsoleTime", causeName: "2" },
{ start: 18, end: 22, name: "Javascript", submarkers: [
{ start: 19, end: 20, name: "Paint" }
]},
{ start: 30, end: 40, name: "ConsoleTime", causeName: "3" },
{ start: 34, end: 39, name: "Javascript", submarkers: [
{ start: 35, end: 36, name: "Paint" },
]},
{ start: 50, end: 60, name: "Javascript", submarkers: [
{ start: 56, end: 57, name: "Paint" },
]},
{ start: 54, end: 59, name: "ConsoleTime", causeName: "4" },
]};

View File

@ -17,5 +17,3 @@ skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_tree-model-07.js]
[test_tree-model-08.js]
[test_tree-model-09.js]
[test_waterfall-utils-collapse-01.js]
[test_waterfall-utils-collapse-02.js]

View File

@ -132,7 +132,7 @@ let WaterfallView = Heritage.extend(DetailsSubview, {
return cached;
}
let rootMarkerNode = WaterfallUtils.makeParentMarkerNode({ name: "(root)" });
let rootMarkerNode = WaterfallUtils.makeEmptyMarkerNode("(root)");
WaterfallUtils.collapseMarkersIntoNode({
markerNode: rootMarkerNode,