зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1644393 - Fix test case to work in beta/release builds r=sfink
This changes the test to be much more specific. It adds a way of making gcslice only trigger a slice during an incremental collection, without which the collection loop can loop forever. Differential Revision: https://phabricator.services.mozilla.com/D79136
This commit is contained in:
Родитель
bc84cbd3de
Коммит
925ac1a2d0
|
@ -1526,14 +1526,14 @@ static bool FinishGC(JSContext* cx, unsigned argc, Value* vp) {
|
|||
static bool GCSlice(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (args.length() > 1) {
|
||||
if (args.length() > 2) {
|
||||
RootedObject callee(cx, &args.callee());
|
||||
ReportUsageErrorASCII(cx, callee, "Wrong number of arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto budget = SliceBudget::unlimited();
|
||||
if (args.length() == 1) {
|
||||
if (args.length() >= 1) {
|
||||
uint32_t work = 0;
|
||||
if (!ToUint32(cx, args[0], &work)) {
|
||||
return false;
|
||||
|
@ -1541,11 +1541,21 @@ static bool GCSlice(JSContext* cx, unsigned argc, Value* vp) {
|
|||
budget = SliceBudget(WorkBudget(work));
|
||||
}
|
||||
|
||||
bool dontStart = false;
|
||||
if (args.get(1).isObject()) {
|
||||
RootedObject options(cx, &args[1].toObject());
|
||||
RootedValue v(cx);
|
||||
if (!JS_GetProperty(cx, options, "dontStart", &v)) {
|
||||
return false;
|
||||
}
|
||||
dontStart = ToBoolean(v);
|
||||
}
|
||||
|
||||
JSRuntime* rt = cx->runtime();
|
||||
if (!rt->gc.isIncrementalGCInProgress()) {
|
||||
rt->gc.startDebugGC(GC_NORMAL, budget);
|
||||
} else {
|
||||
if (rt->gc.isIncrementalGCInProgress()) {
|
||||
rt->gc.debugGCSlice(budget);
|
||||
} else if (!dontStart) {
|
||||
rt->gc.startDebugGC(GC_NORMAL, budget);
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
|
@ -6156,8 +6166,12 @@ gc::ZealModeHelpText),
|
|||
" Finish an in-progress incremental GC, if none is running then do nothing."),
|
||||
|
||||
JS_FN_HELP("gcslice", GCSlice, 1, 0,
|
||||
"gcslice([n])",
|
||||
" Start or continue an an incremental GC, running a slice that processes about n objects."),
|
||||
"gcslice([n [, options]])",
|
||||
" Start or continue an an incremental GC, running a slice that processes\n"
|
||||
" about n objects. Takes an optional options object, which may contain the\n"
|
||||
" following properties:\n"
|
||||
" dontStart: do not start a new incremental GC if one is not already\n"
|
||||
" running"),
|
||||
|
||||
JS_FN_HELP("abortgc", AbortGC, 1, 0,
|
||||
"abortgc()",
|
||||
|
@ -6512,7 +6526,7 @@ gc::ZealModeHelpText),
|
|||
JS_FN_HELP("getBacktrace", GetBacktrace, 1, 0,
|
||||
"getBacktrace([options])",
|
||||
" Return the current stack as a string. Takes an optional options object,\n"
|
||||
" which may contain any or all of the boolean properties\n"
|
||||
" which may contain any or all of the boolean properties:\n"
|
||||
" options.args - show arguments to each function\n"
|
||||
" options.locals - show local variables in each frame\n"
|
||||
" options.thisprops - show the properties of the 'this' object of each frame\n"),
|
||||
|
|
|
@ -1,21 +1,36 @@
|
|||
// |jit-test| --enable-weak-refs; --no-ti
|
||||
// |jit-test| --enable-weak-refs
|
||||
|
||||
for (let i = 70; i > 50; i--) {
|
||||
gc();
|
||||
gczeal(10, i);
|
||||
for (let p of [false, true]) {
|
||||
f(p);
|
||||
|
||||
f(true, false, false);
|
||||
f(true, false, true);
|
||||
// Run an incremental GC to completion.
|
||||
startgc(1);
|
||||
while (gcstate() !== 'NotActive') {
|
||||
gcslice(10000, { dontStart: true });
|
||||
}
|
||||
}
|
||||
|
||||
function ccwToObject() {
|
||||
return evalcx('({})', newGlobal({newCompartment: true}));
|
||||
}
|
||||
|
||||
function f(x, y, z) {
|
||||
let registry = new FinalizationRegistry(value => {});
|
||||
let target = x ? ccwToObject() : {};
|
||||
let heldValue = y ? ccwToObject() : {};
|
||||
let token = z ? ccwToObject() : {};
|
||||
registry.register(target, heldValue, token);
|
||||
function ccwToRegistry() {
|
||||
return evalcx('new FinalizationRegistry(value => {})',
|
||||
newGlobal({newCompartment: true}));
|
||||
}
|
||||
|
||||
function f(p) {
|
||||
let registry = ccwToRegistry();
|
||||
let target = ccwToObject();
|
||||
registry.register(target, undefined);
|
||||
|
||||
// Add a CCW from registry to target zone or vice versa to control
|
||||
// the order the zones are swept in.
|
||||
if (p) {
|
||||
registry.ptr = target;
|
||||
} else {
|
||||
target.ptr = registry;
|
||||
}
|
||||
|
||||
gc();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче