summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/gc/deduplicateTenuringStrings.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/gc/deduplicateTenuringStrings.js')
-rw-r--r--js/src/jit-test/tests/gc/deduplicateTenuringStrings.js205
1 files changed, 205 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/gc/deduplicateTenuringStrings.js b/js/src/jit-test/tests/gc/deduplicateTenuringStrings.js
new file mode 100644
index 0000000000..1b8259cc15
--- /dev/null
+++ b/js/src/jit-test/tests/gc/deduplicateTenuringStrings.js
@@ -0,0 +1,205 @@
+// |jit-test| skip-if: !('stringRepresentation' in this)
+
+// This is to test the correctness of the string deduplication algorithm during
+// the tenuring phase. Same strings below refer to the same character encoding
+// (either latin1 or twobyte) and the same characters.
+
+// Tests:
+// 1. Same strings with same flags and zones should be deduplicated for
+// all linear strings except atoms and external strings.
+// 2. Same strings, but from different zones should not be deduplicated.
+// 3. Same strings, but with different flags should not be deduplicated.
+
+// We require predictable GC timing to make sure the correct
+// strings are tenured together.
+gczeal(0);
+
+var helperCode = `
+function makeInlineStr(isLatin1) {
+ var s = isLatin1 ? "123456789*1" : "一二三";
+ return s + s;
+}
+
+// Generic linear strings are non-atom, non-extensible, non-inline
+// linear strings.
+// Generic linear strings can only have latin1 characters.
+function makeGenericLinearStr() {
+ return notes(() => 1);
+}
+
+function makeRopeStr(isLatin1) {
+ var left = isLatin1 ? "1" : "一";
+ var right = isLatin1 ? "123456789*123456789*123456" :
+ "一二三四五六七八九*一二三四五六七八";
+ return left + right;
+}
+
+function makeExtensibleStr(isLatin1) {
+ var r = makeRopeStr(isLatin1);
+ ensureLinearString(r);
+ return r;
+}
+
+function makeExtensibleStrFrom(str) {
+ var left = str.substr(0, str.length/2);
+ var right = str.substr(str.length/2, str.length);
+ var ropeStr = left + right;
+ return ensureLinearString(ropeStr);
+}
+
+function makeDependentStr(isLatin1) {
+ var e = makeExtensibleStr(isLatin1);
+ var r1 = e + "!";
+ var r2 = e + r1;
+ ensureLinearString(r2);
+ return r1;
+}
+
+function makeDependentStrFrom(str) {
+ var e = makeExtensibleStrFrom(str);
+ var r1 = e.substr(0, e.length/2) + e.substr(e.length/2, e.length);
+ var r2 = e + r1;
+ ensureLinearString(r2);
+ return r1;
+}
+
+function makeExternalStr(isLatin1) {
+ return isLatin1 ? newString("12345678", {external: true}) :
+ newString("一二三", {external: true});
+}
+
+function tenureStringsWithSameChars(str1, str2, isDeduplicatable) {
+ minorgc();
+ assertEq(stringRepresentation(str1) == stringRepresentation(str2),
+ isDeduplicatable);
+}
+
+function assertDiffStrRepAfterMinorGC(g1, g2) {
+ minorgc();
+ g1.eval(\`strRep = stringRepresentation(str);\`);
+ g2.eval(\`strRep = stringRepresentation(str);\`);
+ assertEq(g1.strRep == g2.strRep, false);
+}
+`;
+
+eval(helperCode);
+
+// test1:
+// Same strings with same flags and zones should be deduplicated for all linear
+// strings except atoms, external strings.
+function test1(isLatin1) {
+ const isDeduplicatable = true;
+
+ // Deduplicatable:
+ // --> Inline Strings
+ var str1 = makeInlineStr(isLatin1);
+ var str2 = makeInlineStr(isLatin1);
+ tenureStringsWithSameChars(str1, str2, isDeduplicatable);
+
+ // --> Extensible Strings
+ str1 = makeExtensibleStr(isLatin1);
+ str2 = makeExtensibleStr(isLatin1);
+ tenureStringsWithSameChars(str1, str2, isDeduplicatable);
+
+ // --> Dependent Strings
+ str1 = makeDependentStr(isLatin1);
+ str2 = makeDependentStr(isLatin1);
+ tenureStringsWithSameChars(str1, str2, isDeduplicatable);
+
+ // --> Generic Linear Strings
+ if (isLatin1) {
+ var str1 = makeGenericLinearStr();
+ var str2 = makeGenericLinearStr();
+ tenureStringsWithSameChars(str1, str2, isDeduplicatable);
+ }
+
+ // Non-Deduplicatable:
+ // --> Rope Strings
+ str1 = makeRopeStr(isLatin1);
+ str2 = makeRopeStr(isLatin1);
+ tenureStringsWithSameChars(str1, str2, !isDeduplicatable);
+
+ // --> Atom strings are deduplicated already but not through string
+ // deduplication during tenuring.
+
+ // --> External strings are not nursery allocated.
+}
+
+// test2:
+// Same strings, but from different zones should not be deduplicated.
+function test2(isLatin1) {
+ var g1 = newGlobal({ newCompartment: true });
+ var g2 = newGlobal({ newCompartment: true });
+
+ g1.eval(helperCode);
+ g2.eval(helperCode);
+
+ // --> Inline Strings
+ g1.eval(`var str = makeInlineStr(${isLatin1}); `);
+ g2.eval(`var str = makeInlineStr(${isLatin1}); `);
+ assertDiffStrRepAfterMinorGC(g1, g2);
+
+ // --> Extensible Strings
+ g1.eval(`str = makeExtensibleStr(${isLatin1}); `);
+ g2.eval(`str = makeExtensibleStr(${isLatin1}); `);
+ assertDiffStrRepAfterMinorGC(g1, g2);
+
+ // --> Dependent Strings
+ g1.eval(`str = makeDependentStr(${isLatin1}); `);
+ g2.eval(`str = makeDependentStr(${isLatin1}); `);
+ assertDiffStrRepAfterMinorGC(g1, g2);
+
+ // --> Generic Linear Strings
+ if (isLatin1) {
+ g1.eval(`str = makeGenericLinearStr();`);
+ g2.eval(`str = makeGenericLinearStr();`);
+ assertDiffStrRepAfterMinorGC(g1, g2);
+ }
+}
+
+// test3:
+// Same strings, but with different flags should not be deduplicated.
+function test3(isLatin1) {
+ const isDeduplicatable = true;
+
+ // --> Dependent String and Extensible String
+ var dependentStr = makeDependentStr(isLatin1);
+ var extensibleStr = makeExtensibleStrFrom(dependentStr);
+ tenureStringsWithSameChars(dependentStr, extensibleStr, !isDeduplicatable);
+
+ if (isLatin1) {
+ // --> Generic Linear String and Extensible String
+ var genericLinearStr = makeGenericLinearStr();
+ var extensibleStr = makeExtensibleStrFrom(genericLinearStr);
+ tenureStringsWithSameChars(
+ genericLinearStr,
+ extensibleStr,
+ !isDeduplicatable
+ );
+
+ // --> Generic Linear String and Dependent String
+ var dependentStr = makeDependentStrFrom(genericLinearStr);
+ tenureStringsWithSameChars(
+ dependentStr,
+ genericLinearStr,
+ !isDeduplicatable
+ );
+ }
+
+ // --> Inline strings are too short to have the same chars as the extensible
+ // strings, generic linear strings and dependent strings
+}
+
+function runTests() {
+ var charEncoding = { TWOBYTE: 0, LATIN1: 1 };
+
+ test1(charEncoding.TWOBYTE);
+ test2(charEncoding.TWOBYTE);
+ test3(charEncoding.TWOBYTE);
+
+ test1(charEncoding.LATIN1);
+ test2(charEncoding.LATIN1);
+ test3(charEncoding.LATIN1);
+}
+
+runTests();