summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/gc/weak-marking-02.js
blob: c3d9a0516576a78f2b99b03a8e2f4165a0dbb907 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 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();