зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1582741 - Create a test for balanced native allocation; r=canaltinova
This file adds coverage for the balanced native allocations feature from the previous commit. It asserts that a de-allocation will have a matching allocation. Differential Revision: https://phabricator.services.mozilla.com/D51936 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
bcab6046af
Коммит
61e8d2fc21
|
@ -31,19 +31,14 @@ add_task(async () => {
|
|||
);
|
||||
doWork();
|
||||
|
||||
info(
|
||||
"Go ahead and wait for a periodic sample as well, in order to make sure that " +
|
||||
"the native allocations play nicely with the rest of the profiler machinery."
|
||||
);
|
||||
await Services.profiler.waitOnePeriodicSampling();
|
||||
|
||||
info("Get the profile data and analyze it.");
|
||||
const profile = await stopAndGetProfile();
|
||||
|
||||
const allocationPayloads = getPayloadsOfType(
|
||||
profile.threads[0],
|
||||
"Native allocation"
|
||||
);
|
||||
const {
|
||||
allocationPayloads,
|
||||
unmatchedAllocations,
|
||||
logAllocationsAndDeallocations,
|
||||
} = getAllocationInformation(profile);
|
||||
|
||||
Assert.greater(
|
||||
allocationPayloads.length,
|
||||
|
@ -51,6 +46,23 @@ add_task(async () => {
|
|||
"Native allocation payloads were recorded for the parent process' main thread when " +
|
||||
"the Native Allocation feature was turned on."
|
||||
);
|
||||
|
||||
if (unmatchedAllocations.length !== 0) {
|
||||
info(
|
||||
"There were unmatched allocations. Log all of the allocations and " +
|
||||
"deallocations in order to aid debugging."
|
||||
);
|
||||
logAllocationsAndDeallocations();
|
||||
ok(
|
||||
false,
|
||||
"Found a deallocation that did not have a matching allocation site. " +
|
||||
"This could happen if balanced allocations is broken, or if the the " +
|
||||
"buffer size of this test was too small, and some markers ended up " +
|
||||
"rolling off."
|
||||
);
|
||||
}
|
||||
|
||||
ok(true, "All deallocation sites had matching allocations.");
|
||||
}
|
||||
|
||||
info("Restart the profiler, to ensure that we get no more allocations.");
|
||||
|
@ -81,3 +93,64 @@ function doWork() {
|
|||
this.n += Math.random();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the allocation payloads, and find the unmatched allocations.
|
||||
*/
|
||||
function getAllocationInformation(profile) {
|
||||
// Get all of the allocation payloads.
|
||||
const allocationPayloads = getPayloadsOfType(
|
||||
profile.threads[0],
|
||||
"Native allocation"
|
||||
);
|
||||
|
||||
// Decide what is an allocation and deallocation.
|
||||
const allocations = allocationPayloads.filter(
|
||||
payload => ensureIsNumber(payload.size) >= 0
|
||||
);
|
||||
const deallocations = allocationPayloads.filter(
|
||||
payload => ensureIsNumber(payload.size) < 0
|
||||
);
|
||||
|
||||
// Now determine the unmatched allocations by building a set
|
||||
const allocationSites = new Set(
|
||||
allocations.map(({ memoryAddress }) => memoryAddress)
|
||||
);
|
||||
|
||||
const unmatchedAllocations = deallocations.filter(
|
||||
({ memoryAddress }) => !allocationSites.has(memoryAddress)
|
||||
);
|
||||
|
||||
// Provide a helper to log out the allocations and deallocations on failure.
|
||||
function logAllocationsAndDeallocations() {
|
||||
for (const { memoryAddress } of allocations) {
|
||||
console.log("Allocations", formatHex(memoryAddress));
|
||||
allocationSites.add(memoryAddress);
|
||||
}
|
||||
|
||||
for (const { memoryAddress } of deallocations) {
|
||||
console.log("Deallocations", formatHex(memoryAddress));
|
||||
}
|
||||
|
||||
for (const { memoryAddress } of unmatchedAllocations) {
|
||||
console.log("Deallocation with no allocation", formatHex(memoryAddress));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
allocationPayloads,
|
||||
unmatchedAllocations,
|
||||
logAllocationsAndDeallocations,
|
||||
};
|
||||
}
|
||||
|
||||
function ensureIsNumber(value) {
|
||||
if (typeof value !== "number") {
|
||||
throw new Error(`Expected a number: ${value}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function formatHex(number) {
|
||||
return `0x${number.toString(16)}`;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче