weak-marking-budget.js (2404B)
1 // Make enterWeakMarkingMode expensive so it gets forced into a single slice. 2 3 gczeal(0); // We need full control here. 4 5 var keys = []; 6 var maps = Array(1000).fill().map(() => new WeakMap); 7 for (const map of maps) { 8 for (let i = 0; i < 100; i++) { 9 // The key will die the next major collection , but will need to be put 10 // into the ephemeron table first. 11 let key = {}; 12 keys.push(key); 13 map.set(key, {}); 14 } 15 } 16 17 minorgc(); 18 keys = undefined; 19 20 // Slowly work forward until we reach Mark. 21 startgc(10); 22 while (["Prepare", "MarkRoots"].includes(gcstate())) { 23 gcslice(10); 24 } 25 assertEq(gcstate(), "Mark"); 26 27 // This will yield before leaving marking, in order to give the first sweep 28 // slice a full budget. 29 print("gcslice(10000) #1"); 30 gcslice(10000); 31 assertEq(gcstate(), "Mark"); 32 33 // First Sweep slice will hit the long enterWeakMarkingMode and yield as soon as 34 // the budget runs out, and set up the next Sweep slice to finish. 35 print("gcslice(10000) #2"); 36 gcslice(10000); 37 assertEq(gcstate(), "Sweep"); 38 hasFunction["currentgc"] && assertEq(currentgc().finishMarkingDuringSweeping, true); 39 40 // This slice will finish the marking, but will go way over budget and so will 41 // yield as soon as the marking is done. This will still be during Sweep (in the 42 // middle of sweepWeakCaches). 43 print("gcslice(1) #3"); 44 // Use more than gcslice(1) because it is possible to get a few things added to 45 // the mark stack from read barriers. 46 gcslice(100); 47 assertEq(gcstate(), "Sweep"); 48 hasFunction["currentgc"] && assertEq(currentgc().finishMarkingDuringSweeping, false); 49 50 // There's still a lot of sweeping left to do, because all of the dead stuff 51 // needs to be finalized. 52 finishgc(); 53 54 // Do another GC without a slow enterWMM, to confirm that the extra slice is not 55 // requested. (The previous GC will have thrown out all of the WeakMaps' 56 // entries, so this will just be doing one step for each of the 1000 WeakMaps 57 // instead of 1000 * (1 + 100) for the WeakMaps plus their keys.) 58 startgc(10); 59 while (["Prepare", "MarkRoots"].includes(gcstate())) { 60 gcslice(10); 61 } 62 assertEq(gcstate(), "Mark"); 63 64 gcslice(10000); 65 assertEq(gcstate(), "Mark"); 66 67 gcslice(1); 68 assertEq(gcstate(), "Sweep"); 69 hasFunction["currentgc"] && assertEq(currentgc().finishMarkingDuringSweeping, false); 70 71 gcslice(1); 72 assertEq(gcstate(), "Sweep"); 73 hasFunction["currentgc"] && assertEq(currentgc().finishMarkingDuringSweeping, false);