зеркало из https://github.com/mozilla/gecko-dev.git
Backout db5eef36bcd9 (bug 1117825) for dt2 orange
This commit is contained in:
Родитель
e02d1f8242
Коммит
be4d564b24
|
@ -19,7 +19,6 @@ support-files =
|
|||
[browser_flame-graph-02.js]
|
||||
[browser_flame-graph-03.js]
|
||||
[browser_flame-graph-04.js]
|
||||
[browser_flame-graph-utils.js]
|
||||
[browser_graphs-01.js]
|
||||
[browser_graphs-02.js]
|
||||
[browser_graphs-03.js]
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that text metrics in the flame graph widget work properly.
|
||||
|
||||
let {FlameGraphUtils} = Cu.import("resource:///modules/devtools/FlameGraph.jsm", {});
|
||||
|
||||
let test = Task.async(function*() {
|
||||
yield promiseTab("about:blank");
|
||||
yield performTest();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
|
||||
function* performTest() {
|
||||
let out = FlameGraphUtils.createFlameGraphDataFromSamples(TEST_DATA);
|
||||
|
||||
ok(out, "Some data was outputted properly");
|
||||
is(out.length, 10, "The outputted length is correct.");
|
||||
|
||||
for (let i = 0; i < out.length; i++) {
|
||||
let found = out[i];
|
||||
let expected = EXPECTED_OUTPUT[i];
|
||||
|
||||
is(found.blocks.length, expected.blocks.length,
|
||||
"The correct number of blocks were found in this bucket.");
|
||||
|
||||
for (let j = 0; j < found.blocks.length; j++) {
|
||||
is(found.blocks[j].x, expected.blocks[j].x,
|
||||
"The expected block X position is correct for this frame.");
|
||||
is(found.blocks[j].y, expected.blocks[j].y,
|
||||
"The expected block Y position is correct for this frame.");
|
||||
is(found.blocks[j].width, expected.blocks[j].width,
|
||||
"The expected block width is correct for this frame.");
|
||||
is(found.blocks[j].height, expected.blocks[j].height,
|
||||
"The expected block height is correct for this frame.");
|
||||
is(found.blocks[j].text, expected.blocks[j].text,
|
||||
"The expected block text is correct for this frame.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let TEST_DATA = [{
|
||||
frames: [{
|
||||
location: "M"
|
||||
}, {
|
||||
location: "N",
|
||||
}, {
|
||||
location: "P"
|
||||
}],
|
||||
time: 50,
|
||||
}, {
|
||||
frames: [{
|
||||
location: "A"
|
||||
}, {
|
||||
location: "B",
|
||||
}, {
|
||||
location: "C"
|
||||
}],
|
||||
time: 100,
|
||||
}, {
|
||||
frames: [{
|
||||
location: "A"
|
||||
}, {
|
||||
location: "B",
|
||||
}, {
|
||||
location: "D"
|
||||
}],
|
||||
time: 210,
|
||||
}, {
|
||||
frames: [{
|
||||
location: "A"
|
||||
}, {
|
||||
location: "E",
|
||||
}, {
|
||||
location: "F"
|
||||
}],
|
||||
time: 330,
|
||||
}, {
|
||||
frames: [{
|
||||
location: "A"
|
||||
}, {
|
||||
location: "B",
|
||||
}, {
|
||||
location: "C"
|
||||
}],
|
||||
time: 460,
|
||||
}, {
|
||||
frames: [{
|
||||
location: "X"
|
||||
}, {
|
||||
location: "Y",
|
||||
}, {
|
||||
location: "Z"
|
||||
}],
|
||||
time: 500
|
||||
}];
|
||||
|
||||
let EXPECTED_OUTPUT = [{
|
||||
blocks: [{
|
||||
x: 0,
|
||||
y: 24,
|
||||
width: 50,
|
||||
height: 12,
|
||||
text: "P"
|
||||
}, {
|
||||
x: 210,
|
||||
y: 24,
|
||||
width: 120,
|
||||
height: 12,
|
||||
text: "F"
|
||||
}, {
|
||||
x: 460,
|
||||
y: 24,
|
||||
width: 40,
|
||||
height: 12,
|
||||
text: "Z"
|
||||
}]
|
||||
}, {
|
||||
blocks: []
|
||||
}, {
|
||||
blocks: []
|
||||
}, {
|
||||
blocks: []
|
||||
}, {
|
||||
blocks: []
|
||||
}, {
|
||||
blocks: [{
|
||||
x: 50,
|
||||
y: 0,
|
||||
width: 410,
|
||||
height: 12,
|
||||
text: "A"
|
||||
}]
|
||||
}, {
|
||||
blocks: [{
|
||||
x: 50,
|
||||
y: 12,
|
||||
width: 160,
|
||||
height: 12,
|
||||
text: "B"
|
||||
}, {
|
||||
x: 330,
|
||||
y: 12,
|
||||
width: 130,
|
||||
height: 12,
|
||||
text: "B"
|
||||
}]
|
||||
}, {
|
||||
blocks: [{
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 50,
|
||||
height: 12,
|
||||
text: "M"
|
||||
}, {
|
||||
x: 50,
|
||||
y: 24,
|
||||
width: 50,
|
||||
height: 12,
|
||||
text: "C"
|
||||
}, {
|
||||
x: 330,
|
||||
y: 24,
|
||||
width: 130,
|
||||
height: 12,
|
||||
text: "C"
|
||||
}]
|
||||
}, {
|
||||
blocks: [{
|
||||
x: 0,
|
||||
y: 12,
|
||||
width: 50,
|
||||
height: 12,
|
||||
text: "N"
|
||||
}, {
|
||||
x: 100,
|
||||
y: 24,
|
||||
width: 110,
|
||||
height: 12,
|
||||
text: "D"
|
||||
}, {
|
||||
x: 460,
|
||||
y: 0,
|
||||
width: 40,
|
||||
height: 12,
|
||||
text: "X"
|
||||
}]
|
||||
}, {
|
||||
blocks: [{
|
||||
x: 210,
|
||||
y: 12,
|
||||
width: 120,
|
||||
height: 12,
|
||||
text: "E"
|
||||
}, {
|
||||
x: 460,
|
||||
y: 12,
|
||||
width: 40,
|
||||
height: 12,
|
||||
text: "Y"
|
||||
}]
|
||||
}];
|
|
@ -746,121 +746,10 @@ FlameGraph.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
const FLAME_GRAPH_BLOCK_HEIGHT = 12; // px
|
||||
|
||||
const PALLETTE_SIZE = 10;
|
||||
const PALLETTE_HUE_OFFSET = Math.random() * 90;
|
||||
const PALLETTE_HUE_RANGE = 270;
|
||||
const PALLETTE_SATURATION = 60;
|
||||
const PALLETTE_BRIGHTNESS = 75;
|
||||
const PALLETTE_OPACITY = 0.7;
|
||||
|
||||
const COLOR_PALLETTE = Array.from(Array(PALLETTE_SIZE)).map((_, i) => "hsla" +
|
||||
"(" + ((PALLETTE_HUE_OFFSET + (i / PALLETTE_SIZE * PALLETTE_HUE_RANGE))|0 % 360) +
|
||||
"," + PALLETTE_SATURATION + "%" +
|
||||
"," + PALLETTE_BRIGHTNESS + "%" +
|
||||
"," + PALLETTE_OPACITY +
|
||||
")"
|
||||
);
|
||||
|
||||
/**
|
||||
* A collection of utility functions converting various data sources
|
||||
* into a format drawable by the FlameGraph.
|
||||
*/
|
||||
let FlameGraphUtils = {
|
||||
/**
|
||||
* Converts a list of samples from the profiler data to something that's
|
||||
* drawable by a FlameGraph widget.
|
||||
*
|
||||
* @param array samples
|
||||
* A list of { time, frames: [{ location }] } objects.
|
||||
* @param array out [optional]
|
||||
* An output storage to reuse for storing the flame graph data.
|
||||
* @return array
|
||||
* The flame graph data.
|
||||
*/
|
||||
createFlameGraphDataFromSamples: function(samples, out = []) {
|
||||
// 1. Create a map of colors to arrays, representing buckets of
|
||||
// blocks inside the flame graph pyramid sharing the same style.
|
||||
|
||||
let buckets = new Map();
|
||||
|
||||
for (let color of COLOR_PALLETTE) {
|
||||
buckets.set(color, []);
|
||||
}
|
||||
|
||||
// 2. Populate the buckets by iterating over every frame in every sample.
|
||||
|
||||
let prevTime = 0;
|
||||
let prevFrames = [];
|
||||
|
||||
for (let { frames, time } of samples) {
|
||||
let frameIndex = 0;
|
||||
|
||||
for (let { location } of frames) {
|
||||
let prevFrame = prevFrames[frameIndex];
|
||||
|
||||
// Frames at the same location and the same depth will be reused.
|
||||
// If there is a block already created, change its width.
|
||||
if (prevFrame && prevFrame.srcData.rawLocation == location) {
|
||||
prevFrame.width = (time - prevFrame.srcData.startTime);
|
||||
}
|
||||
// Otherwise, create a new block for this frame at this depth,
|
||||
// using a simple location based salt for picking a color.
|
||||
else {
|
||||
let salt = this._getStringHash(location);
|
||||
let color = COLOR_PALLETTE[salt % PALLETTE_SIZE];
|
||||
let bucket = buckets.get(color);
|
||||
|
||||
bucket.push(prevFrames[frameIndex] = {
|
||||
srcData: { startTime: prevTime, rawLocation: location },
|
||||
x: prevTime,
|
||||
y: frameIndex * FLAME_GRAPH_BLOCK_HEIGHT,
|
||||
width: time - prevTime,
|
||||
height: FLAME_GRAPH_BLOCK_HEIGHT,
|
||||
text: location
|
||||
});
|
||||
}
|
||||
|
||||
frameIndex++;
|
||||
}
|
||||
|
||||
// Previous frames at stack depths greater than the current sample's
|
||||
// maximum need to be nullified. It's nonsensical to reuse them.
|
||||
for (let i = frameIndex; i < prevFrames.length; i++) {
|
||||
prevFrames[i] = null;
|
||||
}
|
||||
|
||||
prevTime = time;
|
||||
}
|
||||
|
||||
// 3. Convert the buckets into a data source usable by the FlameGraph.
|
||||
// This is a simple conversion from a Map to an Array.
|
||||
|
||||
for (let [color, blocks] of buckets) {
|
||||
out.push({ color, blocks });
|
||||
}
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
/**
|
||||
* Very dumb hashing of a string. Used to pick colors from a pallette.
|
||||
*
|
||||
* @param string input
|
||||
* @return number
|
||||
*/
|
||||
_getStringHash: function(input) {
|
||||
const STRING_HASH_PRIME1 = 7;
|
||||
const STRING_HASH_PRIME2 = 31;
|
||||
|
||||
let hash = STRING_HASH_PRIME1;
|
||||
|
||||
for (let i = 0, len = input.length; i < len; i++) {
|
||||
hash *= STRING_HASH_PRIME2;
|
||||
hash += input.charCodeAt(i);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
// TODO bug 1077459
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче