-
Notifications
You must be signed in to change notification settings - Fork 13k
Make modifierFlagsCache mandatory for Node objects #29726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The `modifierFlagsCache` property is among the top properties that cause megamorphic stub cache misses when having `tsc` build itself. This is because it's added sort of randomly to a whole lot of different objects, at arbitrary points after their initialization. This also means that `modifierFlagsCache` is often not present on the instances, which means that when missing on the megamorphic stub cache, Node/V8 has to compute `NonExistent` handlers for the relevant inline caches. It's a lot cheaper to just make sure that the property is always existent on the instance, and ideally also at the same offset. This change ensures exactly that. Drive-by-fix: Also make sure that `transformFlags` (and `parent`) is always at the same offset for `Node` objects.
@rbuckton can you grab some perf numbers for this? |
In general this makes sense, we already do this in utilities.ts for compiler for the same reason. I can run a benchmark comparison, though it seems there are test failures currently. |
Unfortunately this is not easy to assess, due to the nature of the megamorphic stub cache in V8. I'm currently investigating class performance in various applications, especially ones generated with TypeScript (I wrote an explainer regarding the megamorphic stub cache as part of that). This change reduces the number of megamorphic stub cache misses for The |
@bmeurer: Since these modifications are mostly in services, I take it your comparisons were against the language server and not the command-line compiler? @RyanCavanaugh: Our benchmarks don't differ here because the benchmarks only test command-line compiler performance. However, this is a good change as it helps to align the language server object allocators for our ASTs to align with the behavior of the object allocators for tsc. |
@rbuckton I'm using the typescript runner from the web-tooling-benchmark, which uses |
That unfortunately loads the whole language service, which has its own AST factory (the I'm not certain why your change has caused test failures. Most seem to be related to JSDoc parsing. @sandersn: Any idea what's going on here? |
This should start with `TransformFlags.None` just like in the `Node` constructor in `src/compiler/utilities.ts`.
Any idea regarding the JSDoc test failures? I'm a bit puzzled here TBH. |
@bmeurer the test failures are from tests that baseline the parser output (example below). You should run
|
@RyanCavanaugh Ah, thanks. Did that 👍 (BTW |
This is a gulp4 thing. Apparently it doesn't like streams merged with |
It seems like there are still failing baslines. |
@rbuckton Ups. Should be fixed now. |
I think you should run
These are consequences to remove optionality from |
@j-oliveras done, thanks |
Thanks for the contribution! |
Awesome, thanks a lot! 👍 So do you think the typescript testing in the web-tooling-benchmark is actually a useful, representative test? Or am I looking at the wrong problem? |
That can depend on whether your benchmark is intended to measure the execution time of a specific downlevel representation of native JavaScript, or to measure the execution of the compiler itself. The Internally, the TypeScript team runs regular benchmarks (multiple per day) against the We have, on occasion, chosen to focus on downlevel emit that has better performance characteristics at runtime at the expense of non-spec-compliant runtime semantics. For example, our |
The benchmark was supposed to give an idea of the general performance of TypeScript compiler on any given JavaScript engine. So ideally improvements on the benchmark should show up as improvements in the wild for users. There are two main scenarios I see here:
Ideally both of these should be fast. |
The
modifierFlagsCache
property is among the top properties that causemegamorphic stub cache misses when having
tsc
build itself. This isbecause it's added sort of randomly to a whole lot of different objects,
at arbitrary points after their initialization.
This also means that
modifierFlagsCache
is often not present on theinstances, which means that when missing on the megamorphic stub cache,
Node/V8 has to compute
NonExistent
handlers for the relevant inlinecaches.
It's a lot cheaper to just make sure that the property is always
existent on the instance, and ideally also at the same offset. This
change ensures exactly that.
Drive-by-fix: Also make sure that
transformFlags
(andparent
)is always at the same offset for
Node
objects.