Bug 1184486 - Let PerformanceStats.jsm play nicer with process-per-tab. r=mconley

--HG--
extra : amend_source : a7a1e4f69592e8828469f84db6d6665d40fd68be
extra : transplant_source : %EB%C5q%CA%01%DC%3A%D5%07Y%19%07%8A%DCH%B0II%CA%C3
extra : histedit_source : d2d769675008d662ea78ae5b04e70c926296b3c1
This commit is contained in:
David Rajchenbach-Teller 2015-07-16 12:19:17 +02:00
Родитель e61fe71db0
Коммит 44f4adbd13
4 изменённых файлов: 40 добавлений и 13 удалений

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

@ -49,7 +49,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "finalizer",
// and that we can release/close the probes it holds.
const FINALIZATION_TOPIC = "performancemonitor-finalize";
const PROPERTIES_META_IMMUTABLE = ["addonId", "isSystem", "isChildProcess", "groupId"];
const PROPERTIES_META_IMMUTABLE = ["addonId", "isSystem", "isChildProcess", "groupId", "processId"];
const PROPERTIES_META = [...PROPERTIES_META_IMMUTABLE, "windowId", "title", "name"];
// How long we wait for children processes to respond.

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

@ -22,7 +22,7 @@
* All values are monotonic and are updated only when
* `nsIPerformanceStatsService.isStopwatchActive` is `true`.
*/
[scriptable, uuid(1bc2d016-e9ae-4186-97c6-9478eddda245)]
[scriptable, uuid(89440555-dd81-4a22-8747-049bcf0ab586)]
interface nsIPerformanceStats: nsISupports {
/**
* An identifier unique to the component.
@ -91,6 +91,11 @@ interface nsIPerformanceStats: nsISupports {
*/
readonly attribute bool isSystem;
/**
* The process running this group.
*/
readonly attribute unsigned long long processId;
/**
* Jank indicator.
*
@ -104,7 +109,7 @@ interface nsIPerformanceStats: nsISupports {
/**
* A snapshot of the performance data of the process.
*/
[scriptable, uuid(29ecebd0-908a-4b34-8f62-a6015dea1141)]
[scriptable, uuid(2e0c50e2-3aff-4cc8-88a6-c0dc200da8fc)]
interface nsIPerformanceSnapshot: nsISupports {
/**
* Data on all individual components.

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

@ -35,6 +35,7 @@ public:
const nsAString& aAddonId,
const nsAString& aTitle,
const uint64_t aWindowId,
const uint64_t aProcessId,
const bool aIsSystem,
const js::PerformanceData& aPerformanceData)
: mName(aName)
@ -42,6 +43,7 @@ public:
, mAddonId(aAddonId)
, mTitle(aTitle)
, mWindowId(aWindowId)
, mProcessId(aProcessId)
, mIsSystem(aIsSystem)
, mPerformanceData(aPerformanceData)
{
@ -121,7 +123,7 @@ public:
};
/* void getDurations (out unsigned long aCount, [array, size_is (aCount), retval] out unsigned long long aNumberOfOccurrences); */
NS_IMETHODIMP GetDurations(uint32_t *aCount, uint64_t **aNumberOfOccurrences) override {
NS_IMETHOD GetDurations(uint32_t *aCount, uint64_t **aNumberOfOccurrences) override {
const size_t length = mozilla::ArrayLength(mPerformanceData.durations);
if (aCount) {
*aCount = length;
@ -133,6 +135,14 @@ public:
return NS_OK;
};
/*
readonly attribute unsigned long long processId;
*/
NS_IMETHODIMP GetProcessId(uint64_t* processId) override {
*processId = mProcessId;
return NS_OK;
}
private:
nsString mName;
nsString mParentId;
@ -140,6 +150,7 @@ private:
nsString mAddonId;
nsString mTitle;
uint64_t mWindowId;
uint64_t mProcessId;
bool mIsSystem;
js::PerformanceData mPerformanceData;
@ -358,7 +369,7 @@ nsPerformanceSnapshot::ImportStats(JSContext* cx, const js::PerformanceData& per
bool isSystem = GetIsSystem(cx, global);
nsCOMPtr<nsIPerformanceStats> result =
new nsPerformanceStats(name, parent, groupId, addonId, title, windowId, isSystem, performance);
new nsPerformanceStats(name, parent, groupId, addonId, title, windowId, mProcessId, isSystem, performance);
return result.forget();
}
@ -402,6 +413,7 @@ nsPerformanceSnapshot::Init(JSContext* cx, uint64_t processId) {
NS_LITERAL_STRING(""), // add-on id
NS_LITERAL_STRING(""), // title
0, // window id
mProcessId, // process id
true, // isSystem
processStats);
return NS_OK;

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

@ -9,12 +9,16 @@
* to the top window.
*/
Cu.import("resource://gre/modules/PerformanceStats.jsm", this);
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://testing-common/ContentTask.jsm", this);
const URL = "http://example.com/browser/toolkit/components/perfmonitoring/tests/browser/browser_compartments.html?test=" + Math.random();
const PARENT_TITLE = `Main frame for test browser_compartments.js ${Math.random()}`;
const FRAME_TITLE = `Subframe for test browser_compartments.js ${Math.random()}`;
const PARENT_PID = Services.appinfo.processID;
// This function is injected as source as a frameScript
function frameScript() {
try {
@ -22,7 +26,7 @@ function frameScript() {
const { utils: Cu, classes: Cc, interfaces: Ci } = Components;
Cu.import("resource://gre/modules/PerformanceStats.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let performanceStatsService =
Cc["@mozilla.org/toolkit/performance-stats-service;1"].
getService(Ci.nsIPerformanceStatsService);
@ -33,7 +37,7 @@ function frameScript() {
addMessageListener("compartments-test:getStatistics", () => {
try {
monitor.promiseSnapshot().then(snapshot => {
sendAsyncMessage("compartments-test:getStatistics", snapshot);
sendAsyncMessage("compartments-test:getStatistics", {snapshot, pid: Services.appinfo.processID});
});
} catch (ex) {
Cu.reportError("Error in content (getStatistics): " + ex);
@ -135,19 +139,21 @@ function monotinicity_tester(source, testName) {
return;
}
let name = `${testName}: ${iteration++}`;
let snapshot = yield source();
if (!snapshot) {
let result = yield source();
if (!result) {
// This can happen at the end of the test when we attempt
// to communicate too late with the content process.
window.clearInterval(interval);
return;
}
let {pid, snapshot} = result;
// Sanity check on the process data.
sanityCheck(previous.processData, snapshot.processData);
SilentAssert.equal(snapshot.processData.isSystem, true);
SilentAssert.equal(snapshot.processData.name, "<process>");
SilentAssert.equal(snapshot.processData.addonId, "");
SilentAssert.equal(snapshot.processData.processId, pid);
previous.procesData = snapshot.processData;
// Sanity check on components data.
@ -160,10 +166,14 @@ function monotinicity_tester(source, testName) {
]) {
// Note that we cannot expect components data to be always smaller
// than process data, as `getrusage` & co are not monotonic.
SilentAssert.leq(item[probe][k], 2 * snapshot.processData[probe][k],
`Sanity check (${testName}): ${k} of component is not impossibly larger than that of process`);
SilentAssert.leq(item[probe][k], 3 * snapshot.processData[probe][k],
`Sanity check (${name}): ${k} of component is not impossibly larger than that of process`);
}
let isCorrectPid = (item.processId == pid && !item.isChildProcess)
|| (item.processId != pid && item.isChildProcess);
SilentAssert.ok(isCorrectPid, `Pid check (${name}): the item comes from the right process`);
let key = item.groupId;
if (map.has(key)) {
let old = map.get(key);
@ -222,7 +232,7 @@ add_task(function* test() {
info("Deactivating sanity checks under Windows (bug 1151240)");
} else {
info("Setting up sanity checks");
monotinicity_tester(() => monitor.promiseSnapshot(), "parent process");
monotinicity_tester(() => monitor.promiseSnapshot().then(snapshot => ({snapshot, pid: PARENT_PID})), "parent process");
monotinicity_tester(() => promiseContentResponseOrNull(browser, "compartments-test:getStatistics", null), "content process" );
}
@ -242,7 +252,7 @@ add_task(function* test() {
});
info("Titles set");
let stats = (yield promiseContentResponse(browser, "compartments-test:getStatistics", null));
let {snapshot: stats} = (yield promiseContentResponse(browser, "compartments-test:getStatistics", null));
let titles = [for(stat of stats.componentsData) stat.title];