Open Bug 1662156 (run-from-stencil) Opened 4 years ago Updated 1 year ago

[meta] Support instantiating JS stencil without allocating inner-inner JSFunctions

Categories

(Core :: JavaScript Engine, task, P3)

task

Tracking

()

People

(Reporter: tcampbell, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: meta)

In cases where the CompilationStencil lives past the initial call to instantiateStencils, we can avoid allocating JSFunctions that have lazy parents (as well as the BaseScript). Doing so would reduce the latency from having stencil data in memory to executing the first opcode in a given Realm. This may be useful in browser startup cases where the ScriptPreloader has pinned the stencil data across multiple Fission processes.

Currently these allocated functions store information such as closed-of-bindings and SourceExtent, but this information would continue to be available from the stencil so we can defer the allocation until their parent function is delazified. This will also save memory for functions are never have their parents called and reduce GC traffic.

The primary blockers are the JS Debugger, but it can be modified to delazify on-demand the scripts that it actually requires.

Blocks: 1663955
No longer blocks: stencil

(Arai may take a look at this, so tentatively assigning to avoid duplicate work)

Assignee: nobody → arai.unmht

TODO (random order):

  • associate compiled/decoded stencils to ScriptSource or somewhere:
    • requirement:
      • accessible from all functions
      • kept alive if there's any function alive
  • do no instantiate inner-inner functions
  • do not store names/functions in GC things of lazy functions
  • when delazifying a function, allocate inner functions
  • debugger
    • fix findScript to iterate on stencil vector instead of (or in addition to) iterating GC cells
    • instantiate function when findScript result or something refers inner-inner function

Things to consider:

  • what to keep on memory
  • avoid duplication
  • when to release stencil

for example:

  • constant (extent, immutable flags) can be stored only in stencil, to avoid duplication, but in that case stencil cannot be released
    • we might need to separate shared/immutable data and mutable/GC things, and use different lifetime between them
  • how to achieve:
    • the equivalent of GC-ing top-level script
    • the equivalent of relazification

Possible steps:

  1. when compiling initial stencil, allocate ScriptSource first
  2. allocate CompilationInfo inside ScriptSource field
  3. compile to stencil, with CompilationInfo stored in the ScriptSource
  4. when instantiating:
    • do not allocate function inside lazy function
    • allocate lazy function with GC things pointing ScriptStencil inside CompilationInfo stored in ScriptSource, by index (maybe we can use pointer, but given it's Vector element, index might be better)
  5. when delazifying, instantiate inner functions as lazy function in the same way as step 4
  6. when compacting, instantiate all remaining functions as lazy function first (make sure nothing points/depends CompilationInfo), and drop CompilationInfo in ScriptSource

it's a bit annoying that:

  • compaction allocates possibly-many extra things before releasing (but that way we can get the same memory pressure as before after compaction)
  • we need to keep current lazy-inside-lazy handling
    • delazification and debugger need to support both cases

Another way is, to integrate delazification/relazification with XDR.
make it possible to point CompilationInfo stored either in ScriptSource as on memory data, or in XDR-encoded buffer stored on disk,
and when delazifying, load and XDR-decode the buffer if necessary, and use the CompilationInfo.

this is complicated because currently we have multiple on-disk format/file on gecko side,
and load/decode to be sync-operation.

TODO: measure how many bytes in the XDR data is referred from decoded stencil.
if the amount of heap-allocated data isn't large compared to the entire XDR data,
keeping the decoded stencil on memory won't be much trouble.

unassigning for now.
will revisit this after other phase 2 things.

Assignee: arai.unmht → nobody
You need to log in before you can comment on or make changes to this bug.