tor-browser

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

array-push-multiple-frozen.js (2274B)


      1 // |jit-test| --no-threads
      2 
      3 // This test case check's Ion ability to recover from an allocation failure in
      4 // the inlining of Array.prototype.push, when given multiple arguments. Note,
      5 // that the following are not equivalent in case of failures:
      6 //
      7 //   arr = [];
      8 //   arr.push(1,2,3); // OOM ---> arr == []
      9 //
     10 //   arr = [];
     11 //   arr.push(1);
     12 //   arr.push(2); // OOM --> arr == [1]
     13 //   arr.push(3);
     14 
     15 function canIoncompile() {
     16  while (true) {
     17    var i = inIon();
     18    if (i)
     19      return i;
     20  }
     21 }
     22 
     23 if (canIoncompile() != true)
     24  quit();
     25 if ("gczeal" in this)
     26  gczeal(0);
     27 
     28 function pushLimits(limit, offset, arr, freeze) {
     29  arr = arr || [];
     30  arr.push(0,1,2,3,4,5,6,7,8,9);
     31  arr.length = offset;
     32  var l = arr.length;
     33  var was = inIon();
     34  oomAtAllocation(limit);
     35  try {
     36    for (var i = 0; i < 50; i++)
     37      arr.push(0,1,2,3,4,5,6,7,8,9);
     38    if (freeze)
     39      arr.frozen();
     40    for (var i = 0; i < 100; i++)
     41      arr.push(0,1,2,3,4,5,6,7,8,9);
     42  } catch (e) {
     43    // Catch OOM.
     44  }
     45  resetOOMFailure();
     46  assertEq(arr.length % 10, l);
     47  // Check for a bailout.
     48  var is = inIon();
     49  return was ? is ? 1 : 2 : 0;
     50 }
     51 
     52 // We need this limit to be high enough to be able to OSR in the for-loop of
     53 // pushLimits.
     54 var limit = 1024 * 1024 * 1024;
     55 while(true) {
     56  var res = pushLimits(limit, 0);
     57 
     58  if (res == 0) {
     59    limit = 1024 * 1024 * 1024;
     60  } else if (res == 1) { // Started and finished in Ion.
     61    if (limit <= 1) // If we are not in the Jit.
     62      break;
     63    // We want to converge quickly to a state where the memory is limited
     64    // enough to cause failures in array.prototype.push.
     65    limit = (limit / 2) | 0;
     66  } else if (res == 2) { // Started in Ion, and finished in Baseline.
     67    if (limit < 10) {
     68      // This is used to offset the OOM location, such that we can test
     69      // each steps of the Array.push function, when it is jitted.
     70      for (var off = 1; off < 10; off++) {
     71        var arr = [];
     72        try {
     73          pushLimits(limit, off, arr, true);
     74        } catch (e) {
     75          // Cacth OOM produced while generating the error message.
     76        }
     77        if (arr.length > 10) assertEq(arr[arr.length - 1], 9);
     78        else assertEq(arr[arr.length - 1], arr.length - 1);
     79      }
     80    }
     81    if (limit == 1)
     82      break;
     83    limit--;
     84  }
     85 }