tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gray-unmarking.js (2483B)


      1 // Test interaction of gray marking / cross zone pointers / aborted GC marking.
      2 
      3 gczeal(0);
      4 
      5 gc();
      6 assertEq(grayBitsValid(), true);
      7 
      8 // Create some globals in different zones.
      9 let g1 = newGlobal({newCompartment: true});
     10 let g2 = newGlobal({newCompartment: true});
     11 let g3 = newGlobal({newCompartment: true});
     12 
     13 // Set up a linked list of objects in different zones: a --> b --> c
     14 g1.eval('var a = {}');
     15 g2.eval('var b = {}');
     16 g3.eval('var c = {}');
     17 g1.a.next = g2.b;
     18 g2.b.next = g3.c;
     19 
     20 // Observe mark state of the objects and remove extra references from the globals.
     21 g1.eval('addMarkObservers([a])');
     22 g2.eval('addMarkObservers([b])');
     23 g3.eval('addMarkObservers([c])');
     24 g2.b = undefined;
     25 g3.c = undefined;
     26 
     27 function checkMarks(a, b, c) {
     28  assertEq(getMarks().join(", "), [a, b, c].join(", "));
     29 }
     30 
     31 // Check GC initially marks everything black.
     32 gc();
     33 checkMarks("black", "black", "black");
     34 
     35 // Replace root with a gray one and check GC marks everything gray.
     36 g1.eval('grayRoot()[0] = a');
     37 g1.a = undefined;
     38 gc();
     39 checkMarks("gray", "gray", "gray");
     40 
     41 // Read the gray root and check gray unmarking marks everything black again.
     42 g1.eval('grayRoot()[0]');
     43 checkMarks("black", "black", "black");
     44 
     45 // Reset everything to gray.
     46 gc();
     47 checkMarks("gray", "gray", "gray");
     48 
     49 // Start marking zone 2.
     50 schedulezone(g2);
     51 startgc(10);
     52 while (gcstate() === "Prepare" || gcstate() === "MarkRoots") {
     53  gcslice(10);
     54 }
     55 assertEq(gcstate(), "Mark");
     56 assertEq(gcstate(g1), "NoGC");
     57 assertEq(gcstate(g2), "MarkBlackOnly");
     58 assertEq(gcstate(g3), "NoGC");
     59 
     60 // Check zone 2's mark bits have been cleared.
     61 checkMarks("gray", "unmarked", "gray");
     62 
     63 // Gray unmarking stops at the zone that is being mraked
     64 g1.eval('grayRoot()[0]');
     65 checkMarks("black", "black", "gray");
     66 
     67 // GC marking handles the gray unmarking by propagaing b's mark state.
     68 finishgc();
     69 assertEq(grayBitsValid(), true);
     70 checkMarks("black", "black", "black");
     71 
     72 // Reset everything to gray.
     73 gc();
     74 checkMarks("gray", "gray", "gray");
     75 
     76 // Repeat the previous test but abort marking after unmarking a. c is
     77 // left as 'gray' (incorrect) but the gray marking state is marked as invalid.
     78 schedulezone(g2);
     79 startgc(10);
     80 while (gcstate() === "Prepare" || gcstate() === "MarkRoots") {
     81  gcslice(10);
     82 }
     83 assertEq(gcstate(), "Mark");
     84 checkMarks("gray", "unmarked", "gray");
     85 g1.eval('grayRoot()[0]');
     86 assertEq(grayBitsValid(), true);
     87 abortgc();
     88 assertEq(grayBitsValid(), false);
     89 checkMarks("black", "black", "gray");
     90 
     91 gc();
     92 checkMarks("gray", "gray", "gray");