blob: c3d9a0516576a78f2b99b03a8e2f4165a0dbb907 [file] [log] [blame]
// These tests will be using object literals as keys, and we want some of them
// to be dead after being inserted into a WeakMap. That means we must wrap
// everything in functions because it seems like the toplevel script hangs onto
// its object literals.
// Cross-compartment WeakMap keys work by storing a cross-compartment wrapper
// in the WeakMap, and the actual "delegate" object in the target compartment
// is the thing whose liveness is checked.
var g2 = newGlobal();
g2.eval('function genObj(name) { return {"name": name} }');
function basicSweeping() {
var wm1 = new WeakMap();
wm1.set({'name': 'obj1'}, {'name': 'val1'});
var hold = g2.genObj('obj2');
wm1.set(hold, {'name': 'val2'});
wm1.set({'name': 'obj3'}, {'name': 'val3'});
var obj4 = g2.genObj('obj4');
wm1.set(obj4, {'name': 'val3'});
obj4 = undefined;
startgc(100000, 'shrinking');
gcslice();
assertEq(wm1.get(hold).name, 'val2');
assertEq(nondeterministicGetWeakMapKeys(wm1).length, 1);
}
basicSweeping();
// Same, but behind an additional WM layer, to avoid ordering problems (not
// that I've checked that basicSweeping even has any problems.)
function basicSweeping2() {
var wm1 = new WeakMap();
wm1.set({'name': 'obj1'}, {'name': 'val1'});
var hold = g2.genObj('obj2');
wm1.set(hold, {'name': 'val2'});
wm1.set({'name': 'obj3'}, {'name': 'val3'});
var obj4 = g2.genObj('obj4');
wm1.set(obj4, {'name': 'val3'});
obj4 = undefined;
var base1 = {'name': 'base1'};
var base2 = {'name': 'base2'};
var wm_base1 = new WeakMap();
var wm_base2 = new WeakMap();
wm_base1.set(base1, wm_base2);
wm_base2.set(base2, wm1);
wm1 = wm_base2 = undefined;
startgc(100000, 'shrinking');
gcslice();
assertEq(nondeterministicGetWeakMapKeys(wm_base1).length, 1);
wm_base2 = wm_base1.get(base1);
assertEq(nondeterministicGetWeakMapKeys(wm_base2).length, 1);
assertEq(nondeterministicGetWeakMapKeys(wm_base1)[0], base1);
assertEq(nondeterministicGetWeakMapKeys(wm_base2)[0], base2);
wm_base2 = wm_base1.get(base1);
wm1 = wm_base2.get(base2);
assertEq(wm1.get(hold).name, 'val2');
assertEq(nondeterministicGetWeakMapKeys(wm1).length, 1);
}
basicSweeping2();
// Scatter the weakmap, the keys, and the values among different compartments.
function tripleZoneMarking() {
var g1 = newGlobal();
var g2 = newGlobal();
var g3 = newGlobal();
var wm = g1.eval("new WeakMap()");
var key = g2.eval("({'name': 'obj1'})");
var value = g3.eval("({'name': 'val1'})");
g1 = g2 = g3 = undefined;
wm.set(key, value);
// Make all of it only reachable via a weakmap in the main test compartment,
// so that all of this happens during weak marking mode. Use the weakmap as
// its own key, so we know that the weakmap will get traced before the key
// and therefore will populate the weakKeys table and all of that jazz.
var base_wm = new WeakMap();
base_wm.set(base_wm, [ wm, key ]);
wm = key = value = undefined;
startgc(100000, 'shrinking');
gcslice();
var keys = nondeterministicGetWeakMapKeys(base_wm);
assertEq(keys.length, 1);
var [ wm, key ] = base_wm.get(keys[0]);
assertEq(key.name, "obj1");
value = wm.get(key);
assertEq(value.name, "val1");
}
tripleZoneMarking();
function enbugger() {
var g = newGlobal();
var dbg = new Debugger;
g.eval("function debuggee_f() { return 1; }");
g.eval("function debuggee_g() { return 1; }");
dbg.addDebuggee(g);
var [ s ] = dbg.findScripts({global: g}).filter(s => s.displayName == "debuggee_f");
var [ s2 ] = dbg.findScripts({global: g}).filter(s => s.displayName == "debuggee_g");
g.eval("debuggee_f = null");
gc();
dbg.removeAllDebuggees();
gc();
assertEq(s.displayName, "debuggee_f");
var wm = new WeakMap;
var obj = Object.create(null);
var obj2 = Object.create(null);
wm.set(obj, s);
wm.set(obj2, obj);
wm.set(s2, obj2);
s = s2 = obj = obj2 = null;
gc();
}
enbugger();