tor-browser

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

deduplicateTenuringStrings.js (6159B)


      1 // |jit-test| skip-if: !('stringRepresentation' in this); --setpref=objectfuse_for_global=false
      2 
      3 // Don't use object fuses for this test because atomizing global constants
      4 // affects what we're testing.
      5 
      6 // This is to test the correctness of the string deduplication algorithm during
      7 // the tenuring phase. Same strings below refer to the same character encoding
      8 // (either latin1 or twobyte) and the same characters.
      9 
     10 // Tests:
     11 // 1. Same strings with same flags and zones should be deduplicated for
     12 // all linear strings except atoms and external strings.
     13 // 2. Same strings, but from different zones should not be deduplicated.
     14 // 3. Same strings, but with different flags should not be deduplicated.
     15 
     16 // We require predictable GC timing to make sure the correct
     17 // strings are tenured together.
     18 gczeal(0);
     19 gcparam('semispaceNurseryEnabled', 0);
     20 
     21 var helperCode = `
     22 function makeInlineStr(isLatin1) {
     23  var s = isLatin1 ? "123456789*1" : "一二三";
     24  return s + s;
     25 }
     26 
     27 // Generic linear strings are non-atom, non-extensible, non-inline
     28 // linear strings.
     29 // Generic linear strings can only have latin1 characters.
     30 function makeGenericLinearStr() {
     31  return notes(() => 1);
     32 }
     33 
     34 function makeRopeStr(isLatin1) {
     35  var left = isLatin1 ? "1" : "一";
     36  var right = isLatin1 ? "123456789*123456789*123456" :
     37    					   "一二三四五六七八九*一二三四五六七八";
     38  return left + right;
     39 }
     40 
     41 function makeExtensibleStr(isLatin1) {
     42  var r = makeRopeStr(isLatin1);
     43  ensureLinearString(r);
     44  return r;
     45 }
     46 
     47 function makeExtensibleStrFrom(str) {
     48  var left = str.substr(0, str.length/2);
     49  var right = str.substr(str.length/2, str.length);
     50  var ropeStr = left + right;
     51  return ensureLinearString(ropeStr);
     52 }
     53 
     54 function makeDependentStr(isLatin1) {
     55  var e = makeExtensibleStr(isLatin1);
     56  var r1 = e + "!";
     57  var r2 = e + r1;
     58  ensureLinearString(r2);
     59  return r1;
     60 }
     61 
     62 function makeDependentStrFrom(str) {
     63  var e = makeExtensibleStrFrom(str);
     64  var r1 = e.substr(0, e.length/2) + e.substr(e.length/2, e.length);
     65  var r2 = e + r1;
     66  ensureLinearString(r2);
     67  return r1;
     68 }
     69 
     70 function makeExternalStr(isLatin1) {
     71  return isLatin1 ? newString("12345678", {external: true}) :
     72                    newString("一二三", {external: true});
     73 }
     74 
     75 function tenureStringsWithSameChars(str1, str2, isDeduplicatable) {
     76  minorgc();
     77  assertEq(stringRepresentation(str1) == stringRepresentation(str2),
     78    isDeduplicatable);
     79 }
     80 
     81 function assertDiffStrRepAfterMinorGC(g1, g2) {
     82  minorgc();
     83  g1.eval(\`strRep = stringRepresentation(str);\`);
     84  g2.eval(\`strRep = stringRepresentation(str);\`);
     85  assertEq(g1.strRep == g2.strRep, false);
     86 }
     87 `;
     88 
     89 eval(helperCode);
     90 
     91 // test1:
     92 // Same strings with same flags and zones should be deduplicated for all linear
     93 // strings except atoms, external strings.
     94 function test1(isLatin1) {
     95  const isDeduplicatable = true;
     96 
     97  // Deduplicatable:
     98  // --> Inline Strings
     99  var str1 = makeInlineStr(isLatin1);
    100  var str2 = makeInlineStr(isLatin1);
    101  tenureStringsWithSameChars(str1, str2, isDeduplicatable);
    102 
    103  // --> Extensible Strings
    104  str1 = makeExtensibleStr(isLatin1);
    105  str2 = makeExtensibleStr(isLatin1);
    106  tenureStringsWithSameChars(str1, str2, isDeduplicatable);
    107 
    108  // --> Dependent Strings
    109  str1 = makeDependentStr(isLatin1);
    110  str2 = makeDependentStr(isLatin1);
    111  tenureStringsWithSameChars(str1, str2, isDeduplicatable);
    112 
    113  // --> Generic Linear Strings
    114  if (isLatin1) {
    115    var str1 = makeGenericLinearStr();
    116    var str2 = makeGenericLinearStr();
    117    tenureStringsWithSameChars(str1, str2, isDeduplicatable);
    118  }
    119 
    120  // Non-Deduplicatable:
    121  // --> Rope Strings
    122  str1 = makeRopeStr(isLatin1);
    123  str2 = makeRopeStr(isLatin1);
    124  tenureStringsWithSameChars(str1, str2, !isDeduplicatable);
    125 
    126  // --> Atom strings are deduplicated already but not through string
    127  // deduplication during tenuring.
    128 
    129  // --> External strings are not nursery allocated.
    130 }
    131 
    132 // test2:
    133 // Same strings, but from different zones should not be deduplicated.
    134 function test2(isLatin1) {
    135  var g1 = newGlobal({ newCompartment: true });
    136  var g2 = newGlobal({ newCompartment: true });
    137 
    138  g1.eval(helperCode);
    139  g2.eval(helperCode);
    140 
    141  // --> Inline Strings
    142  g1.eval(`var str = makeInlineStr(${isLatin1}); `);
    143  g2.eval(`var str = makeInlineStr(${isLatin1}); `);
    144  assertDiffStrRepAfterMinorGC(g1, g2);
    145 
    146  // --> Extensible Strings
    147  g1.eval(`str = makeExtensibleStr(${isLatin1}); `);
    148  g2.eval(`str = makeExtensibleStr(${isLatin1}); `);
    149  assertDiffStrRepAfterMinorGC(g1, g2);
    150 
    151  // --> Dependent Strings
    152  g1.eval(`str = makeDependentStr(${isLatin1}); `);
    153  g2.eval(`str = makeDependentStr(${isLatin1}); `);
    154  assertDiffStrRepAfterMinorGC(g1, g2);
    155 
    156  // --> Generic Linear Strings
    157  if (isLatin1) {
    158    g1.eval(`str = makeGenericLinearStr();`);
    159    g2.eval(`str = makeGenericLinearStr();`);
    160    assertDiffStrRepAfterMinorGC(g1, g2);
    161  }
    162 }
    163 
    164 // test3:
    165 // Same strings, but with different flags should not be deduplicated.
    166 function test3(isLatin1) {
    167  const isDeduplicatable = true;
    168 
    169  // --> Dependent String and Extensible String
    170  var dependentStr = makeDependentStr(isLatin1);
    171  var extensibleStr = makeExtensibleStrFrom(dependentStr);
    172  tenureStringsWithSameChars(dependentStr, extensibleStr, !isDeduplicatable);
    173 
    174  if (isLatin1) {
    175    // --> Generic Linear String and Extensible String
    176    var genericLinearStr = makeGenericLinearStr();
    177    var extensibleStr = makeExtensibleStrFrom(genericLinearStr);
    178    tenureStringsWithSameChars(
    179      genericLinearStr,
    180      extensibleStr,
    181      !isDeduplicatable
    182    );
    183 
    184    // --> Generic Linear String and Dependent String
    185    var dependentStr = makeDependentStrFrom(genericLinearStr);
    186    tenureStringsWithSameChars(
    187      dependentStr,
    188      genericLinearStr,
    189      !isDeduplicatable
    190    );
    191  }
    192 
    193  // --> Inline strings are too short to have the same chars as the extensible
    194  // strings, generic linear strings and dependent strings
    195 }
    196 
    197 function runTests() {
    198  var charEncoding = { TWOBYTE: 0, LATIN1: 1 };
    199 
    200  test1(charEncoding.TWOBYTE);
    201  test2(charEncoding.TWOBYTE);
    202  test3(charEncoding.TWOBYTE);
    203 
    204  test1(charEncoding.LATIN1);
    205  test2(charEncoding.LATIN1);
    206  test3(charEncoding.LATIN1);
    207 }
    208 
    209 runTests();