test_onGarbageCollection-04.js (1992B)
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: 10 // 11 // debuggee gc 12 // | 13 // V 14 // debuggeree's onGarbageCollection 15 // | 16 // V 17 // debuggeree gc 18 // | 19 // V 20 // top level onGarbageCollection 21 // 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. 25 26 Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); 27 registerCleanupFunction(() => { 28 Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); 29 }); 30 31 function run_test() { 32 do_test_pending(); 33 34 const debuggeree = newGlobal(); 35 const debuggee = debuggeree.debuggee = newGlobal(); 36 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 ); 47 48 const dbg = new Debugger(debuggeree); 49 let fired = 0; 50 dbg.memory.onGarbageCollection = _ => { 51 fired++; 52 }; 53 54 debuggee.eval(`gc(this)`); 55 56 // Let first onGarbageCollection runnable get run. 57 executeSoon(() => { 58 59 // Let second onGarbageCollection runnable get run. 60 executeSoon(() => { 61 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); 67 68 debuggeree.dbg.removeAllDebuggees(); 69 do_test_finished(); 70 }); 71 }); 72 }