summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/gc/weakRefs.js
blob: 667d9cbe2b902e25b88e5e156d21400bbc12a7b3 (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
// https://tc39.es/proposal-weakrefs/#sec-keepduringjob
// When the abstract operation KeepDuringJob is called with a target object
// reference, it adds the target to an identity Set that will point strongly at
// the target until the end of the current Job.
//
// https://tc39.es/proposal-weakrefs/#sec-weakref-invariants
// When WeakRef.prototype.deref is called, the referent (if it's not already
// dead) is kept alive so that subsequent, synchronous accesses also return the
// object.

let wr;
{
  let obj = {};
  wr = new WeakRef(obj);
  obj = null;
}
// obj is out of block scope now, should be GCed.

gc();

assertEq(undefined == wr.deref(), false);

// test for target is in another zone.
var g = newGlobal({newCompartment: true});
var wr2 = new g.WeakRef({});
assertEq(undefined == wr2.deref(), false);

let wr3 = g.eval("new WeakRef({})");
let wr4 = new WeakRef(evalcx('({})', newGlobal({newCompartment: true})));
let wr5 = new g.WeakRef(evalcx('({})', newGlobal({newCompartment: true})));

var that = this;
(function(){
  let wr6 = new g.WeakRef(newGlobal({newCompartment: true}));
  let wr7 = new WeakRef(wr6);
  let wr8 = new WeakRef(that);
  wr6 = null;
  wr7 = null;
  wr8 = null;
})();

gc();

let wr1;
// Allocate the object in the function to prevent marked as a singleton so the
// object won't be kept alive by IC stub.
function allocObj() { return {}; }

(function () {
  let obj = allocObj();
  wr1 = new WeakRef(obj);
  obj = null;
})();

assertEq(undefined === wr1.deref(), false);

gc();

// See https://tc39.es/proposal-weakrefs/#sec-weakref-invariants
// This list is reset when synchronous work is done using the
// ClearKeptObjects abstract operation.
//
// TODO:
// Bug 1603070: The shell has no way to start a new task.
//
// In shell, there's no window object hence there isn't a setTimeout nor event
// handler, so we use this function to simulate that.
// The timeout function in shell doesn't launch a new job, and it will cause
// this test file timeout so I didn't use it here.
function simulateEndOfJob(fn) {
  clearKeptObjects();
  gc();
  fn();
}

simulateEndOfJob(() => {
  assertEq(undefined, wr1.deref());
});