Bug 1167300 - Consolidate the performance tool directory, r=jsantell

--HG--
rename : browser/devtools/shared/timeline/global.js => browser/devtools/performance/modules/global.js
rename : browser/devtools/performance/modules/actors.js => browser/devtools/performance/modules/logic/actors.js
rename : browser/devtools/performance/modules/compatibility.js => browser/devtools/performance/modules/logic/compatibility.js
rename : browser/devtools/shared/profiler/frame-utils.js => browser/devtools/performance/modules/logic/frame-utils.js
rename : browser/devtools/performance/modules/front.js => browser/devtools/performance/modules/logic/front.js
rename : browser/devtools/performance/modules/io.js => browser/devtools/performance/modules/logic/io.js
rename : browser/devtools/shared/profiler/jit.js => browser/devtools/performance/modules/logic/jit.js
rename : browser/devtools/shared/timeline/marker-utils.js => browser/devtools/performance/modules/logic/marker-utils.js
rename : browser/devtools/performance/modules/recording-model.js => browser/devtools/performance/modules/logic/recording-model.js
rename : browser/devtools/performance/modules/recording-utils.js => browser/devtools/performance/modules/logic/recording-utils.js
rename : browser/devtools/shared/profiler/tree-model.js => browser/devtools/performance/modules/logic/tree-model.js
rename : browser/devtools/performance/modules/graphs.js => browser/devtools/performance/modules/widgets/graphs.js
rename : browser/devtools/shared/timeline/marker-details.js => browser/devtools/performance/modules/widgets/marker-details.js
rename : browser/devtools/shared/timeline/markers-overview.js => browser/devtools/performance/modules/widgets/markers-overview.js
rename : browser/devtools/shared/profiler/tree-view.js => browser/devtools/performance/modules/widgets/tree-view.js
rename : browser/devtools/shared/timeline/waterfall.js => browser/devtools/performance/modules/widgets/waterfall.js
This commit is contained in:
Victor Porof 2015-05-22 16:25:52 -04:00
Родитель 8f77347ec6
Коммит 4b7d7bd9d0
25 изменённых файлов: 390 добавлений и 370 удалений

Просмотреть файл

