diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit-test/tests/self-test | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/jit-test/tests/self-test')
18 files changed, 411 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/self-test/assertDeepEq.js b/js/src/jit-test/tests/self-test/assertDeepEq.js new file mode 100644 index 0000000000..3619a3fcc6 --- /dev/null +++ b/js/src/jit-test/tests/self-test/assertDeepEq.js @@ -0,0 +1,112 @@ +// Tests for the assertEqual function in jit-test/lib/asserts.js + +load(libdir + "asserts.js"); + +function assertNotDeepEq(a, b, options) { + assertThrowsInstanceOf(() => assertDeepEq(a, b, options), Error); +} + +// primitives +assertDeepEq(undefined, undefined); +assertDeepEq("1", "1"); +assertNotDeepEq(1, "1"); +assertNotDeepEq(undefined, null); +assertNotDeepEq({}, null); + +// symbols +assertDeepEq(Symbol(), Symbol()); +assertNotDeepEq(Symbol(), Symbol("")); +assertDeepEq(Symbol("tweedledum"), Symbol("tweedledum")); +assertNotDeepEq(Symbol("tweedledum"), Symbol("alice")); +assertNotDeepEq(Symbol("what-its-called"), Symbol.for("what-its-called")); +assertNotDeepEq(Symbol.iterator, Symbol.for("Symbol.iterator")); +assertDeepEq([Symbol(), Symbol(), Symbol()], + [Symbol(), Symbol(), Symbol()]); +var sym = Symbol(); +assertDeepEq([sym, sym], [sym, sym]); +assertNotDeepEq([sym, sym], [Symbol(), Symbol()]); +assertNotDeepEq([sym, sym], [Symbol(), sym]); +var obj1 = {}, obj2 = {}; +obj1[Symbol("x")] = "y"; +obj2[Symbol("x")] = "y"; +assertDeepEq(obj1, obj2); + +// objects +assertDeepEq({}, {}); +assertDeepEq({one: 1, two: 2}, {one: 1, two: 2}); +assertNotDeepEq(Object.freeze({}), {}); +assertDeepEq(Object.create(null), Object.create(null)); +assertNotDeepEq(Object.create(null, {a: {configurable: false, value: 3}}), + Object.create(null, {a: {configurable: true, value: 3}})); +assertNotDeepEq({one: 1}, {one: 1, two: 2}); +assertNotDeepEq({yes: true}, {oui: true}); +assertNotDeepEq({zero: 0}, {zero: "0"}); + +// test the comment +var x = {}, y = {}, ax = [x]; +assertDeepEq([ax, x], [ax, y]); // passes (bogusly) +assertNotDeepEq([ax, x], [ax, y], {strictEquivalence: true}); +assertDeepEq([x, ax], [y, ax]); // passes (bogusly) +assertNotDeepEq([x, ax], [y, ax], {strictEquivalence: true}); + +// object identity +assertNotDeepEq([x, y], [x, x]); +assertDeepEq([x, y], [x, y]); +assertDeepEq([y, x], [x, y]); + +// proto chain +var x = {}; +assertDeepEq(Object.create(x), Object.create(x)); +assertDeepEq(Object.create({}), Object.create({})); // equivalent but not identical proto objects + +// arrays +assertDeepEq([], []); +assertNotDeepEq([], [1]); +assertDeepEq([1], [1]); +assertNotDeepEq([0], [1]); +assertDeepEq([1, 2, 3], [1, 2, 3]); +assertNotDeepEq([1, , 3], [1, undefined, 3]); +var p = [], q = []; +p.prop = 1; +assertNotDeepEq(p, q); +assertNotDeepEq(q, p); +q.prop = 1; +assertDeepEq(q, p); + +// functions +assertNotDeepEq(() => 1, () => 2); +assertNotDeepEq((...x) => 1, x => 1); +assertNotDeepEq(function f(){}, function g(){}); +// Avoid setting name property. +var [f1, f2] = [function () {}, function () {}]; +assertDeepEq(f1, f1); +assertDeepEq(f1, f2); // same text, close enough +f1.prop = 1; +assertNotDeepEq(f1, f2); +f2.prop = 1; +assertDeepEq(f1, f2); + +// recursion +var a = [], b = []; +a[0] = a; +b[0] = b; +assertDeepEq(a, b); +a[0] = b; +assertNotDeepEq(a, b); // [#1=[#1#]] is not structurally equivalent to #1=[[#1#]] +b[0] = a; +assertDeepEq(a, b); +b[0] = [a]; // a[0] === b, b[0] === c, c[0] === a +assertDeepEq(a, b); + +// objects that merge +var x = {}; +assertDeepEq({x: x}, {x: x}); +var y = [x]; +assertDeepEq([y], [y]); + +// cross-compartment +var g1 = newGlobal({newCompartment: true}), g2 = newGlobal({newCompartment: true}); +assertDeepEq(g1, g2); +assertDeepEq(g1, g2, {strictEquivalence: true}); +Object.preventExtensions(g2.Math.abs); // make some miniscule change +assertNotDeepEq(g1, g2); diff --git a/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js b/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js new file mode 100644 index 0000000000..47f538b5f3 --- /dev/null +++ b/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js @@ -0,0 +1,12 @@ +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +function f () { + var o = {}; + var x = assertRecoveredOnBailout(o, true); + bailout(); + return x; +} + +f(); +f(); diff --git a/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js b/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js new file mode 100644 index 0000000000..68f07c92ab --- /dev/null +++ b/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js @@ -0,0 +1,36 @@ +// |jit-test| crash; skip-if: getBuildConfiguration()['tsan'] || getBuildConfiguration()['wasi']; --ion-warmup-threshold=50 +setJitCompilerOption("offthread-compilation.enable", 0); + +var opts = getJitCompilerOptions(); +if (!opts['ion.enable'] || !opts['baseline.enable'] || + opts["ion.forceinlineCaches"] || opts["ion.check-range-analysis"]) +{ + crash("Cannot test assertRecoveredOnBailout"); +} + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +function g() { + return inIon(); +} + +// Wait until IonMonkey compilation finished. +while(!(res = g())); + +// Check that we entered Ion succesfully. +if (res !== true) + crash("Cannot enter IonMonkey"); + +// Test that assertRecoveredOnBailout fails as expected. +function f () { + var o = {}; + assertRecoveredOnBailout(o, false); + return inIon(); +} + +// Wait until IonMonkey compilation finished. +while(!(res = f())); + +// Ensure that we entered Ion. +assertEq(res, true); diff --git a/js/src/jit-test/tests/self-test/baselineCompile-Bug1444894.js b/js/src/jit-test/tests/self-test/baselineCompile-Bug1444894.js new file mode 100644 index 0000000000..768d4b655c --- /dev/null +++ b/js/src/jit-test/tests/self-test/baselineCompile-Bug1444894.js @@ -0,0 +1,5 @@ + +if (typeof baselineCompile == "function") { + gc(); + newGlobal().baselineCompile(); +} diff --git a/js/src/jit-test/tests/self-test/baselineCompile.js b/js/src/jit-test/tests/self-test/baselineCompile.js new file mode 100644 index 0000000000..18da9dbf12 --- /dev/null +++ b/js/src/jit-test/tests/self-test/baselineCompile.js @@ -0,0 +1,21 @@ +// |jit-test| test-also=--fuzzing-safe +// Check that the help text for baselineCompile() is accurate. + +if (typeof inJit == "function" && typeof baselineCompile == "function") { + if (!inJit()) { + + var res = baselineCompile(); // compile the current script + + assertEq(inJit(), false, + "We have compiled this script to baseline jitcode, but shouldn't " + + "be running it yet, according to the help text for baselineCompile() " + + "in TestingFunctions.cpp. If you fail this assertion, nice work, and " + + "please update the help text!"); + + for (var i=0; i<1; i++) {} // exact boilerplate suggested by the help text + + assertEq(typeof res != "string" ? inJit() : true, true, + "help text in TestingFunctions.cpp claims the above loop causes " + + "the interpreter to start running the new baseline jitcode"); + } +} diff --git a/js/src/jit-test/tests/self-test/cacheEntry.js b/js/src/jit-test/tests/self-test/cacheEntry.js new file mode 100644 index 0000000000..d60671b602 --- /dev/null +++ b/js/src/jit-test/tests/self-test/cacheEntry.js @@ -0,0 +1,23 @@ +// These tests are checking that CacheEntry_getBytecode properly set an error +// when there is no bytecode registered. +var caught = 0; +var code = cacheEntry(""); +try { + offThreadDecodeStencil(code); +} +catch (e) { + // offThreadDecodeStencil does not work with the --no-thread command line option. + assertEq(e.message.includes("CacheEntry") || e.message.includes("offThreadDecodeStencil"), true); + caught++; +} + +code = cacheEntry(""); +try { + evaluate(code, {loadBytecode: true}); +} +catch (e) { + assertEq(e.message.includes("CacheEntry"), true); + caught++; +} + +assertEq(caught, 2); diff --git a/js/src/jit-test/tests/self-test/delazification-mode-00.js b/js/src/jit-test/tests/self-test/delazification-mode-00.js new file mode 100644 index 0000000000..036065c688 --- /dev/null +++ b/js/src/jit-test/tests/self-test/delazification-mode-00.js @@ -0,0 +1,19 @@ +//|jit-test| skip-if: isLcovEnabled() + +let source = ` + function foo() { + return "foo"; + } + + // Wait is skipped as the source is not registered in the stencil cache. + waitForStencilCache(foo); + assertEq(isInStencilCache(foo), false); +`; + +const options = { + fileName: "inner-00.js", + lineNumber: 1, + eagerDelazificationStrategy: "OnDemandOnly", + newContext: true, +}; +evaluate(source, options); diff --git a/js/src/jit-test/tests/self-test/delazification-mode-01.js b/js/src/jit-test/tests/self-test/delazification-mode-01.js new file mode 100644 index 0000000000..ce1f9ee89b --- /dev/null +++ b/js/src/jit-test/tests/self-test/delazification-mode-01.js @@ -0,0 +1,24 @@ +//|jit-test| skip-if: isLcovEnabled() || helperThreadCount() === 0 + +// GCs might trash the stencil cache. Prevent us from scheduling too many GCs. +if ('gczeal' in this) { + gczeal(0); +} + +let source = ` + function foo() { + return "foo"; + } + + waitForStencilCache(foo); + // false would be expected if threads are disabled. + assertEq(isInStencilCache(foo), true); +`; + +const options = { + fileName: "inner-01.js", + lineNumber: 1, + eagerDelazificationStrategy: "CheckConcurrentWithOnDemand", + newContext: true, +}; +evaluate(source, options); diff --git a/js/src/jit-test/tests/self-test/delazification-mode-02.js b/js/src/jit-test/tests/self-test/delazification-mode-02.js new file mode 100644 index 0000000000..ea16ee7027 --- /dev/null +++ b/js/src/jit-test/tests/self-test/delazification-mode-02.js @@ -0,0 +1,24 @@ +//|jit-test| skip-if: isLcovEnabled() || helperThreadCount() === 0 + +// GCs might trash the stencil cache. Prevent us from scheduling too many GCs. +if ('gczeal' in this) { + gczeal(0); +} + +let source = ` + function foo() { + return "foo"; + } + + waitForStencilCache(foo); + // false would be expected if threads are disabled. + assertEq(isInStencilCache(foo), true); +`; + +const options = { + fileName: "inner-02.js", + lineNumber: 1, + eagerDelazificationStrategy: "ConcurrentDepthFirst", + newContext: true, +}; +evaluate(source, options); diff --git a/js/src/jit-test/tests/self-test/delazification-mode-03.js b/js/src/jit-test/tests/self-test/delazification-mode-03.js new file mode 100644 index 0000000000..53f158765e --- /dev/null +++ b/js/src/jit-test/tests/self-test/delazification-mode-03.js @@ -0,0 +1,17 @@ +let source = ` + function foo() { + return "foo"; + } + + // Wait is skipped as the source is not registered in the stencil cache. + waitForStencilCache(foo); + assertEq(isInStencilCache(foo), false); +`; + +const options = { + fileName: "inner-03.js", + lineNumber: 1, + eagerDelazificationStrategy: "ParseEverythingEagerly", + newContext: true, +}; +evaluate(source, options); diff --git a/js/src/jit-test/tests/self-test/getBacktrace-bug1138195.js b/js/src/jit-test/tests/self-test/getBacktrace-bug1138195.js new file mode 100644 index 0000000000..092cdd936f --- /dev/null +++ b/js/src/jit-test/tests/self-test/getBacktrace-bug1138195.js @@ -0,0 +1,8 @@ + +function f(x) { + for (var i = 0; i < 40; ++i) { + var stack = getBacktrace({args: true}); + (function() { g = x;}); + } +} +f(1); diff --git a/js/src/jit-test/tests/self-test/inIon.js b/js/src/jit-test/tests/self-test/inIon.js new file mode 100644 index 0000000000..e14a0bc4a9 --- /dev/null +++ b/js/src/jit-test/tests/self-test/inIon.js @@ -0,0 +1,20 @@ +// Test that inIon eventually becomes truthy. +// This code should never timeout. + +function callInIon() { + return inIon(); +}; + +function test() { + // Test with OSR. + while(!inIon()); + + // Test with inlining. + while(!callInIon()); + + // Test with zealous gc preventing compilation. + while(!inIon()) gc(this, 'shrinking'); +}; + +test(); + diff --git a/js/src/jit-test/tests/self-test/inJit.js b/js/src/jit-test/tests/self-test/inJit.js new file mode 100644 index 0000000000..dd218b5160 --- /dev/null +++ b/js/src/jit-test/tests/self-test/inJit.js @@ -0,0 +1,20 @@ +// Test that inJit eventually becomes truthy. +// This code should never timeout. + +function callInJit() { + return inJit(); +}; + +function test() { + // Test with OSR. + while(!inJit()); + + // Test with inlining. + while(!callInJit()); + + // Test with zealous gc preventing compilation. + while(!inJit()) gc(); +}; + +test(); + diff --git a/js/src/jit-test/tests/self-test/isRelazifiableFunction-0.js b/js/src/jit-test/tests/self-test/isRelazifiableFunction-0.js new file mode 100644 index 0000000000..a75246668d --- /dev/null +++ b/js/src/jit-test/tests/self-test/isRelazifiableFunction-0.js @@ -0,0 +1,3 @@ +// |jit-test| error: Error: The first argument should be a function. + +isRelazifiableFunction(new Array()); diff --git a/js/src/jit-test/tests/self-test/notInIon.js b/js/src/jit-test/tests/self-test/notInIon.js new file mode 100644 index 0000000000..f3da1836e0 --- /dev/null +++ b/js/src/jit-test/tests/self-test/notInIon.js @@ -0,0 +1,3 @@ +// |jit-test| --no-ion + +assertEq(inIon(), "Ion is disabled."); diff --git a/js/src/jit-test/tests/self-test/notInJit.js b/js/src/jit-test/tests/self-test/notInJit.js new file mode 100644 index 0000000000..4bb3469e40 --- /dev/null +++ b/js/src/jit-test/tests/self-test/notInJit.js @@ -0,0 +1,4 @@ +// |jit-test| --no-baseline + +assertEq(inJit(), "Baseline is disabled."); +assertEq(inIon(), "Ion is disabled."); diff --git a/js/src/jit-test/tests/self-test/oom-test-bug1497906.js b/js/src/jit-test/tests/self-test/oom-test-bug1497906.js new file mode 100644 index 0000000000..da6a0a959d --- /dev/null +++ b/js/src/jit-test/tests/self-test/oom-test-bug1497906.js @@ -0,0 +1,18 @@ +// |jit-test| skip-if: !('oomTest' in this && 'stackTest' in this) || helperThreadCount() === 0 + +// Check that oomTest throws an exception on worker threads. + +setSharedObject(0); +evalInWorker(` + try { + oomTest(crash); + } catch (e) { + if (e.toString().includes("main thread")) { + setSharedObject(1); + } + } +`); + +while (getSharedObject() != 1) { + // poor-man wait condition. +} diff --git a/js/src/jit-test/tests/self-test/readlineBuf.js b/js/src/jit-test/tests/self-test/readlineBuf.js new file mode 100644 index 0000000000..1430c4ae49 --- /dev/null +++ b/js/src/jit-test/tests/self-test/readlineBuf.js @@ -0,0 +1,42 @@ +load(libdir + "asserts.js"); + +assertThrowsInstanceOf(function () { readlineBuf() }, Error); + +var testBuffers = [ + "foo\nbar\nbaz\n", + "foo\nbar\nbaz", + "foo\n\nbar\nbaz", + "f", + "\n", + "\nf", + "", + "Ää\n\u{10ffff}", +]; + +var expected = [ + [ "foo", "bar", "baz" ], + [ "foo", "bar", "baz" ], + [ "foo", "", "bar", "baz" ], + [ "f" ], + [ "" ], + [ "", "f" ], + [], + ["Ää", "\u{10ffff}"], +]; + +for (var [idx, testValue] of testBuffers.entries()) { + readlineBuf(testValue); + var result = []; + + while ((line = readlineBuf()) != null) { + result.push(line); + } + + assertDeepEq(result, expected[idx]); +} + +readlineBuf(testBuffers[0]); +readlineBuf(); +readlineBuf(); +readlineBuf(testBuffers[3]); +assertEq(readlineBuf(), expected[3][0]); |