Stack alloc reduce
This Pull Request closes #4089
Reduce the stack size. Mostly affected expression with nested parenthesizes.
Some examples & comparison charts
fn parenthesized_fn_test() {
let n = ...;
let js = "(function(){ ".repeat(n) + &" })()".repeat(n);
let interner = &mut Interner::default();
crate::Parser::new(crate::Source::from_bytes(&js))
.parse_script(&boa_ast::scope::Scope::new_global(), interner)
.expect("failed to parse");
}
| profile | prev max n without stack overflow |
new max n without stack overflow |
x |
|---|---|---|---|
dev (opt-level = 0) |
11 | 79 | ~6 |
test (opt-level = 1) |
50 | 160 | ~3 |
| release | 50 | 217 | ~4 |
fn parenthesized_sum_test() {
let n = ...;
let js = "(1+".repeat(n) + "41" + &")".repeat(n);
let interner = &mut Interner::default();
crate::Parser::new(crate::Source::from_bytes(&js))
.parse_script(&boa_ast::scope::Scope::new_global(), interner)
.expect("failed to parse");
}
| profile | prev max n without stack overflow |
new max n without stack overflow |
x |
|---|---|---|---|
dev (opt-level = 0) |
30 | 200 | ~6.5 |
test (opt-level = 1) |
105 | 390 | ~3.5 |
| release | 105 | 510 | ~4.5 |
Now there no stack overflow when running the boa_tester in debug(cargo run -p boa_tester -- run -v -o test262 ). The problem was here test262\test\language\statements\function\S13.2.1_A1_T1.js, so you can run cargo run -p boa_tester -- run -s test/language/statements/function/ to test the fix. For more details see the issue.
The reduction performed by 3 operations:
- boxing of large objects. It's affected all
profiles and allow to reduce the stack size by ~ 3 times; - In one place nested
parsecalls was unwrapped. Also affected allprofiles; -
Splitting
parsefunction. Affected onlyprofile.dev(opt-level = 0) where the problem arose. Allow to reduce the stack size by ~ 2 times (and with boxing it becomes ~ 6 times).
There are some ugly changes that need to be discussed & maybe rewritten to a less ugly:
- The unwrapping;
- Splitting like this --> this --> this --> this.
All of the changes reduce the stack size, so even if they are ugly, they are still not meaningless :/
Codecov Report
Attention: Patch coverage is 71.97232% with 162 lines in your changes missing coverage. Please review.
Project coverage is 52.78%. Comparing base (
6ddc2b4) to head (e324a18). Report is 385 commits behind head on main.
Additional details and impacted files
@@ Coverage Diff @@
## main #4191 +/- ##
==========================================
+ Coverage 47.24% 52.78% +5.54%
==========================================
Files 476 488 +12
Lines 46892 52236 +5344
==========================================
+ Hits 22154 27575 +5421
+ Misses 24738 24661 -77
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
I would like to see the performance impact of this one, in release. Would you mind running the v8 combined benchmarks?
cargo run -p boa_cli --release -- -O $SRC/boa-dev/data/bench/bench-v8/combined.js
(with $SRC being wherever your root for boa-dev/data repo is)
Current results of the bench.
PROGRESS Richards
RESULT Richards 72.8
PROGRESS DeltaBlue
RESULT DeltaBlue 64.4
PROGRESS Encrypt
PROGRESS Decrypt
RESULT Crypto 144
PROGRESS RayTrace
RESULT RayTrace 196
PROGRESS Earley
PROGRESS Boyer
RESULT EarleyBoyer 229
PROGRESS RegExp
RESULT RegExp 61.0
PROGRESS Splay
RESULT Splay 355
PROGRESS NavierStokes
RESULT NavierStokes 337
SCORE 147
undefined
Previous(checkout 35b44d9ce07efb45fb094887964d473911b21012) results of the bench.
PROGRESS Richards
RESULT Richards 76.0
PROGRESS DeltaBlue
RESULT DeltaBlue 64.8
PROGRESS Encrypt
PROGRESS Decrypt
RESULT Crypto 140
PROGRESS RayTrace
RESULT RayTrace 190
PROGRESS Earley
PROGRESS Boyer
RESULT EarleyBoyer 230
PROGRESS RegExp
RESULT RegExp 61.2
PROGRESS Splay
RESULT Splay 357
PROGRESS NavierStokes
RESULT NavierStokes 334
SCORE 147
undefined
Seems like a noise error. And it's pretty predictable, because as I can understand the bench tests the perf of js execution, and PR's changes affect only the parser stage. So is there a bench to test perf of the parser stage?
Nice! I'll review when I have some time this weekend.
Another question I would have is whether the new _boxed constructors are necessary, instead of simply replacing the regular constructors. WDYT?
Another question I would have is whether the new
_boxedconstructors are necessary, instead of simply replacing the regular constructors. WDYT?
Hmm... new_boxed shows that the return value is not Self but Box<Self>; and sometimes there is another code which does not need Box<T>.