Bug 1915045 Ensure decode tasks are scheduled on BufferingState::Enter() r=media...
[gecko.git] / js / xpconnect / tests / unit / test_onGarbageCollection-04.js
blob72e6d322849719bca08b8867d55590dbe97a56e3
1 // Test that the onGarbageCollection reentrancy guard is on a per Debugger
2 // basis. That is if our first Debugger is observing our second Debugger's
3 // compartment, and this second Debugger triggers a GC inside its
4 // onGarbageCollection hook, the first Debugger's onGarbageCollection hook is
5 // still called.
6 //
7 // This is the scenario we are setting up: top level debugging the `debuggeree`
8 // global, which is debugging the `debuggee` global. Then, we trigger the
9 // following events:
11 //     debuggee gc
12 //         |
13 //         V
14 //     debuggeree's onGarbageCollection
15 //         |
16 //         V
17 //     debuggeree gc
18 //         |
19 //         V
20 //     top level onGarbageCollection
22 // Note that the top level's onGarbageCollection hook should be fired, at the
23 // same time that we are preventing reentrancy into debuggeree's
24 // onGarbageCollection hook.
26 Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true);
27 registerCleanupFunction(() => {
28   Services.prefs.clearUserPref("security.allow_eval_with_system_principal");
29 });
31 function run_test() {
32   do_test_pending();
34   const debuggeree = newGlobal();
35   const debuggee = debuggeree.debuggee = newGlobal();
37   debuggeree.eval(
38     `
39     var dbg = new Debugger(this.debuggee);
40     var fired = 0;
41     dbg.memory.onGarbageCollection = _ => {
42       fired++;
43       gc(this);
44     };
45     `
46   );
48   const dbg = new Debugger(debuggeree);
49   let fired = 0;
50   dbg.memory.onGarbageCollection = _ => {
51     fired++;
52   };
54   debuggee.eval(`gc(this)`);
56   // Let first onGarbageCollection runnable get run.
57   executeSoon(() => {
59     // Let second onGarbageCollection runnable get run.
60     executeSoon(() => {
62       // Even though we request GC'ing a single zone, we can't rely on that
63       // behavior and both zones could have been scheduled for gc for both
64       // gc(this) calls.
65       ok(debuggeree.fired >= 1);
66       ok(fired >= 1);
68       debuggeree.dbg.removeAllDebuggees();
69       do_test_finished();
70     });
71   });