tor-browser

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

weakRefs.js (3138B)


      1 // https://tc39.es/ecma262/#sec-addtokeptobjects
      2 // When the abstract operation AddToKeptObjects is called with a target object
      3 // reference, it adds the target to an identity Set that will point strongly at
      4 // the target until the end of the current Job.
      5 //
      6 // https://tc39.es/proposal-weakrefs/#sec-weakref-invariants
      7 // When WeakRef.prototype.deref is called, the referent (if it's not already
      8 // dead) is kept alive so that subsequent, synchronous accesses also return the
      9 // object.
     10 
     11 function testSameCompartmentWeakRef(
     12  targetReachable,
     13  weakRefReachable) {
     14 
     15  let target = {};
     16 
     17  let weakref = new WeakRef(target);
     18  assertEq(weakref.deref(), target);
     19 
     20  if (!targetReachable) {
     21    target = undefined;
     22  }
     23 
     24  if (!weakRefReachable) {
     25    weakRef = undefined;
     26  }
     27 
     28  clearKeptObjects();
     29  gc();
     30 
     31  if (weakRefReachable) {
     32    if (targetReachable) {
     33      assertEq(weakref.deref(), target);
     34    } else {
     35      assertEq(weakref.deref(), undefined);
     36    }
     37  }
     38 }
     39 
     40 let serial = 0;
     41 
     42 function testCrossCompartmentWeakRef(
     43  targetReachable,
     44  weakRefReachable,
     45  collectTargetZone,
     46  collectWeakRefZone,
     47  sameZone) {
     48 
     49  gc();
     50 
     51  let id = serial++;
     52  let global = newGlobal(sameZone ? {sameZoneAs: this} : {newCompartment: true});
     53  global.eval('var target = {};');
     54  global.target.id = id;
     55 
     56  let weakref = new WeakRef(global.target);
     57  assertEq(weakref.deref(), global.target);
     58 
     59  if (!targetReachable) {
     60    global.target = undefined;
     61  }
     62 
     63  if (!weakRefReachable) {
     64    weakRef = undefined;
     65  }
     66 
     67  if (collectTargetZone || collectWeakRefZone) {
     68    clearKeptObjects();
     69 
     70    if (collectTargetZone) {
     71      schedulezone(global);
     72    }
     73    if (collectWeakRefZone) {
     74      schedulezone(this);
     75    }
     76 
     77    // Incremental GC so we use sweep groups. Shrinking GC to test updating
     78    // pointers.
     79    startgc(1, 'shrinking');
     80    while (gcstate() !== 'NotActive') {
     81      gcslice(1000, {dontStart: true});
     82    }
     83  }
     84 
     85  if (!(collectWeakRefZone && !weakRefReachable)) {
     86    if (collectTargetZone && !targetReachable) {
     87      assertEq(weakref.deref(), undefined);
     88    } else if (targetReachable) {
     89      assertEq(weakref.deref(), global.target);
     90    } else {
     91      // Target is not strongly reachable but hasn't been collected yet. We
     92      // can get it back through deref() but must check it based on properties.
     93      assertEq(weakref.deref() !== undefined, true);
     94      assertEq(weakref.deref().id, id);
     95    }
     96  }
     97 }
     98 
     99 gczeal(0);
    100 
    101 for (let targetReachable of [true, false]) {
    102  for (let weakRefReachable of [true, false]) {
    103    testSameCompartmentWeakRef(targetReachable, weakRefReachable);
    104  }
    105 }
    106 
    107 for (let targetReachable of [true, false]) {
    108  for (let weakRefReachable of [true, false]) {
    109    for (let collectTargetZone of [true, false]) {
    110      for (let collectWeakRefZone of [true, false]) {
    111        for (let sameZone of [true, false]) {
    112          if (sameZone && (collectTargetZone != collectWeakRefZone)) {
    113            continue;
    114          }
    115 
    116          testCrossCompartmentWeakRef(targetReachable, weakRefReachable,
    117                                      collectTargetZone, collectWeakRefZone, sameZone);
    118        }
    119      }
    120    }
    121  }
    122 }