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/parser/stencil-scope.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/jit-test/tests/parser/stencil-scope.js')
-rw-r--r-- | js/src/jit-test/tests/parser/stencil-scope.js | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/parser/stencil-scope.js b/js/src/jit-test/tests/parser/stencil-scope.js new file mode 100644 index 0000000000..0dc562147a --- /dev/null +++ b/js/src/jit-test/tests/parser/stencil-scope.js @@ -0,0 +1,134 @@ +const optionsFull = { + fileName: "compileToStencil-DATA.js", + lineNumber: 1, + eagerDelazificationStrategy: "ParseEverythingEagerly", +}; + +const optionsLazy = { + fileName: "compileToStencil-DATA.js", + lineNumber: 1, + eagerDelazificationStrategy: "OnDemandOnly", +}; + +const optionsLazyCache = { + fileName: "compileToStencil-DATA.js", + lineNumber: 1, + eagerDelazificationStrategy: "ConcurrentDepthFirst", +}; + +const optionsLazyCache2 = { + fileName: "compileToStencil-DATA.js", + lineNumber: 1, + eagerDelazificationStrategy: "ConcurrentLargeFirst", +}; + +let result = 0; + +function testMainThread(script_str) { + const stencil = compileToStencil(script_str, optionsFull); + result = evalStencil(stencil, optionsFull); + assertEq(result, 1); +} + +function testMainThreadDelazifyAll(script_str) { + if (isLcovEnabled()) { + // Code-coverage implies forceFullParse = true, and as such it cannot be + // used while testing to incrementally delazify. + return; + } + const stencil = compileToStencil(script_str, optionsLazy); + result = evalStencil(stencil, optionsLazy); + assertEq(result, 1); +} + +function testMainThreadCacheAll(script_str) { + if (isLcovEnabled() || helperThreadCount() === 0) { + // Code-coverage implies forceFullParse = true, and as such it cannot be + // used while testing to incrementally delazify. + // Similarly, concurrent delazification requires off-threads processing. + return; + } + const stencil = compileToStencil(script_str, optionsLazyCache); + result = evalStencil(stencil, optionsLazyCache); + assertEq(result, 1); +} + +function testMainThreadCacheAll2(script_str) { + if (isLcovEnabled() || helperThreadCount() === 0) { + // Code-coverage implies forceFullParse = true, and as such it cannot be + // used while testing to incrementally delazify. + // Similarly, concurrent delazification requires off-threads processing. + return; + } + const stencil = compileToStencil(script_str, optionsLazyCache2); + result = evalStencil(stencil, optionsLazyCache2); + assertEq(result, 1); +} + +function testOffThread(script_str) { + const job = offThreadCompileToStencil(script_str, optionsFull); + const stencil = finishOffThreadStencil(job); + result = evalStencil(stencil, optionsFull); + assertEq(result, 1); +} + +// These patches are meant to wrap the inner code given as argument into one +// kind of scope. The freeVars specify one way to retrieve the variable name +// added in this process if any. +const scopeCases = [ + { code: inner => `{ ${inner} }`, freeVars: [] }, + { code: inner => `{ var v = 1; ${inner} }`, freeVars: ["v"] }, + { code: inner => `{ let l = 1; ${inner} }`, freeVars: ["l"] }, + { code: inner => `{ const c = 1; ${inner} }`, freeVars: ["c"] }, + { code: inner => `with ({ p: 1 }) { ${inner} }`, freeVars: ["p"], + inClass: false }, + { code: inner => `(a => { ${inner} })(1)`, freeVars: ["a"] }, + { code: inner => `function fun(a) { ${inner} }; fun(1)`, freeVars: ["a"], + inClass: false}, + { code: inner => `try { ${inner} } catch(unused) { }`, freeVars: [] }, + { code: inner => `try { throw 1; } catch(t) { ${inner} }`, freeVars: ["t"] }, + { code: inner => `{ class C { #m = 1; constructor() { ${inner} }}; new C() }`, + freeVars: ["this.#m"], isClass: true }, +]; + +// This function is used to generate code which mostly exercise the various kind +// of scopes to cover ScopeContext class in CompilationStencil.h +function generateCode(seed) { + let start = inner => ` + ${inner}; + result + `; + + let prog = [start]; + let freeVars = ["1"]; + let inClass = false; + + while (seed >= freeVars.length) { + let index = seed % scopeCases.length; + seed = (seed / scopeCases.length) | 0; + let scope = scopeCases[index]; + if (inClass && !(scope.inClass ?? false)) { + // Skip illegal code (non-strict) or code which might not accept + // this to work. + continue; + } + inClass ||= scope.isClass ?? false; + prog.push(scope.code); + freeVars = freeVars.concat(scope.freeVars); + } + + let name = freeVars[seed]; + return prog.reduceRight((inner, f) => f(inner), `result = ${name}`); +} + +for (let s = 0; s < 3000; s++) { + let code = generateCode(s); + // console.log(s, ":", code); + testMainThread(code); + testMainThreadDelazifyAll(code); + testMainThreadCacheAll(code); + testMainThreadCacheAll2(code); + if (helperThreadCount() > 0) { + testOffThread(code); + } +} |