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();