mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1167976 - Mark platform JS code with category where appropriate. In this case, just "tools" category as devtools JS code. r=vp,shu
This commit is contained in:
parent
3cfaf3da52
commit
ba1c4112a7
@ -65,6 +65,10 @@ const CATEGORIES = [{
|
||||
color: "#d99b28",
|
||||
abbrev: "events",
|
||||
label: L10N.getStr("category.events")
|
||||
}, {
|
||||
color: "#8fa1b2",
|
||||
abbrev: "tools",
|
||||
label: L10N.getStr("category.tools")
|
||||
}];
|
||||
|
||||
/**
|
||||
@ -81,6 +85,9 @@ const CATEGORY_MAPPINGS = {
|
||||
"1024": CATEGORIES[5], // js::ProfileEntry::Category::GRAPHICS
|
||||
"2048": CATEGORIES[6], // js::ProfileEntry::Category::STORAGE
|
||||
"4096": CATEGORIES[7], // js::ProfileEntry::Category::EVENTS
|
||||
|
||||
// non-bitmasks for specially-assigned categories
|
||||
"9000": CATEGORIES[8],
|
||||
};
|
||||
|
||||
/**
|
||||
@ -106,17 +113,17 @@ const [CATEGORY_MASK, CATEGORY_MASK_LIST] = (function () {
|
||||
return [
|
||||
function (name, index) {
|
||||
if (!(name in bitmasksForCategory)) {
|
||||
throw new Error(`Category abbreviation '${name}' does not exist.`);
|
||||
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}'.`);
|
||||
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}'.`);
|
||||
throw new Error(`Index "${index}" too high for category "${name}".`);
|
||||
} else {
|
||||
return bitmasksForCategory[name][index - 1];
|
||||
}
|
||||
@ -125,7 +132,7 @@ const [CATEGORY_MASK, CATEGORY_MASK_LIST] = (function () {
|
||||
|
||||
function (name) {
|
||||
if (!(name in bitmasksForCategory)) {
|
||||
throw new Error(`Category abbreviation '${name}' does not exist.`);
|
||||
throw new Error(`Category abbreviation "${name}" does not exist.`);
|
||||
}
|
||||
return bitmasksForCategory[name];
|
||||
}
|
||||
@ -135,11 +142,15 @@ const [CATEGORY_MASK, CATEGORY_MASK_LIST] = (function () {
|
||||
// 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');
|
||||
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');
|
||||
// like "EnterJIT", don't have any associated `category` information.
|
||||
const CATEGORY_JIT = CATEGORY_MASK("js");
|
||||
|
||||
// Human-readable "devtools" category bitmask. Not emitted from frames themselves,
|
||||
// but used manually in the client.
|
||||
const CATEGORY_DEVTOOLS = CATEGORY_MASK("tools");
|
||||
|
||||
// Exported symbols.
|
||||
exports.L10N = L10N;
|
||||
@ -150,3 +161,4 @@ exports.CATEGORY_MASK = CATEGORY_MASK;
|
||||
exports.CATEGORY_MASK_LIST = CATEGORY_MASK_LIST;
|
||||
exports.CATEGORY_OTHER = CATEGORY_OTHER;
|
||||
exports.CATEGORY_JIT = CATEGORY_JIT;
|
||||
exports.CATEGORY_DEVTOOLS = CATEGORY_DEVTOOLS;
|
||||
|
@ -6,8 +6,8 @@
|
||||
const { Cc, Ci, Cu, Cr } = require("chrome");
|
||||
|
||||
loader.lazyRequireGetter(this, "Services");
|
||||
loader.lazyRequireGetter(this, "CATEGORY_OTHER",
|
||||
"devtools/performance/global", true);
|
||||
loader.lazyRequireGetter(this, "global",
|
||||
"devtools/performance/global");
|
||||
|
||||
// Character codes used in various parsing helper functions.
|
||||
const CHAR_CODE_A = "a".charCodeAt(0);
|
||||
@ -162,33 +162,55 @@ function parseLocation(location, fallbackLine, fallbackColumn) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the specified function represents a chrome or content frame.
|
||||
* Sets the properties of `isContent` and `category` on a frame.
|
||||
*
|
||||
* @param string location
|
||||
* The location of the frame.
|
||||
* @param number category [optional]
|
||||
* If a chrome frame, the category.
|
||||
* @return boolean
|
||||
* True if a content frame, false if a chrome frame.
|
||||
* @param {InflatedFrame} frame
|
||||
*/
|
||||
function isContent({ location, category }) {
|
||||
function computeIsContentAndCategory(frame) {
|
||||
// Only C++ stack frames have associated category information.
|
||||
if (category) {
|
||||
return false;
|
||||
if (frame.category) {
|
||||
return;
|
||||
}
|
||||
|
||||
let location = frame.location;
|
||||
|
||||
// Locations in frames with function names look like:
|
||||
// "functionName (foo://bar)".
|
||||
// Look for the starting left parenthesis, then try to match a
|
||||
// scheme name.
|
||||
for (let i = 0; i < location.length; i++) {
|
||||
if (location.charCodeAt(i) === CHAR_CODE_LPAREN) {
|
||||
return isContentScheme(location, i + 1);
|
||||
if (isContentScheme(location, i + 1)) {
|
||||
frame.isContent = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (let j = i + 1; j < location.length; j++) {
|
||||
if (location.charCodeAt(j) === CHAR_CODE_R &&
|
||||
isChromeScheme(location, j) &&
|
||||
(location.indexOf("resource://gre/modules/devtools") !== -1 ||
|
||||
location.indexOf("resource:///modules/devtools") !== -1)) {
|
||||
frame.category = global.CATEGORY_DEVTOOLS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If there was no left parenthesis, try matching from the start.
|
||||
return isContentScheme(location, 0);
|
||||
if (isContentScheme(location, 0)) {
|
||||
frame.isContent = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (location === "EnterJIT") {
|
||||
frame.category = global.CATEGORY_JIT;
|
||||
return;
|
||||
}
|
||||
|
||||
frame.category = global.CATEGORY_OTHER;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,10 +269,17 @@ function InflatedFrame(index, frameTable, stringTable, allocationsTable) {
|
||||
this.optimizations = frame[OPTIMIZATIONS_SLOT];
|
||||
this.line = frame[LINE_SLOT];
|
||||
this.column = undefined;
|
||||
this.category = category;
|
||||
this.metaCategory = category || CATEGORY_OTHER;
|
||||
this.allocations = allocationsTable ? allocationsTable[index] : 0;
|
||||
this.isContent = isContent(this);
|
||||
this.category = category;
|
||||
this.isContent = false;
|
||||
|
||||
// Attempt to compute if this frame is a content frame, and if not,
|
||||
// its category.
|
||||
//
|
||||
// Since only C++ stack frames have associated category information,
|
||||
// attempt to generate a useful category, fallback to the one provided
|
||||
// by the profiling data, or fallback to an unknown category.
|
||||
computeIsContentAndCategory(this);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -284,7 +313,7 @@ InflatedFrame.prototype.getFrameKey = function getFrameKey(options) {
|
||||
// non-leaf platform frames don't give any meaningful context, and so we
|
||||
// can safely filter them out.
|
||||
options.isMetaCategoryOut = true;
|
||||
return this.metaCategory;
|
||||
return this.category;
|
||||
}
|
||||
|
||||
// Return an empty string denoting that this frame should be skipped.
|
||||
@ -418,8 +447,8 @@ function isNumeric(c) {
|
||||
return c >= CHAR_CODE_0 && c <= CHAR_CODE_9;
|
||||
}
|
||||
|
||||
exports.computeIsContentAndCategory = computeIsContentAndCategory;
|
||||
exports.parseLocation = parseLocation;
|
||||
exports.isContent = isContent;
|
||||
exports.getInflatedFrameCache = getInflatedFrameCache;
|
||||
exports.getOrAddInflatedFrame = getOrAddInflatedFrame;
|
||||
exports.InflatedFrame = InflatedFrame;
|
||||
|
@ -9,12 +9,6 @@ loader.lazyRequireGetter(this, "L10N",
|
||||
"devtools/performance/global", true);
|
||||
loader.lazyRequireGetter(this, "CATEGORY_MAPPINGS",
|
||||
"devtools/performance/global", true);
|
||||
loader.lazyRequireGetter(this, "CATEGORIES",
|
||||
"devtools/performance/global", true);
|
||||
loader.lazyRequireGetter(this, "CATEGORY_JIT",
|
||||
"devtools/performance/global", true);
|
||||
loader.lazyRequireGetter(this, "CATEGORY_OTHER",
|
||||
"devtools/performance/global", true);
|
||||
loader.lazyRequireGetter(this, "JITOptimizations",
|
||||
"devtools/performance/jit", true);
|
||||
loader.lazyRequireGetter(this, "FrameUtils",
|
||||
@ -377,15 +371,15 @@ function FrameNode(frameKey, { location, line, category, allocations, isContent
|
||||
this.key = frameKey;
|
||||
this.location = location;
|
||||
this.line = line;
|
||||
this.category = category;
|
||||
this.allocations = allocations;
|
||||
this.samples = 0;
|
||||
this.duration = 0;
|
||||
this.calls = [];
|
||||
this.isContent = isContent;
|
||||
this.isContent = !!isContent;
|
||||
this._optimizations = null;
|
||||
this._stringTable = null;
|
||||
this.isMetaCategory = isMetaCategory;
|
||||
this.isMetaCategory = !!isMetaCategory;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
FrameNode.prototype = {
|
||||
@ -462,19 +456,7 @@ FrameNode.prototype = {
|
||||
* function name and source url.
|
||||
*/
|
||||
_computeInfo: function() {
|
||||
// "EnterJIT" pseudoframes are special, not actually on the stack.
|
||||
if (this.location == "EnterJIT") {
|
||||
this.category = CATEGORY_JIT;
|
||||
}
|
||||
|
||||
if (this.isMetaCategory && !this.category) {
|
||||
this.category = CATEGORY_OTHER;
|
||||
}
|
||||
|
||||
// Since only C++ stack frames have associated category information,
|
||||
// default to an "unknown" category otherwise.
|
||||
let categoryData = CATEGORY_MAPPINGS[this.category] || {};
|
||||
|
||||
let parsedData = FrameUtils.parseLocation(this.location, this.line, this.column);
|
||||
parsedData.nodeType = "Frame";
|
||||
parsedData.categoryData = categoryData;
|
||||
|
@ -117,8 +117,6 @@ skip-if = e10s # GC events seem unreliable in multiprocess
|
||||
[browser_perf-recording-selected-03.js]
|
||||
[browser_perf-recording-selected-04.js]
|
||||
[browser_perf-theme-toggle-01.js]
|
||||
[browser_profiler_categories.js]
|
||||
[browser_profiler_content-check.js]
|
||||
[browser_profiler_tree-abstract-01.js]
|
||||
[browser_profiler_tree-abstract-02.js]
|
||||
[browser_profiler_tree-abstract-03.js]
|
||||
|
@ -40,7 +40,12 @@ function run_test() {
|
||||
}
|
||||
|
||||
add_task(function () {
|
||||
const { isContent, parseLocation } = devtools.require("devtools/performance/frame-utils");
|
||||
const { computeIsContentAndCategory, parseLocation } = devtools.require("devtools/performance/frame-utils");
|
||||
let isContent = (frame) => {
|
||||
computeIsContentAndCategory(frame);
|
||||
return frame.isContent;
|
||||
};
|
||||
|
||||
|
||||
for (let frame of CONTENT_LOCATIONS) {
|
||||
ok(isContent.apply(null, frameify(frame)), `${frame[0]} should be considered a content frame.`);
|
||||
|
@ -6,46 +6,53 @@
|
||||
* works properly.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function () {
|
||||
let FrameUtils = devtools.require("devtools/performance/frame-utils");
|
||||
|
||||
ok(FrameUtils.isContent({ location: "http://foo" }),
|
||||
let isContent = (frame) => {
|
||||
FrameUtils.computeIsContentAndCategory(frame);
|
||||
return frame.isContent;
|
||||
};
|
||||
|
||||
ok(isContent({ location: "http://foo" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(FrameUtils.isContent({ location: "https://foo" }),
|
||||
ok(isContent({ location: "https://foo" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(FrameUtils.isContent({ location: "file://foo" }),
|
||||
ok(isContent({ location: "file://foo" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
|
||||
ok(!FrameUtils.isContent({ location: "chrome://foo" }),
|
||||
ok(!isContent({ location: "chrome://foo" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(!FrameUtils.isContent({ location: "resource://foo" }),
|
||||
ok(!isContent({ location: "resource://foo" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
|
||||
ok(!FrameUtils.isContent({ location: "chrome://foo -> http://bar" }),
|
||||
ok(!isContent({ location: "chrome://foo -> http://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(!FrameUtils.isContent({ location: "chrome://foo -> https://bar" }),
|
||||
ok(!isContent({ location: "chrome://foo -> https://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(!FrameUtils.isContent({ location: "chrome://foo -> file://bar" }),
|
||||
ok(!isContent({ location: "chrome://foo -> file://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
|
||||
ok(!FrameUtils.isContent({ location: "resource://foo -> http://bar" }),
|
||||
ok(!isContent({ location: "resource://foo -> http://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(!FrameUtils.isContent({ location: "resource://foo -> https://bar" }),
|
||||
ok(!isContent({ location: "resource://foo -> https://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(!FrameUtils.isContent({ location: "resource://foo -> file://bar" }),
|
||||
ok(!isContent({ location: "resource://foo -> file://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
|
||||
ok(!FrameUtils.isContent({ category: 1, location: "chrome://foo" }),
|
||||
ok(!isContent({ category: 1, location: "chrome://foo" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(!FrameUtils.isContent({ category: 1, location: "resource://foo" }),
|
||||
ok(!isContent({ category: 1, location: "resource://foo" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
|
||||
ok(!FrameUtils.isContent({ category: 1, location: "file://foo -> http://bar" }),
|
||||
ok(!isContent({ category: 1, location: "file://foo -> http://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(!FrameUtils.isContent({ category: 1, location: "file://foo -> https://bar" }),
|
||||
ok(!isContent({ category: 1, location: "file://foo -> https://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
ok(!FrameUtils.isContent({ category: 1, location: "file://foo -> file://bar" }),
|
||||
ok(!isContent({ category: 1, location: "file://foo -> file://bar" }),
|
||||
"Verifying content/chrome frames is working properly.");
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
@ -5,7 +5,11 @@
|
||||
* Tests if the profiler categories are mapped correctly.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function () {
|
||||
let global = devtools.require("devtools/performance/global");
|
||||
let l10n = global.L10N;
|
||||
let categories = global.CATEGORIES;
|
||||
@ -15,20 +19,18 @@ function test() {
|
||||
ok(count,
|
||||
"Should have a non-empty list of categories available.");
|
||||
|
||||
ok(!categories.some(e => !e.color),
|
||||
ok(categories.some(e => e.color),
|
||||
"All categories have an associated color.");
|
||||
|
||||
ok(!categories.some(e => !e.label),
|
||||
ok(categories.every(e => e.label),
|
||||
"All categories have an associated label.");
|
||||
|
||||
ok(!categories.some(e => e.label != l10n.getStr("category." + e.abbrev)),
|
||||
ok(categories.every(e => e.label === l10n.getStr("category." + e.abbrev)),
|
||||
"All categories have a correctly localized label.");
|
||||
|
||||
ok(!Object.keys(mappings).some(e => !Number.isInteger(Math.log2(e))),
|
||||
"All bitmask mappings keys are powers of 2.");
|
||||
ok(Object.keys(mappings).every(e => (Number(e) >= 9000 && Number(e) <= 9999) || Number.isInteger(Math.log2(e))),
|
||||
"All bitmask mappings keys are powers of 2, or between 9000-9999 for special categories.");
|
||||
|
||||
ok(!Object.keys(mappings).some(e => categories.indexOf(mappings[e]) == -1),
|
||||
ok(Object.keys(mappings).every(e => categories.indexOf(mappings[e]) !== -1),
|
||||
"All bitmask mappings point to a category.");
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
@ -26,7 +26,7 @@ add_task(function test() {
|
||||
"The correct duration was calculated for the root node.");
|
||||
equal(root.getInfo().functionName, "(root)",
|
||||
"The correct function name was retrieved for the root node.");
|
||||
equal(root.getInfo().categoryData.toSource(), "({})",
|
||||
equal(root.getInfo().categoryData.abbrev, "other",
|
||||
"The correct empty category data was retrieved for the root node.");
|
||||
|
||||
equal(root.calls.length, 1,
|
||||
|
@ -13,238 +13,82 @@ add_task(function test() {
|
||||
let FrameUtils = devtools.require("devtools/performance/frame-utils");
|
||||
let { FrameNode } = devtools.require("devtools/performance/tree-model");
|
||||
let { CATEGORY_OTHER } = devtools.require("devtools/performance/global");
|
||||
let compute = frame => {
|
||||
FrameUtils.computeIsContentAndCategory(frame);
|
||||
return frame;
|
||||
};
|
||||
|
||||
let frame1 = new FrameNode("hello/<.world (http://foo/bar.js:123:987)", {
|
||||
location: "hello/<.world (http://foo/bar.js:123:987)",
|
||||
line: 456,
|
||||
isContent: FrameUtils.isContent({
|
||||
location: "hello/<.world (http://foo/bar.js:123:987)"
|
||||
})
|
||||
}, false);
|
||||
|
||||
equal(frame1.getInfo().nodeType, "Frame",
|
||||
"The first frame node has the correct type.");
|
||||
equal(frame1.getInfo().functionName, "hello/<.world",
|
||||
"The first frame node has the correct function name.");
|
||||
equal(frame1.getInfo().fileName, "bar.js",
|
||||
"The first frame node has the correct file name.");
|
||||
equal(frame1.getInfo().hostName, "foo",
|
||||
"The first frame node has the correct host name.");
|
||||
equal(frame1.getInfo().url, "http://foo/bar.js",
|
||||
"The first frame node has the correct url.");
|
||||
equal(frame1.getInfo().line, 123,
|
||||
"The first frame node has the correct line.");
|
||||
equal(frame1.getInfo().column, 987,
|
||||
"The first frame node has the correct column.");
|
||||
equal(frame1.getInfo().categoryData.toSource(), "({})",
|
||||
"The first frame node has the correct category data.");
|
||||
equal(frame1.getInfo().isContent, true,
|
||||
"The first frame node has the correct content flag.");
|
||||
|
||||
let frame2 = new FrameNode("hello/<.world (http://foo/bar.js#baz:123:987)", {
|
||||
location: "hello/<.world (http://foo/bar.js#baz:123:987)",
|
||||
line: 456,
|
||||
isContent: FrameUtils.isContent({
|
||||
location: "hello/<.world (http://foo/bar.js#baz:123:987)"
|
||||
})
|
||||
}, false);
|
||||
|
||||
equal(frame2.getInfo().nodeType, "Frame",
|
||||
"The second frame node has the correct type.");
|
||||
equal(frame2.getInfo().functionName, "hello/<.world",
|
||||
"The second frame node has the correct function name.");
|
||||
equal(frame2.getInfo().fileName, "bar.js",
|
||||
"The second frame node has the correct file name.");
|
||||
equal(frame2.getInfo().hostName, "foo",
|
||||
"The second frame node has the correct host name.");
|
||||
equal(frame2.getInfo().url, "http://foo/bar.js#baz",
|
||||
"The second frame node has the correct url.");
|
||||
equal(frame2.getInfo().line, 123,
|
||||
"The second frame node has the correct line.");
|
||||
equal(frame2.getInfo().column, 987,
|
||||
"The second frame node has the correct column.");
|
||||
equal(frame2.getInfo().categoryData.toSource(), "({})",
|
||||
"The second frame node has the correct category data.");
|
||||
equal(frame2.getInfo().isContent, true,
|
||||
"The second frame node has the correct content flag.");
|
||||
|
||||
let frame3 = new FrameNode("hello/<.world (http://foo/#bar:123:987)", {
|
||||
location: "hello/<.world (http://foo/#bar:123:987)",
|
||||
line: 456,
|
||||
isContent: FrameUtils.isContent({
|
||||
location: "hello/<.world (http://foo/#bar:123:987)"
|
||||
})
|
||||
}, false);
|
||||
|
||||
equal(frame3.getInfo().nodeType, "Frame",
|
||||
"The third frame node has the correct type.");
|
||||
equal(frame3.getInfo().functionName, "hello/<.world",
|
||||
"The third frame node has the correct function name.");
|
||||
equal(frame3.getInfo().fileName, "/",
|
||||
"The third frame node has the correct file name.");
|
||||
equal(frame3.getInfo().hostName, "foo",
|
||||
"The third frame node has the correct host name.");
|
||||
equal(frame3.getInfo().url, "http://foo/#bar",
|
||||
"The third frame node has the correct url.");
|
||||
equal(frame3.getInfo().line, 123,
|
||||
"The third frame node has the correct line.");
|
||||
equal(frame3.getInfo().column, 987,
|
||||
"The third frame node has the correct column.");
|
||||
equal(frame3.getInfo().categoryData.toSource(), "({})",
|
||||
"The third frame node has the correct category data.");
|
||||
equal(frame3.getInfo().isContent, true,
|
||||
"The third frame node has the correct content flag.");
|
||||
|
||||
let frame4 = new FrameNode("hello/<.world (http://foo/:123:987)", {
|
||||
location: "hello/<.world (http://foo/:123:987)",
|
||||
line: 456,
|
||||
isContent: FrameUtils.isContent({
|
||||
location: "hello/<.world (http://foo/:123:987)"
|
||||
})
|
||||
}, false);
|
||||
|
||||
equal(frame4.getInfo().nodeType, "Frame",
|
||||
"The fourth frame node has the correct type.");
|
||||
equal(frame4.getInfo().functionName, "hello/<.world",
|
||||
"The fourth frame node has the correct function name.");
|
||||
equal(frame4.getInfo().fileName, "/",
|
||||
"The fourth frame node has the correct file name.");
|
||||
equal(frame4.getInfo().hostName, "foo",
|
||||
"The fourth frame node has the correct host name.");
|
||||
equal(frame4.getInfo().url, "http://foo/",
|
||||
"The fourth frame node has the correct url.");
|
||||
equal(frame4.getInfo().line, 123,
|
||||
"The fourth frame node has the correct line.");
|
||||
equal(frame4.getInfo().column, 987,
|
||||
"The fourth frame node has the correct column.");
|
||||
equal(frame4.getInfo().categoryData.toSource(), "({})",
|
||||
"The fourth frame node has the correct category data.");
|
||||
equal(frame4.getInfo().isContent, true,
|
||||
"The fourth frame node has the correct content flag.");
|
||||
|
||||
let frame5 = new FrameNode("hello/<.world (resource://foo.js -> http://bar/baz.js:123:987)", {
|
||||
location: "hello/<.world (resource://foo.js -> http://bar/baz.js:123:987)",
|
||||
line: 456,
|
||||
isContent: FrameUtils.isContent({
|
||||
location: "hello/<.world (resource://foo.js -> http://bar/baz.js:123:987)"
|
||||
})
|
||||
}, false);
|
||||
|
||||
equal(frame5.getInfo().nodeType, "Frame",
|
||||
"The fifth frame node has the correct type.");
|
||||
equal(frame5.getInfo().functionName, "hello/<.world",
|
||||
"The fifth frame node has the correct function name.");
|
||||
equal(frame5.getInfo().fileName, "baz.js",
|
||||
"The fifth frame node has the correct file name.");
|
||||
equal(frame5.getInfo().hostName, "bar",
|
||||
"The fifth frame node has the correct host name.");
|
||||
equal(frame5.getInfo().url, "http://bar/baz.js",
|
||||
"The fifth frame node has the correct url.");
|
||||
equal(frame5.getInfo().line, 123,
|
||||
"The fifth frame node has the correct line.");
|
||||
equal(frame5.getInfo().column, 987,
|
||||
"The fifth frame node has the correct column.");
|
||||
equal(frame5.getInfo().categoryData.toSource(), "({})",
|
||||
"The fifth frame node has the correct category data.");
|
||||
equal(frame5.getInfo().isContent, false,
|
||||
"The fifth frame node has the correct content flag.");
|
||||
|
||||
let frame6 = new FrameNode("Foo::Bar::Baz", {
|
||||
location: "Foo::Bar::Baz",
|
||||
line: 456,
|
||||
category: CATEGORY_OTHER,
|
||||
isContent: FrameUtils.isContent({
|
||||
let frames = [
|
||||
new FrameNode("hello/<.world (http://foo/bar.js:123:987)", compute({
|
||||
location: "hello/<.world (http://foo/bar.js:123:987)",
|
||||
line: 456,
|
||||
}), false),
|
||||
new FrameNode("hello/<.world (http://foo/bar.js#baz:123:987)", compute({
|
||||
location: "hello/<.world (http://foo/bar.js#baz:123:987)",
|
||||
line: 456,
|
||||
}), false),
|
||||
new FrameNode("hello/<.world (http://foo/#bar:123:987)", compute({
|
||||
location: "hello/<.world (http://foo/#bar:123:987)",
|
||||
line: 456,
|
||||
}), false),
|
||||
new FrameNode("hello/<.world (http://foo/:123:987)", compute({
|
||||
location: "hello/<.world (http://foo/:123:987)",
|
||||
line: 456,
|
||||
}), false),
|
||||
new FrameNode("hello/<.world (resource://foo.js -> http://bar/baz.js:123:987)", compute({
|
||||
location: "hello/<.world (resource://foo.js -> http://bar/baz.js:123:987)",
|
||||
line: 456,
|
||||
}), false),
|
||||
new FrameNode("Foo::Bar::Baz", compute({
|
||||
location: "Foo::Bar::Baz",
|
||||
category: CATEGORY_OTHER
|
||||
})
|
||||
}, false);
|
||||
line: 456,
|
||||
category: CATEGORY_OTHER,
|
||||
}), false),
|
||||
new FrameNode("EnterJIT", compute({
|
||||
location: "EnterJIT",
|
||||
}), false),
|
||||
new FrameNode("chrome://browser/content/content.js", compute({
|
||||
location: "chrome://browser/content/content.js",
|
||||
line: 456,
|
||||
column: 123
|
||||
}), false),
|
||||
new FrameNode("hello/<.world (resource://gre/foo.js:123:434)", compute({
|
||||
location: "hello/<.world (resource://gre/foo.js:123:434)",
|
||||
line: 456
|
||||
}), false),
|
||||
new FrameNode("main (http://localhost:8888/file.js:123:987)", compute({
|
||||
location: "main (http://localhost:8888/file.js:123:987)",
|
||||
line: 123,
|
||||
}), false),
|
||||
new FrameNode("main (resource://gre/modules/devtools/timeline.js:123)", compute({
|
||||
location: "main (resource://gre/modules/devtools/timeline.js:123)",
|
||||
}), false),
|
||||
];
|
||||
|
||||
equal(frame6.getInfo().nodeType, "Frame",
|
||||
"The sixth frame node has the correct type.");
|
||||
equal(frame6.getInfo().functionName, "Foo::Bar::Baz",
|
||||
"The sixth frame node has the correct function name.");
|
||||
equal(frame6.getInfo().fileName, null,
|
||||
"The sixth frame node has the correct file name.");
|
||||
equal(frame6.getInfo().hostName, null,
|
||||
"The sixth frame node has the correct host name.");
|
||||
equal(frame6.getInfo().url, null,
|
||||
"The sixth frame node has the correct url.");
|
||||
equal(frame6.getInfo().line, 456,
|
||||
"The sixth frame node has the correct line.");
|
||||
equal(frame6.getInfo().categoryData.abbrev, "other",
|
||||
"The sixth frame node has the correct category data.");
|
||||
equal(frame6.getInfo().isContent, false,
|
||||
"The sixth frame node has the correct content flag.");
|
||||
let fields = ["nodeType", "functionName", "fileName", "hostName", "url", "line", "column", "categoryData.abbrev", "isContent", "port"]
|
||||
let expected = [
|
||||
// nodeType, functionName, fileName, hostName, url, line, column, categoryData.abbrev, isContent, port
|
||||
["Frame", "hello/<.world", "bar.js", "foo", "http://foo/bar.js", 123, 987, void 0, true],
|
||||
["Frame", "hello/<.world", "bar.js", "foo", "http://foo/bar.js#baz", 123, 987, void 0, true],
|
||||
["Frame", "hello/<.world", "/", "foo", "http://foo/#bar", 123, 987, void 0, true],
|
||||
["Frame", "hello/<.world", "/", "foo", "http://foo/", 123, 987, void 0, true],
|
||||
["Frame", "hello/<.world", "baz.js", "bar", "http://bar/baz.js", 123, 987, "other", false],
|
||||
["Frame", "Foo::Bar::Baz", null, null, null, 456, void 0, "other", false],
|
||||
["Frame", "EnterJIT", null, null, null, null, null, "js", false],
|
||||
["Frame", "chrome://browser/content/content.js", null, null, null, 456, null, "other", false],
|
||||
["Frame", "hello/<.world", "foo.js", null, "resource://gre/foo.js", 123, 434, "other", false],
|
||||
["Frame", "main", "file.js", "localhost", "http://localhost:8888/file.js", 123, 987, null, true, 8888],
|
||||
["Frame", "main", "timeline.js", null, "resource://gre/modules/devtools/timeline.js", 123, null, "tools", false]
|
||||
];
|
||||
|
||||
let frame7 = new FrameNode("EnterJIT", {
|
||||
location: "EnterJIT",
|
||||
isContent: FrameUtils.isContent({
|
||||
location: "EnterJIT"
|
||||
})
|
||||
}, false);
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
let info = frames[i].getInfo();
|
||||
let expect = expected[i];
|
||||
|
||||
equal(frame7.getInfo().nodeType, "Frame",
|
||||
"The seventh frame node has the correct type.");
|
||||
equal(frame7.getInfo().functionName, "EnterJIT",
|
||||
"The seventh frame node has the correct function name.");
|
||||
equal(frame7.getInfo().fileName, null,
|
||||
"The seventh frame node has the correct file name.");
|
||||
equal(frame7.getInfo().hostName, null,
|
||||
"The seventh frame node has the correct host name.");
|
||||
equal(frame7.getInfo().url, null,
|
||||
"The seventh frame node has the correct url.");
|
||||
equal(frame7.getInfo().line, null,
|
||||
"The seventh frame node has the correct line.");
|
||||
equal(frame7.getInfo().column, null,
|
||||
"The seventh frame node has the correct column.");
|
||||
equal(frame7.getInfo().categoryData.abbrev, "js",
|
||||
"The seventh frame node has the correct category data.");
|
||||
equal(frame7.getInfo().isContent, false,
|
||||
"The seventh frame node has the correct content flag.");
|
||||
|
||||
let frame8 = new FrameNode("chrome://browser/content/content.js", {
|
||||
location: "chrome://browser/content/content.js",
|
||||
line: 456,
|
||||
column: 123
|
||||
}, false);
|
||||
|
||||
equal(frame8.getInfo().hostName, null,
|
||||
"The eighth frame node has the correct host name.");
|
||||
|
||||
let frame9 = new FrameNode("hello/<.world (resource://gre/foo.js:123:434)", {
|
||||
location: "hello/<.world (resource://gre/foo.js:123:434)",
|
||||
line: 456
|
||||
}, false);
|
||||
|
||||
equal(frame9.getInfo().hostName, null,
|
||||
"The ninth frame node has the correct host name.");
|
||||
|
||||
let frame10 = new FrameNode("main (http://localhost:8888/file.js:123:987)", {
|
||||
location: "main (http://localhost:8888/file.js:123:987)",
|
||||
line: 123,
|
||||
isContent: FrameUtils.isContent({
|
||||
location: "main (http://localhost:8888/file.js:123:987)"
|
||||
})
|
||||
}, false);
|
||||
|
||||
equal(frame10.getInfo().nodeType, "Frame",
|
||||
"The tenth frame node has the correct type.");
|
||||
equal(frame10.getInfo().functionName, "main",
|
||||
"The tenth frame node has the correct function name.");
|
||||
equal(frame10.getInfo().fileName, "file.js",
|
||||
"The tenth frame node has the correct file name.");
|
||||
equal(frame10.getInfo().hostName, "localhost",
|
||||
"The tenth frame node has the correct host name.");
|
||||
equal(frame10.getInfo().url, "http://localhost:8888/file.js",
|
||||
"The tenth frame node has the correct url.");
|
||||
equal(frame10.getInfo().line, 123,
|
||||
"The tenth frame node has the correct line.");
|
||||
equal(frame10.getInfo().column, 987,
|
||||
"The tenth frame node has the correct column.");
|
||||
equal(frame10.getInfo().isContent, true,
|
||||
"The tenth frame node has the correct content flag.");
|
||||
equal(frame10.getInfo().host, "localhost:8888",
|
||||
"The tenth frame node has the correct host.");
|
||||
equal(frame10.getInfo().port, 8888,
|
||||
"The tenth frame node has the correct port.");
|
||||
for (let j = 0; j < fields.length; j++) {
|
||||
let field = fields[j];
|
||||
let value = field === "categoryData.abbrev" ? info.categoryData.abbrev : info[field];
|
||||
equal(value, expect[j], `${field} for frame #${i} is correct: ${expect[j]}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
82
browser/devtools/performance/test/unit/test_tree-model-09.js
Normal file
82
browser/devtools/performance/test/unit/test_tree-model-09.js
Normal file
@ -0,0 +1,82 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that when displaying only content nodes, platform nodes are generalized.
|
||||
*/
|
||||
|
||||
let { CATEGORY_MASK } = devtools.require("devtools/performance/global");
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function test() {
|
||||
let { ThreadNode } = devtools.require("devtools/performance/tree-model");
|
||||
let url = (n) => `http://content/${n}`;
|
||||
|
||||
// Create a root node from a given samples array.
|
||||
|
||||
let root = getFrameNodePath(new ThreadNode(gThread, { contentOnly: true }), "(root)");
|
||||
|
||||
/*
|
||||
* should have a tree like:
|
||||
* root
|
||||
* - (Tools)
|
||||
* - A
|
||||
* - B
|
||||
* - C
|
||||
* - D
|
||||
* - E
|
||||
* - F
|
||||
* - (Tools)
|
||||
*/
|
||||
|
||||
// Test the root node.
|
||||
|
||||
equal(root.calls.length, 2, "root has 2 children");
|
||||
ok(getFrameNodePath(root, url("A")), "root has content child");
|
||||
ok(getFrameNodePath(root, "9000"), "root has platform generalized child from Chrome JS");
|
||||
equal(getFrameNodePath(root, "9000").calls.length, 0, "platform generalized child is a leaf.");
|
||||
|
||||
ok(getFrameNodePath(root, `${url("A")} > ${url("E")} > ${url("F")} > 9000`),
|
||||
"a second leaf of the generalized Chrome JS exists.");
|
||||
|
||||
equal(getFrameNodePath(root, "9000").category,
|
||||
getFrameNodePath(root, `${url("A")} > ${url("E")} > ${url("F")} > 9000`).category,
|
||||
"generalized frames of same type are duplicated in top-down view");
|
||||
});
|
||||
|
||||
let gThread = synthesizeProfileForTest([{
|
||||
time: 5,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "http://content/A" },
|
||||
{ location: "http://content/B" },
|
||||
{ location: "http://content/C" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "http://content/A" },
|
||||
{ location: "http://content/B" },
|
||||
{ location: "fn (resource://loader.js -> resource:///modules/devtools/timeline.js)" },
|
||||
{ location: "http://content/D" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6 + 7,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "http://content/A" },
|
||||
{ location: "http://content/E" },
|
||||
{ location: "http://content/F" },
|
||||
{ location: "fn (resource://loader.js -> resource://gre/modules/devtools/promise.js)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 20,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "somefn (resource://loader.js -> resource:///modules/devtools/framerate.js)" }
|
||||
]
|
||||
}]);
|
@ -5,7 +5,9 @@ tail =
|
||||
firefox-appdir = browser
|
||||
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||
|
||||
[test_profiler-categories.js]
|
||||
[test_frame-utils-01.js]
|
||||
[test_frame-utils-02.js]
|
||||
[test_tree-model-01.js]
|
||||
[test_tree-model-02.js]
|
||||
[test_tree-model-03.js]
|
||||
@ -14,3 +16,4 @@ skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||
[test_tree-model-06.js]
|
||||
[test_tree-model-07.js]
|
||||
[test_tree-model-08.js]
|
||||
[test_tree-model-09.js]
|
||||
|
@ -82,6 +82,7 @@ category.network=Network
|
||||
category.graphics=Graphics
|
||||
category.storage=Storage
|
||||
category.events=Input & Events
|
||||
category.tools=Tools
|
||||
|
||||
# LOCALIZATION NOTE (graphs.ms):
|
||||
# This string is displayed in the call tree after units of time in milliseconds.
|
||||
|
Loading…
Reference in New Issue
Block a user