@ -0,0 +1,357 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {Cc, Ci, Cu, Cr} = require("chrome");
loader.lazyRequireGetter(this, "ViewHelpers",
"resource:///modules/devtools/ViewHelpers.jsm", true);
loader.lazyRequireGetter(this, "Services");
// String used to fill in platform data when it should be hidden.
const GECKO_SYMBOL = "(Gecko)";
/**
* Localization convenience methods.
+ TODO: merge these into a single file: Bug 1082695.
*/
const TIMELINE_STRINGS_URI = "chrome://browser/locale/devtools/timeline.properties";
const PROFILER_STRINGS_URI = "chrome://browser/locale/devtools/profiler.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
/**
* A list of preferences for this tool. The values automatically update
* if somebody edits edits about:config or the prefs change somewhere else.
*/
const Prefs = new ViewHelpers.Prefs("devtools.performance.ui", {
showPlatformData: ["Bool", "show-platform-data"]
}, {
monitorChanges: true
});
/**
* Details about each profile entry cateogry.
* @see CATEGORY_MAPPINGS.
*/
const CATEGORIES = [{
ordinal: 7,
color: "#5e88b0",
abbrev: "other",
label: L10N.getStr("category.other")
}, {
ordinal: 4,
color: "#46afe3",
abbrev: "css",
label: L10N.getStr("category.css")
}, {
ordinal: 1,
color: "#d96629",
abbrev: "js",
label: L10N.getStr("category.js")
}, {
ordinal: 2,
color: "#eb5368",
abbrev: "gc",
label: L10N.getStr("category.gc")
}, {
ordinal: 0,
color: "#df80ff",
abbrev: "network",
label: L10N.getStr("category.network")
}, {
ordinal: 5,
color: "#70bf53",
abbrev: "graphics",
label: L10N.getStr("category.graphics")
}, {
ordinal: 6,
color: "#8fa1b2",
abbrev: "storage",
label: L10N.getStr("category.storage")
}, {
ordinal: 3,
color: "#d99b28",
abbrev: "events",
label: L10N.getStr("category.events")
}];
/**
* Mapping from category bitmasks in the profiler data to additional details.
* To be kept in sync with the js::ProfileEntry::Category in ProfilingStack.h
*/
const CATEGORY_MAPPINGS = {
"16": CATEGORIES[0], // js::ProfileEntry::Category::OTHER
"32": CATEGORIES[1], // js::ProfileEntry::Category::CSS
"64": CATEGORIES[2], // js::ProfileEntry::Category::JS
"128": CATEGORIES[3], // js::ProfileEntry::Category::GC
"256": CATEGORIES[3], // js::ProfileEntry::Category::CC
"512": CATEGORIES[4], // js::ProfileEntry::Category::NETWORK
"1024": CATEGORIES[5], // js::ProfileEntry::Category::GRAPHICS
"2048": CATEGORIES[6], // js::ProfileEntry::Category::STORAGE
"4096": CATEGORIES[7], // js::ProfileEntry::Category::EVENTS
};
/**
* A simple schema for mapping markers to the timeline UI. The keys correspond
* to marker names, while the values are objects with the following format:
*
* - group: The row index in the timeline overview graph; multiple markers
* can be added on the same row. @see <overview.js/buildGraphImage>
* - label: The label used in the waterfall to identify the marker. Can be a
* string or just a function that accepts the marker and returns a
* string, if you want to use a dynamic property for the main label.
* If you use a function for a label, it *must* handle the case where
* no marker is provided for a main label to describe all markers of
* this type.
* - colorName: The label of the DevTools color used for this marker. If
* adding a new color, be sure to check that there's an entry
* for `.marker-details-bullet.{COLORNAME}` for the equivilent
* entry in ./browser/themes/shared/devtools/performance.inc.css
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors
* - 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
* like `Cause: ${marker.aCauseName}` in the marker details view.
* Each `field` item may take the following properties:
* - property: The property that must exist on the marker to render,
* and the value of the property will be displayed.
* - label: The name of the property that should be displayed.
* - formatter: If a formatter is provided, instead of directly using
* the `property` property on the marker, the marker is
* passed into the formatter function to determine the
* displayed value.
* Can also be a function that returns an object. Each key in the object
* will be rendered as a field, with its value rendering as the value.
*
* Whenever this is changed, browser_timeline_waterfall-styles.js *must* be
* updated as well.
*/
const TIMELINE_BLUEPRINT = {
/* Group 0 - Reflow and Rendering pipeline */
"Styles": {
group: 0,
colorName: "graphs-purple",
label: L10N.getStr("timeline.label.styles2"),
fields: getStylesFields,
},
"Reflow": {
group: 0,
colorName: "graphs-purple",
label: L10N.getStr("timeline.label.reflow2")
},
"Paint": {
group: 0,
colorName: "graphs-green",
label: L10N.getStr("timeline.label.paint")
},
/* Group 1 - JS */
"DOMEvent": {
group: 1,
colorName: "graphs-yellow",
label: L10N.getStr("timeline.label.domevent"),
fields: getDOMEventFields,
},
"Javascript": {
group: 1,
colorName: "graphs-yellow",
label: getJSLabel,
fields: getJSFields,
},
"Parse HTML": {
group: 1,
colorName: "graphs-yellow",
label: L10N.getStr("timeline.label.parseHTML")
},
"Parse XML": {
group: 1,
colorName: "graphs-yellow",
label: L10N.getStr("timeline.label.parseXML")
},
"GarbageCollection": {
group: 1,
colorName: "graphs-red",
label: getGCLabel,
fields: [
{ property: "causeName", label: "Reason:" },
{ property: "nonincrementalReason", label: "Non-incremental Reason:" }
]
},
/* Group 2 - User Controlled */
"ConsoleTime": {
group: 2,
colorName: "graphs-grey",
label: sublabelForProperty(L10N.getStr("timeline.label.consoleTime"), "causeName"),
fields: [{
property: "causeName",
label: L10N.getStr("timeline.markerDetail.consoleTimerName")
}]
},
"TimeStamp": {
group: 2,
colorName: "graphs-blue",
label: sublabelForProperty(L10N.getStr("timeline.label.timestamp"), "causeName"),
fields: [{
property: "causeName",
label: "Label:"
}]
},
};
/**
* A series of formatters used by the blueprint.
*/
function getGCLabel (marker={}) {
let label = L10N.getStr("timeline.label.garbageCollection");
// Only if a `nonincrementalReason` exists, do we want to label
// this as a non incremental GC event.
if ("nonincrementalReason" in marker) {
label = `${label} (Non-incremental)`;
}
return label;
}
/**
* Mapping of JS marker causes to a friendlier form. Only
* markers that are considered "from content" should be labeled here.
*/
const JS_MARKER_MAP = {
"<script> element": "Script Tag",
"setInterval handler": "setInterval",
"setTimeout handler": "setTimeout",
"FrameRequestCallback": "requestAnimationFrame",
"promise callback": "Promise Callback",
"promise initializer": "Promise Init",
"Worker runnable": "Worker",
"javascript: URI": "JavaScript URI",
// The difference between these two event handler markers are differences
// in their WebIDL implementation, so distinguishing them is not necessary.
"EventHandlerNonNull": "Event Handler",
"EventListener.handleEvent": "Event Handler",
};
function getJSLabel (marker={}) {
let generic = L10N.getStr("timeline.label.javascript2");
if ("causeName" in marker) {
return JS_MARKER_MAP[marker.causeName] || generic;
}
return generic;
}
/**
* Returns a hash for computing a fields object for a JS marker. If the cause
* is considered content (so an entry exists in the JS_MARKER_MAP), do not display it
* since it's redundant with the label. Otherwise for Gecko code, either display
* the cause, or "(Gecko)", depending on if "show-platform-data" is set.
*/
function getJSFields (marker) {
if ("causeName" in marker && !JS_MARKER_MAP[marker.causeName]) {
return { Reason: Prefs.showPlatformData ? marker.causeName : GECKO_SYMBOL };
}
}
function getDOMEventFields (marker) {
let fields = Object.create(null);
if ("type" in marker) {
fields[L10N.getStr("timeline.markerDetail.DOMEventType")] = marker.type;
}
if ("eventPhase" in marker) {
let phase;
if (marker.eventPhase === Ci.nsIDOMEvent.AT_TARGET) {
phase = L10N.getStr("timeline.markerDetail.DOMEventTargetPhase");
} else if (marker.eventPhase === Ci.nsIDOMEvent.CAPTURING_PHASE) {
phase = L10N.getStr("timeline.markerDetail.DOMEventCapturingPhase");
} else if (marker.eventPhase === Ci.nsIDOMEvent.BUBBLING_PHASE) {
phase = L10N.getStr("timeline.markerDetail.DOMEventBubblingPhase");
}
fields[L10N.getStr("timeline.markerDetail.DOMEventPhase")] = phase;
}
return fields;
}
function getStylesFields (marker) {
if ("restyleHint" in marker) {
return { "Restyle Hint": marker.restyleHint.replace(/eRestyle_/g, "") };
}
}
/**
* Takes a main label (like "Timestamp") and a property,
* and returns a marker that will print out the property
* value for a marker if it exists ("Timestamp (rendering)"),
* or just the main label if it does not.
*/
function sublabelForProperty (mainLabel, prop) {
return (marker={}) => marker[prop] ? `${mainLabel} (${marker[prop]})` : mainLabel;
}
/**
* Get the numeric bitmask (or set of masks) for the given category
* abbreviation. See CATEGORIES and CATEGORY_MAPPINGS above.
*
* CATEGORY_MASK can be called with just a name if it is expected that the
* category is mapped to by exactly one bitmask. If the category is mapped
* to by multiple masks, CATEGORY_MASK for that name must be called with
* an additional argument specifying the desired id (in ascending order).
*/
const [CATEGORY_MASK, CATEGORY_MASK_LIST] = (function () {
let bitmasksForCategory = {};
let all = Object.keys(CATEGORY_MAPPINGS);
for (let category of CATEGORIES) {
bitmasksForCategory[category.abbrev] = all
.filter(mask => CATEGORY_MAPPINGS[mask] == category)
.map(mask => +mask)
.sort();
}
return [
function (name, index) {
if (!(name in bitmasksForCategory)) {
throw new Error(`Category abbreviation '${name}' does not exist.`);
}
if (arguments.length == 1) {
if (bitmasksForCategory[name].length != 1) {
throw new Error(`Expected exactly one category number for '${name}'.`);
} else {
return bitmasksForCategory[name][0];
}
} else {
if (index > bitmasksForCategory[name].length) {
throw new Error(`Index '${index}' too high for category '${name}'.`);
} else {
return bitmasksForCategory[name][index - 1];
}
}
},
function (name) {
if (!(name in bitmasksForCategory)) {
throw new Error(`Category abbreviation '${name}' does not exist.`);
}
return bitmasksForCategory[name];
}
];
})();
// Human-readable "other" category bitmask. Older Geckos don't have all the
// necessary instrumentation in the sampling profiler backend for creating
// a categories graph, in which case we default to the "other" category.
const CATEGORY_OTHER = CATEGORY_MASK('other');
// Human-readable JIT category bitmask. Certain pseudo-frames in a sample,
// like "EnterJIT", don't have any associated `cateogry` information.
const CATEGORY_JIT = CATEGORY_MASK('js');
// Exported symbols.
exports.L10N = L10N;
exports.TIMELINE_BLUEPRINT = TIMELINE_BLUEPRINT;
exports.CATEGORIES = CATEGORIES;
exports.CATEGORY_MAPPINGS = CATEGORY_MAPPINGS;
exports.CATEGORY_MASK = CATEGORY_MASK;
exports.CATEGORY_MASK_LIST = CATEGORY_MASK_LIST;
exports.CATEGORY_OTHER = CATEGORY_OTHER;
exports.CATEGORY_JIT = CATEGORY_JIT;

