tor-browser

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

weakRefs-with-symbol-keys.js (3974B)


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