// Test 'compartment revived' GCs, where we do an extra GC if there are // compartments which we expected to die but were kept alive.
// A global used as the destination for transplants.
let transplantTargetGlobal = newGlobal();
function didCompartmentRevivedGC() { return performance.mozMemory.gc.lastStartReason === "COMPARTMENT_REVIVED";
}
function compartmentCount() {
let r = performance.mozMemory.gc.compartmentCount; return r;
}
function startIncrementalGC() {
startgc(1); while (gcstate() === "Prepare" || gcstate() == "MarkRoots") {
gcslice(100, {dontStart: true});
}
assertEq(gcstate(), "Mark");
}
function finishIncrementalGC() { while (gcstate() !== "NotActive") {
gcslice(100, {dontStart: true});
}
assertEq(gcstate(), "NotActive");
}
// Create a new compartment and global and return the global. function createCompartment() { return newGlobal({newCompartment: true});
}
// Create a transplantable object and create a wrapper to it from a new // compartment. Return a function to transplant the target object. function createTransplantableWrapperTarget(wrapperGlobal) {
let {object: target, transplant} = transplantableObject();
wrapperGlobal.wrapper = target; return transplant;
}
// Transplant an object to a new global by calling the transplant // function. This remaps all wrappers pointing to the target object, // potentially keeping dead compartments alive. function transplantTargetAndRemapWrappers(transplant) {
transplant(transplantTargetGlobal);
}
// Test no compartment revived GC triggered in normal cases. function testNormal() {
gc();
assertEq(didCompartmentRevivedGC(), false);
let initialCount = compartmentCount();
createCompartment();
startIncrementalGC();
finishIncrementalGC();
assertEq(compartmentCount(), initialCount);
}
// Test compartment revived GC is triggered by wrapper remapping. function testCompartmentRevived1() {
let initialCount = compartmentCount();
let compartment = createCompartment();
let transplant = createTransplantableWrapperTarget(compartment);
compartment = null;
// Test no compartment revived GC is triggered for compartments transitively // kept alive by black roots. function testCompartmentRevived2() {
let initialCount = compartmentCount();
let compartment = createCompartment();
let transplant = createTransplantableWrapperTarget(compartment);
let liveCompartment = createCompartment();
liveCompartment.wrapper = compartment;
compartment = null;
// Test no compartment revived GC is triggered for compartments transitively // kept alive by gray roots. function testCompartmentRevived3() {
let initialCount = compartmentCount();
let compartment = createCompartment();
let transplant = createTransplantableWrapperTarget(compartment);
let liveCompartment = createCompartment();
liveCompartment.wrapper = compartment;
liveCompartment.eval('grayRoot()[0] = this');
liveCompartment = null;
gc();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.