Просмотреть файл

@ -23,7 +23,7 @@ const SUCCESSFUL_OUTCOMES = [
* An OptimizationSite contains a record of how many times the
* RawOptimizationSite was sampled, as well as the unique id based off of the
* original profiler array, and the RawOptimizationSite itself as a reference.
* @see browser/devtools/shared/profiler/tree-model.js
* @see browser/devtools/performance/modules/logic/tree-model.js
*
* @struct RawOptimizationSite
* A structure describing a location in a script that was attempted to be optimized.

Просмотреть файл

@ -4,13 +4,22 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES.devtools.performance += [
'modules/actors.js',
'modules/compatibility.js',
'modules/front.js',
'modules/graphs.js',
'modules/io.js',
'modules/recording-model.js',
'modules/recording-utils.js',
'modules/global.js',
'modules/logic/actors.js',
'modules/logic/compatibility.js',
'modules/logic/frame-utils.js',
'modules/logic/front.js',
'modules/logic/io.js',
'modules/logic/jit.js',
'modules/logic/marker-utils.js',
'modules/logic/recording-model.js',
'modules/logic/recording-utils.js',
'modules/logic/tree-model.js',
'modules/widgets/graphs.js',
'modules/widgets/marker-details.js',
'modules/widgets/markers-overview.js',
'modules/widgets/tree-view.js',
'modules/widgets/waterfall.js',
'panel.js'
]

Просмотреть файл

@ -17,7 +17,6 @@
<script type="application/javascript" src="performance/system.js"/>
<script type="application/javascript" src="performance/performance-controller.js"/>
<script type="application/javascript" src="performance/performance-view.js"/>
<script type="application/javascript" src="performance/recording-model.js"/>
<script type="application/javascript" src="performance/views/overview.js"/>
<script type="application/javascript" src="performance/views/toolbar.js"/>
<script type="application/javascript" src="performance/views/details-subview.js"/>

Просмотреть файл

@ -4,7 +4,7 @@
/**
* Tests if the retrieved profiler data samples always have a (root) node.
* If this ever changes, the |ThreadNode.prototype.insert| function in
* browser/devtools/profiler/utils/tree-model.js will have to be changed.
* browser/devtools/performance/modules/logic/tree-model.js will have to be changed.
*/
const WAIT_TIME = 1000; // ms

Просмотреть файл

@ -12,7 +12,7 @@ const PROPNAME_MAX_LENGTH = 4;
/**
* View for rendering JIT Optimization data. The terminology and types
* used here can be referenced:
* @see browser/devtools/shared/profiler/jit.js
* @see browser/devtools/performance/modules/logic/jit.js
*/
let JITOptimizationsView = {
@ -243,7 +243,7 @@ let JITOptimizationsView = {
/**
* Creates an element for insertion in the raw view for an IonType.
*
* @see browser/devtools/shared/profiler/jit.js
* @see browser/devtools/performance/modules/logic/jit.js
* @param {IonType} ionType
* @return {Element}
*/
@ -258,7 +258,7 @@ let JITOptimizationsView = {
/**
* Creates an element for insertion in the raw view for an ObservedType.
*
* @see browser/devtools/shared/profiler/jit.js
* @see browser/devtools/performance/modules/logic/jit.js
* @param {ObservedType} type
* @return {Element}
*/
@ -298,7 +298,7 @@ let JITOptimizationsView = {
/**
* Creates an element for insertion in the raw view for an OptimizationAttempt.
*
* @see browser/devtools/shared/profiler/jit.js
* @see browser/devtools/performance/modules/logic/jit.js
* @param {OptimizationAttempt} attempt
* @return {Element}
*/

Просмотреть файл

@ -30,22 +30,6 @@ EXTRA_JS_MODULES.devtools += [
'widgets/ViewHelpers.jsm',
]
EXTRA_JS_MODULES.devtools.shared.profiler += [
'profiler/frame-utils.js',
'profiler/global.js',
'profiler/jit.js',
'profiler/tree-model.js',
'profiler/tree-view.js',
]
EXTRA_JS_MODULES.devtools.shared.timeline += [
'timeline/global.js',
'timeline/marker-details.js',
'timeline/marker-utils.js',
'timeline/markers-overview.js',
'timeline/waterfall.js',
]
EXTRA_JS_MODULES.devtools.shared += [
'autocomplete-popup.js',
'devices.js',

Просмотреть файл

@ -1,108 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {Cc, Ci, Cu, Cr} = require("chrome");
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
/**
* Localization convenience methods.
*/
const STRINGS_URI = "chrome://browser/locale/devtools/profiler.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
/**
* Details about each profile entry cateogry.
* @see CATEGORY_MAPPINGS.
*/
const CATEGORIES = [
{ ordinal: 7, color: "#5e88b0", abbrev: "other", label: L10N.getStr("category.other") },
{ ordinal: 4, color: "#46afe3", abbrev: "css", label: L10N.getStr("category.css") },
{ ordinal: 1, color: "#d96629", abbrev: "js", label: L10N.getStr("category.js") },
{ ordinal: 2, color: "#eb5368", abbrev: "gc", label: L10N.getStr("category.gc") },
{ ordinal: 0, color: "#df80ff", abbrev: "network", label: L10N.getStr("category.network") },
{ ordinal: 5, color: "#70bf53", abbrev: "graphics", label: L10N.getStr("category.graphics") },
{ ordinal: 6, color: "#8fa1b2", abbrev: "storage", label: L10N.getStr("category.storage") },
{ ordinal: 3, color: "#d99b28", abbrev: "events", label: L10N.getStr("category.events") }
];
/**
* Mapping from category bitmasks in the profiler data to additional details.
* To be kept in sync with the js::ProfileEntry::Category in ProfilingStack.h
*/
const CATEGORY_MAPPINGS = {
"16": CATEGORIES[0], // js::ProfileEntry::Category::OTHER
"32": CATEGORIES[1], // js::ProfileEntry::Category::CSS
"64": CATEGORIES[2], // js::ProfileEntry::Category::JS
"128": CATEGORIES[3], // js::ProfileEntry::Category::GC
"256": CATEGORIES[3], // js::ProfileEntry::Category::CC
"512": CATEGORIES[4], // js::ProfileEntry::Category::NETWORK
"1024": CATEGORIES[5], // js::ProfileEntry::Category::GRAPHICS
"2048": CATEGORIES[6], // js::ProfileEntry::Category::STORAGE
"4096": CATEGORIES[7], // js::ProfileEntry::Category::EVENTS
};
/**
* Get the numeric bitmask (or set of masks) for the given category
* abbreviation. See CATEGORIES and CATEGORY_MAPPINGS above.
*
* CATEGORY_MASK can be called with just a name if it is expected that the
* category is mapped to by exactly one bitmask. If the category is mapped
* to by multiple masks, CATEGORY_MASK for that name must be called with
* an additional argument specifying the desired id (in ascending order).
*/
const [CATEGORY_MASK, CATEGORY_MASK_LIST] = (function () {
let mappings = {};
for (let category of CATEGORIES) {
let numList = Object.keys(CATEGORY_MAPPINGS)
.filter(k => CATEGORY_MAPPINGS[k] == category)
.map(k => +k);
numList.sort();
mappings[category.abbrev] = numList;
}
return [
function (name, num) {
if (!(name in mappings)) {
throw new Error(`Category abbreviation '${name}' does not exist.`);
}
if (arguments.length == 1) {
if (mappings[name].length != 1) {
throw new Error(`Expected exactly one category number for '${name}'.`);
}
return mappings[name][0];
}
if (num > mappings[name].length) {
throw new Error(`Num '${num}' too high for category '${name}'.`);
}
return mappings[name][num - 1];
},
function (name) {
if (!(name in mappings)) {
throw new Error(`Category abbreviation '${name}' does not exist.`);
}
return mappings[name];
}
];
})();
// Human-readable "other" category bitmask. Older Geckos don't have all the
// necessary instrumentation in the sampling profiler backend for creating
// a categories graph, in which case we default to the "other" category.
const CATEGORY_OTHER = CATEGORY_MASK('other');
// Human-readable JIT category bitmask. Certain pseudo-frames in a sample,
// like "EnterJIT", don't have any associated `cateogry` information.
const CATEGORY_JIT = CATEGORY_MASK('js');
// Exported symbols.
exports.L10N = L10N;
exports.CATEGORIES = CATEGORIES;
exports.CATEGORY_MAPPINGS = CATEGORY_MAPPINGS;
exports.CATEGORY_OTHER = CATEGORY_OTHER;
exports.CATEGORY_JIT = CATEGORY_JIT;
exports.CATEGORY_MASK = CATEGORY_MASK;
exports.CATEGORY_MASK_LIST = CATEGORY_MASK_LIST;

Просмотреть файл

@ -1,230 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {Cc, Ci, Cu, Cr} = require("chrome");
loader.lazyRequireGetter(this, "ViewHelpers",
"resource:///modules/devtools/ViewHelpers.jsm", true);
loader.lazyRequireGetter(this, "Services");
// String used to fill in platform data when it should be hidden.
const GECKO_SYMBOL = "(Gecko)";
/**
* Localization convenience methods.
*/
const STRINGS_URI = "chrome://browser/locale/devtools/timeline.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
/**
* Monitor "show-platform-data" pref.
*/
const prefs = new ViewHelpers.Prefs("devtools.performance.ui", {
showPlatformData: ["Bool", "show-platform-data"]
});
let SHOW_PLATFORM_DATA = Services.prefs.getBoolPref("devtools.performance.ui.show-platform-data");
prefs.registerObserver();
prefs.on("pref-changed", (_, prefName, prefValue) => {
if (prefName === "showPlatformData") {
SHOW_PLATFORM_DATA = prefValue;
}
});
/**
* A simple schema for mapping markers to the timeline UI. The keys correspond
* to marker names, while the values are objects with the following format:
*
* - group: the row index in the timeline overview graph; multiple markers
* can be added on the same row. @see <overview.js/buildGraphImage>
* - label: the label used in the waterfall to identify the marker. Can be a
* string or just a function that accepts the marker and returns a string,
* if you want to use a dynamic property for the main label.
* If you use a function for a label, it *must* handle the case where
* no marker is provided for a main label to describe all markers of this type.
* - colorName: the label of the DevTools color used for this marker. If adding
* a new color, be sure to check that there's an entry for
* `.marker-details-bullet.{COLORNAME}` for the equivilent entry
* in ./browser/themes/shared/devtools/performance.inc.css
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors
* - fields: An optional array of marker properties you wish to display in the
* marker details view. For example, a field of
* { property: "aCauseName", label: "Cause" }
* would render a field like `Cause: ${marker.aCauseName}`.
* Each `field` item may take the following properties:
*
* - property: The property that must exist on the marker to render, and
* the value of the property will be displayed.
* - label: The name of the property that should be displayed.
*
* Can also be a function that returns an object. Each key in the object
* will be rendered as a field, with its value rendering as the value.
*
* Whenever this is changed, browser_timeline_waterfall-styles.js *must* be
* updated as well.
*/
const TIMELINE_BLUEPRINT = {
/* Group 0 - Reflow and Rendering pipeline */
"Styles": {
group: 0,
colorName: "graphs-purple",
label: L10N.getStr("timeline.label.styles2"),
fields: getStylesFields,
},
"Reflow": {
group: 0,
colorName: "graphs-purple",
label: L10N.getStr("timeline.label.reflow2")
},
"Paint": {
group: 0,
colorName: "graphs-green",
label: L10N.getStr("timeline.label.paint")
},
/* Group 1 - JS */
"DOMEvent": {
group: 1,
colorName: "graphs-yellow",
label: L10N.getStr("timeline.label.domevent"),
fields: getDOMEventFields,
},
"Javascript": {
group: 1,
colorName: "graphs-yellow",
label: getJSLabel,
fields: getJSFields,
},
"Parse HTML": {
group: 1,
colorName: "graphs-yellow",
label: L10N.getStr("timeline.label.parseHTML")
},
"Parse XML": {
group: 1,
colorName: "graphs-yellow",
label: L10N.getStr("timeline.label.parseXML")
},
"GarbageCollection": {
group: 1,
colorName: "graphs-red",
label: getGCLabel,
fields: [
{ property: "causeName", label: "Reason:" },
{ property: "nonincrementalReason", label: "Non-incremental Reason:" }
]
},
/* Group 2 - User Controlled */
"ConsoleTime": {
group: 2,
colorName: "graphs-grey",
label: sublabelForProperty(L10N.getStr("timeline.label.consoleTime"), "causeName"),
fields: [{
property: "causeName",
label: L10N.getStr("timeline.markerDetail.consoleTimerName")
}]
},
"TimeStamp": {
group: 2,
colorName: "graphs-blue",
label: sublabelForProperty(L10N.getStr("timeline.label.timestamp"), "causeName"),
fields: [{
property: "causeName",
label: "Label:"
}]
},
};
/**
* A series of formatters used by the blueprint.
*/
function getGCLabel (marker={}) {
let label = L10N.getStr("timeline.label.garbageCollection");
// Only if a `nonincrementalReason` exists, do we want to label
// this as a non incremental GC event.
if ("nonincrementalReason" in marker) {
label = `${label} (Non-incremental)`;
}
return label;
}
/**
* Mapping of JS marker causes to a friendlier form. Only
* markers that are considered "from content" should be labeled here.
*/
const JS_MARKER_MAP = {
"<script> element": "Script Tag",
"setInterval handler": "setInterval",
"setTimeout handler": "setTimeout",
"FrameRequestCallback": "requestAnimationFrame",
"promise callback": "Promise Callback",
"promise initializer": "Promise Init",
"Worker runnable": "Worker",
"javascript: URI": "JavaScript URI",
// As far as I know, the difference between these two
// event handler markers are differences in their webidl implementation.
"EventHandlerNonNull": "Event Handler",
"EventListener.handleEvent": "Event Handler",
};
function getJSLabel (marker={}) {
let generic = L10N.getStr("timeline.label.javascript2");
if ("causeName" in marker) {
return JS_MARKER_MAP[marker.causeName] || generic;
}
return generic;
}
/**
* Returns a hash for computing a fields object for a JS marker. If the cause
* is considered content (so an entry exists in the JS_MARKER_MAP), do not display it
* since it's redundant with the label. Otherwise for Gecko code, either display
* the cause, or "(Gecko)", depending on if "show-platform-data" is set.
*/
function getJSFields (marker) {
if ("causeName" in marker && !JS_MARKER_MAP[marker.causeName]) {
return { Reason: (SHOW_PLATFORM_DATA ? marker.causeName : GECKO_SYMBOL) };
}
}
function getDOMEventFields (marker) {
let fields = Object.create(null);
if ("type" in marker) {
fields[L10N.getStr("timeline.markerDetail.DOMEventType")] = marker.type;
}
if ("eventPhase" in marker) {
let phase;
if (marker.eventPhase === Ci.nsIDOMEvent.AT_TARGET) {
phase = L10N.getStr("timeline.markerDetail.DOMEventTargetPhase");
} else if (marker.eventPhase === Ci.nsIDOMEvent.CAPTURING_PHASE) {
phase = L10N.getStr("timeline.markerDetail.DOMEventCapturingPhase");
} else if (marker.eventPhase === Ci.nsIDOMEvent.BUBBLING_PHASE) {
phase = L10N.getStr("timeline.markerDetail.DOMEventBubblingPhase");
}
fields[L10N.getStr("timeline.markerDetail.DOMEventPhase")] = phase;
}
return fields;
}
function getStylesFields (marker) {
if ("restyleHint" in marker) {
return { "Restyle Hint": marker.restyleHint.replace(/eRestyle_/g, "") };
}
}
/**
* Takes a main label (like "Timestamp") and a property,
* and returns a marker that will print out the property
* value for a marker if it exists ("Timestamp (rendering)"),
* or just the main label if it does not.
*/
function sublabelForProperty (mainLabel, prop) {
return (marker={}) => marker[prop] ? `${mainLabel} (${marker[prop]})` : mainLabel;
}
// Exported symbols.
exports.L10N = L10N;
exports.TIMELINE_BLUEPRINT = TIMELINE_BLUEPRINT;

Просмотреть файл

@ -409,8 +409,13 @@ ViewHelpers.L10N.prototype = {
* The root path to the required preferences branch.
* @param object aPrefsBlueprint
* An object containing { accessorName: [prefType, prefName] } keys.
* @param object aOptions
* Additional options for this constructor. Currently supported:
* - monitorChanges: true to update the stored values if they changed
* when somebody edits about:config or the prefs
* change somewhere else.
*/
ViewHelpers.Prefs = function(aPrefsRoot = "", aPrefsBlueprint = {}) {
ViewHelpers.Prefs = function(aPrefsRoot = "", aPrefsBlueprint = {}, aOptions = {}) {
EventEmitter.decorate(this);
this._cache = new Map();
@ -442,6 +447,10 @@ ViewHelpers.Prefs = function(aPrefsRoot = "", aPrefsBlueprint = {}) {
this.registerObserver = () => observer.register();
this.unregisterObserver = () => observer.unregister();
if (aOptions.monitorChanges) {
this.registerObserver();
}
};
ViewHelpers.Prefs.prototype = {

Просмотреть файл

@ -70,7 +70,7 @@ class ProfileEntry
CATEGORY_MASK = ~IS_CPP_ENTRY & ~FRAME_LABEL_COPY & ~BEGIN_PSEUDO_JS & ~OSR
};
// Keep these in sync with browser/devtools/profiler/utils/global.js
// Keep these in sync with browser/devtools/performance/modules/global.js
enum class Category : uint32_t {
OTHER = 0x10,
CSS = 0x20,