Hi all, I wanted to give some updates on current and upcoming changes to how the results of lazy-parsing are represented in SpiderMonkey. There has been cleanup over the past year to use more self-contained data-types (such as js::PrivateScriptData) and reducing the amount of manual GC bookkeeping (Bug 1535138). More recently we have been moving towards using a single instance for both the LazyScript and JSScript types (Bug 1529456).
Recent Changes: - Various JIT-related fields were moved from JSScript into a new js::JitScript data type (Bug 1551796). This reduced the size of JSScript and made lifetimes easier to reason about. - The flags for both JSScript and js::LazyScript use the same set of flags. Note that not all flags are fully initialized for each type and some care must be taken. - Both JSScript and js::LazyScript inherit from a new js::BaseScript type (Bug 1566803). This contains fields (such as 'sourceObject' and 'toStringStart') that were duplicated. - LazyScriptData is removed and we use js::PrivateScriptData for both lazy and non-lazy scripts. These primarily contain a variable-length bucket of GCCellPtrs that the script may use. These pointer fields also now belong to the BaseScript type. Note that the contents of the PrivateScriptData changes as a script is delazified from lazy to compiled forms. - The 'LazyScript::enclosingLazySciptOrScope', 'JSScript::warmUpCount', 'JSScript::jitScript_' fields are combined into a tagged-union type called 'js::ScriptWarmUpData'. As a script progresses from uncompiled-lazy to JIT-optimized forms, this field changes types. This is part of the BaseScript. - Many uses of the LazyScript* type in code can now use BaseScript* and use a single path to handle accessing information about both lazy and non-lazy scripts. - The one remaining field differing between LazyScript and JSScript is the shared-reference to the immutable bytecode. This is unsurprisingly only defined for a compiled script. Upcoming Changes (FF73): - Bug 1600705 will avoid allocating script data for leaf-function LazyScripts. Currently this only contains a bunch of nullptrs. - Bug 1529456 will combine the LazyScript and JSScript objects: - The LazyScript GC arena will be removed. All LazyScripts and JSScripts will use same object layout and size. A never-compiled script will use the same memory as before, but any compiled scripts will use less memory. - During delazification, we re-use the script and attach the new bytecode, the PrivateScriptData, and switch the warmUpData to warm-up-count mode. - Since we only relazify leaf-scripts, there will be no script data we need to preserve and relazification can be done in-place. - Special care is taken so that during delazification errors that we correctly restore the script instance to a lazy form. - We eliminate the Debugger's lazy-script tracking and only need to worry about the association of a DebuggerScript to a single script instance. - Stop generating JIT-code check for cases that now behave more consistently regardless of if script is lazy (Bug 1567157). Future Work: - Relazification can be expanding to non-leaf functions. This can be done by releasing bytecode, while preserving js::Scope and other data that prevents relazification today. This would be a new operating mode of a script between lazy and compiled, but is straightforward with the other previous work complete. - This is particularly useful for the top-level script which is run once but kept alive do to entrained scopes. - It is also possible to restore scripts to fully lazy forms. The PrivateScriptData from the original lazy form can be regenerated easily from a fully compiled script. We've come a long way since what these structures looked like in ESR60: https://searchfox.org/mozilla-esr60/rev/02b4ae79b24aae2346b1338e2bf095a571192061/js/src/vm/JSScript.h#820-1897,1908-2159 --Ted _______________________________________________ dev-tech-js-engine-internals mailing list dev-tech-js-engine-internals@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals