tor-browser

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

recover-arrays.js (8519B)


      1 // Ion eager fails the test below because we have not yet created any
      2 // template object in baseline before running the content of the top-level
      3 // function.
      4 if (getJitCompilerOptions()["ion.warmup.trigger"] <= 100)
      5    setJitCompilerOption("ion.warmup.trigger", 100);
      6 
      7 // This test checks that we are able to remove the getelem & setelem with scalar
      8 // replacement, so we should not force inline caches, as this would skip the
      9 // generation of getelem & setelem instructions.
     10 if (getJitCompilerOptions()["ion.forceinlineCaches"])
     11    setJitCompilerOption("ion.forceinlineCaches", 0);
     12 
     13 // Prevent the GC from cancelling Ion compilations, when we expect them to succeed
     14 gczeal(0);
     15 
     16 // This function is used to force a bailout when it is inlined, and to recover
     17 // the frame which is inlining this function.
     18 var resumeHere = function (i) { if (i >= 99) bailout(); };
     19 
     20 // This function is used to cause an invalidation after having removed a branch
     21 // after DCE.  This is made to check if we correctly recover an array
     22 // allocation.
     23 var uceFault = function (i) {
     24    if (i > 98)
     25        uceFault = function (i) { return true; };
     26    return false;
     27 };
     28 
     29 // This function is used to ensure that we do escape the array, and thus prevent
     30 // any escape analysis.
     31 var global_arr;
     32 function escape(arr) { global_arr = arr; }
     33 
     34 // Check Array length defined by the literal.
     35 function array0Length(i) {
     36    var a = [];
     37    assertRecoveredOnBailout(a, true);
     38    return a.length;
     39 }
     40 
     41 function array0LengthBail(i) {
     42    var a = [];
     43    resumeHere(i);
     44    assertRecoveredOnBailout(a, true);
     45    return a.length;
     46 }
     47 
     48 function array1Length(i) {
     49    var a = [ i ];
     50    assertRecoveredOnBailout(a, true);
     51    return a.length;
     52 }
     53 
     54 function array1LengthBail(i) {
     55    var a = [ i ];
     56    resumeHere(i);
     57    assertRecoveredOnBailout(a, true);
     58    return a.length;
     59 }
     60 
     61 function array2Length(i) {
     62    var a = [ i, i ];
     63    assertRecoveredOnBailout(a, true);
     64    return a.length;
     65 }
     66 
     67 function array2LengthBail(i) {
     68    var a = [ i, i ];
     69    resumeHere(i);
     70    assertRecoveredOnBailout(a, true);
     71    return a.length;
     72 }
     73 
     74 // Check that we can correctly gc in the middle of an incomplete object
     75 // intialization.
     76 function arrayWithGCInit0(i) {
     77    var a = [ (i == 99 ? (gc(), i) : i), i ];
     78    assertRecoveredOnBailout(a, true);
     79    return a.length;
     80 }
     81 
     82 function arrayWithGCInit1(i) {
     83    var a = [ i, (i == 99 ? (gc(), i) : i) ];
     84    assertRecoveredOnBailout(a, true);
     85    return a.length;
     86 }
     87 
     88 function arrayWithGCInit2(i) {
     89    var a = [ i, i ];
     90    if (i == 99) gc();
     91    assertRecoveredOnBailout(a, true);
     92    return a.length;
     93 }
     94 
     95 // Check Array content
     96 function array1Content(i) {
     97    var a = [ i ];
     98    assertEq(a[0], i);
     99    assertRecoveredOnBailout(a, true);
    100    return a.length;
    101 }
    102 function array1ContentBail0(i) {
    103    var a = [ i ];
    104    resumeHere(i);
    105    assertEq(a[0], i);
    106    assertRecoveredOnBailout(a, true);
    107    return a.length;
    108 }
    109 function array1ContentBail1(i) {
    110    var a = [ i ];
    111    assertEq(a[0], i);
    112    resumeHere(i);
    113    assertRecoveredOnBailout(a, true);
    114    return a.length;
    115 }
    116 
    117 function array2Content(i) {
    118    var a = [ i, i ];
    119    assertEq(a[0], i);
    120    assertEq(a[1], i);
    121    assertRecoveredOnBailout(a, true);
    122    return a.length;
    123 }
    124 
    125 function array2ContentBail0(i) {
    126    var a = [ i, i ];
    127    resumeHere(i);
    128    assertEq(a[0], i);
    129    assertEq(a[1], i);
    130    assertRecoveredOnBailout(a, true);
    131    return a.length;
    132 }
    133 
    134 function array2ContentBail1(i) {
    135    var a = [ i, i ];
    136    assertEq(a[0], i);
    137    resumeHere(i);
    138    assertEq(a[1], i);
    139    assertRecoveredOnBailout(a, true);
    140    return a.length;
    141 }
    142 
    143 function array2ContentBail2(i) {
    144    var a = [ i, i ];
    145    assertEq(a[0], i);
    146    assertEq(a[1], i);
    147    resumeHere(i);
    148    assertRecoveredOnBailout(a, true);
    149    return a.length;
    150 }
    151 
    152 // Check bailouts during the initialization.
    153 function arrayInitBail0(i) {
    154    var a = [ resumeHere(i), i ];
    155    assertRecoveredOnBailout(a, true);
    156    return a.length;
    157 }
    158 
    159 function arrayInitBail1(i) {
    160    var a = [ i, resumeHere(i) ];
    161    assertRecoveredOnBailout(a, true);
    162    return a.length;
    163 }
    164 
    165 // Check recovery of large arrays.
    166 function arrayLarge0(i) {
    167    var a = new Array(10000000);
    168    resumeHere(); bailout(); // always resume here.
    169    // IsArrayEscaped prevent us from escaping Arrays with too many elements.
    170    assertRecoveredOnBailout(a, false);
    171    return a.length;
    172 }
    173 
    174 function arrayLarge1(i) {
    175    var a = new Array(10000000);
    176    a[0] = i;
    177    assertEq(a[0], i);
    178    // IsArrayEscaped prevent us from escaping Arrays with too many elements.
    179    assertRecoveredOnBailout(a, false);
    180    return a.length;
    181 }
    182 
    183 function arrayLarge2(i) {
    184    var a = new Array(10000000);
    185    a[0] = i;
    186    a[100] = i;
    187    assertEq(a[0], i);
    188    assertEq(a[100], i);
    189    // IsArrayEscaped prevent us from escaping Arrays with too many elements.
    190    assertRecoveredOnBailout(a, false);
    191    return a.length;
    192 }
    193 
    194 // Check escape analysis in case of branches.
    195 function arrayCond(i) {
    196    var a = [i,0,i];
    197    if (i % 2 == 1)
    198        a[1] = i;
    199    assertEq(a[0], i);
    200    assertEq(a[1], (i % 2) * i);
    201    assertEq(a[2], i);
    202    assertRecoveredOnBailout(a, true);
    203    return a.length;
    204 }
    205 
    206 // Check escape analysis in case of holes.
    207 function arrayHole0(i) {
    208    var a = [i,,i];
    209    if (i != 99)
    210        a[1] = i;
    211    assertEq(a[0], i);
    212    assertEq(a[1], i != 99 ? i : undefined);
    213    assertEq(a[2], i);
    214    // need to check for holes.
    215    assertRecoveredOnBailout(a, false);
    216    return a.length;
    217 }
    218 
    219 // Same test as the previous one, but the Array.prototype is changed to reutn
    220 // "100" when we request for the element "1".
    221 function arrayHole1(i) {
    222    var a = [i,,i];
    223    if (i != 99)
    224        a[1] = i;
    225    assertEq(a[0], i);
    226    assertEq(a[1], i != 99 ? i : 100);
    227    assertEq(a[2], i);
    228    // need to check for holes.
    229    assertRecoveredOnBailout(a, false);
    230    return a.length;
    231 }
    232 
    233 // Check that we correctly allocate the array after taking the recover path.
    234 var uceFault_arrayAlloc0 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arrayAlloc0'));
    235 function arrayAlloc0(i) {
    236    var a = new Array(10);
    237    if (uceFault_arrayAlloc0(i) || uceFault_arrayAlloc0(i)) {
    238        return a.length;
    239    }
    240    assertRecoveredOnBailout(a, true);
    241    return 0;
    242 }
    243 
    244 var uceFault_arrayAlloc1 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arrayAlloc1'));
    245 function arrayAlloc1(i) {
    246    var a = new Array(10);
    247    if (uceFault_arrayAlloc1(i) || uceFault_arrayAlloc1(i)) {
    248        a[0] = i;
    249        a[1] = i;
    250        assertEq(a[0], i);
    251        assertEq(a[1], i);
    252        assertEq(a[2], undefined);
    253        return a.length;
    254    }
    255    assertRecoveredOnBailout(a, true);
    256    return 0;
    257 }
    258 
    259 var uceFault_arrayAlloc2 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arrayAlloc2'));
    260 function arrayAlloc2(i) {
    261    var a = new Array(10);
    262    if (uceFault_arrayAlloc2(i) || uceFault_arrayAlloc2(i)) {
    263        a[4096] = i;
    264        assertEq(a[0], undefined);
    265        assertEq(a[4096], i);
    266        return a.length;
    267    }
    268    assertRecoveredOnBailout(a, true);
    269    return 0;
    270 }
    271 
    272 function build(l) { var arr = []; for (var i = 0; i < l; i++) arr.push(i); return arr }
    273 var uceFault_arrayAlloc3 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arrayAlloc3'));
    274 function arrayAlloc3(i) {
    275    var a = [0,1,2,3,4,5,6,7,8];
    276    if (uceFault_arrayAlloc3(i) || uceFault_arrayAlloc3(i)) {
    277        assertEq(a[0], 0);
    278        assertEq(a[3], 3);
    279        return a.length;
    280    }
    281    assertRecoveredOnBailout(a, true);
    282    return 0;
    283 };
    284 
    285 // Prevent compilation of the top-level
    286 eval(`(${resumeHere})`);
    287 
    288 for (var i = 0; i < 100; i++) {
    289    array0Length(i);
    290    array0LengthBail(i);
    291    array1Length(i);
    292    array1LengthBail(i);
    293    array2Length(i);
    294    array2LengthBail(i);
    295    array1Content(i);
    296    array1ContentBail0(i);
    297    array1ContentBail1(i);
    298    array2Content(i);
    299    array2ContentBail0(i);
    300    array2ContentBail1(i);
    301    array2ContentBail2(i);
    302    arrayInitBail0(i);
    303    arrayInitBail1(i);
    304    arrayLarge0(i);
    305    arrayLarge1(i);
    306    arrayLarge2(i);
    307    //arrayCond(i); See bug 1697691.
    308    arrayHole0(i);
    309    arrayAlloc0(i);
    310    arrayAlloc1(i);
    311    arrayAlloc2(i);
    312    arrayAlloc3(i);
    313 }
    314 
    315 for (var i = 0; i < 100; i++) {
    316    arrayWithGCInit0(i);
    317    arrayWithGCInit1(i);
    318    arrayWithGCInit2(i);
    319 }
    320 
    321 // If arr[1] is not defined, then we fallback on the prototype which instead of
    322 // returning undefined, returns "0".
    323 Object.defineProperty(Array.prototype, 1, {
    324  value: 100,
    325  configurable: true,
    326  enumerable: true,
    327  writable: true
    328 });
    329 
    330 for (var i = 0; i < 100; i++) {
    331    arrayHole1(i);
    332 }