Closed Bug 1662273 Opened 1 year ago Closed 1 year ago

Allow XDR of CompilationStencil within ScriptLoader

Categories

(Core :: JavaScript Engine, task, P1)

task

Tracking

()

RESOLVED FIXED
83 Branch
Tracking Status
firefox83 --- fixed

People

(Reporter: tcampbell, Assigned: arai)

References

Details

Attachments

(1 file, 1 obsolete file)

In order to complete Bug 1662102, we need to transcode the CompilationStencil into the bytecode cache instead of the JSScript. This requires changes to the DOM ScriptLoader.

Note that we probably will need to tag the MIME-type as stencil instead of bytecode for the cache to not break down when someone toggles the pref.

Ideally, this encoding would not block page-load main-thread.

Depends on: 1662274

Bug 1660940 will add:

  • same-thread compilation to stencil (JS::CompileToStencil and JS::CompileToStencilForNonSyntacticScope)
  • same-thread stencil instantiation (JS::InstantiateScript)

In this case CompilationStencil is passed back to the API consumer.

 

And bug 1658631 added support for:

  • off-thread compilation to stencil
  • stencil instantiation on main-thread after off-thread compilation to stencil

In this case CompilationStencil is hidden from the API consumer
(started by JS::CompileOffThread, JS::CompileOffThreadModule, finished by JS::FinishOffThreadScript and JS::FinishOffThreadModule).

 

To support stencil XDR in public API used by ScriptLoader, missing parts are:

  • a) XDR encode after same-thread compilation
  • b) XDR encode after off-thread compilation
  • c) same-thread XDR decode
  • d) off-thread XDR decode

 

(a) happens in nsJSUtils::ExecutionContext::InternalCompile, after calling JS::Compile and JS::CompileForNonSyntacticScope.

https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/base/nsJSUtils.cpp#228

  if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) {

and collected by ScriptLoader::EncodeRequestBytecode

https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/script/ScriptLoader.cpp#3135

  if (!JS::FinishIncrementalEncoding(aCx, script, aRequest->mScriptBytecode)) {

In this case, this can use:

  1. CompileToStencil
  2. "XDR encode stencil" (this will be same-thread encode for now)
  3. InstantiateScript

inside nsJSUtils::ExecutionContext::InternalCompile, and not using off-thread encoding.

 

(b) happens in nsJSUtils::ExecutionContext::JoinCompile after calling JS::FinishOffThreadScript.

https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/base/nsJSUtils.cpp#195

  if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) {

and also collected by ScriptLoader::EncodeRequestBytecode.

In this case, CompilationStencil is hidden in JSAPI internal, so JS::FinishOffThreadScript needs refactoring.

something like:

  1. Pass the result of off-thread compilation (CompilationStencil) to JSAPI consumer
  2. "XDR encode stencil"
  3. JS::InstantiateScript

or add single API for those 3 steps.

This case also uses same-thread encode for now.

 

(c) happens in nsJSUtils::ExecutionContext::Decode

https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/base/nsJSUtils.cpp#273-274

  JS::TranscodeResult tr =
      JS::DecodeScript(mCx, aBytecodeBuf, &mScript, aBytecodeIndex);

This can be:

  • "XDR decode stencil"
  • JS::InstantiateScript

or single API with those 2 steps.

 

(d) happens in ScriptLoader::AttemptAsyncScriptCompile

https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/script/ScriptLoader.cpp#2322

    if (!JS::DecodeOffThreadScript(
            cx, options, aRequest->mScriptBytecode, aRequest->mBytecodeOffset,
            OffThreadScriptLoaderCallback, static_cast<void*>(runnable))) {

and collected by nsJSUtils::ExecutionContext::JoinDecode

https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/base/nsJSUtils.cpp#297

  mScript.set(JS::FinishOffThreadScriptDecoder(mCx, *aOffThreadToken));

This case, CompilationStencil is hidden behind JSAPI.
helper thread just needs to support "XDR decode stencil",
and frontend::InstantiateStencil when finishing the task,
just like compilation (parse) task.

for encoding, if we provide composite APIs like "compile and encode", "finish off thread compilation and encode" we don't have to expose CompilationStencil to the consumer (so, bug 1660940 part 4 isn't necessary), at least for this bug.

ScriptPreloader will still need to receive CompilationStencil tho.

(In reply to Tooru Fujisawa [:arai] from comment #1)

(a) happens in nsJSUtils::ExecutionContext::InternalCompile, after calling JS::Compile and JS::CompileForNonSyntacticScope.

https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/base/nsJSUtils.cpp#228

  if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) {

and collected by ScriptLoader::EncodeRequestBytecode

https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/script/ScriptLoader.cpp#3135

  if (!JS::FinishIncrementalEncoding(aCx, script, aRequest->mScriptBytecode)) {

In this case, this can use:

  1. CompileToStencil
  2. "XDR encode stencil" (this will be same-thread encode for now)
  3. InstantiateScript

inside nsJSUtils::ExecutionContext::InternalCompile, and not using off-thread encoding.

One thing to note about the incremental encoding and off-thread saving.

  • Incremental was needed by XDR as a way to spread the XDR costs across function which needed to be encoded. This would not change with Stencil.
  • Off-thread saving was needed by XDR as a way to avoid potentially large 4ms or larger pauses on sorting bytes and transmitting these bytes to the alternate data stream to be written. This would have to be reevaluated with Stencil. While Stencil should not require any reordering of the content, it would still require to copy the bytes to the alternate data stream, and the time needed for this copy might still be time consuming based on the amount of data to be saved.

thanks, I was mixing incremental/off-thread up.

bug 1663962 will add composite APIs for (a) and (b).
there we can switch between JSScript XDR and stencil XDR.

for (c), JS::DecodeScript with TranscodeBuffer has another consumer for startupCache, so we'll need dedicate API for ScriptLoader usage, that can switch between JSScript XDR and stencil XDR.
https://searchfox.org/mozilla-central/search?q=symbol:_ZN2JS12DecodeScriptEP9JSContextRN7mozilla6VectorIhLj0ENS2_17MallocAllocPolicyEEENS_13MutableHandleIP8JSScriptEEj%2C_ZN2JS12DecodeScriptEP9JSContextRN7mozilla6VectorIhLm0ENS2_17MallocAllocPolicyEEENS_13MutableHandleIP8JSScriptEEm%2C_ZN2JS12DecodeScriptEP9JSContextRN7mozilla6VectorIhLy0ENS2_17MallocAllocPolicyEEENS_13MutableHandleIP8JSScriptEEy&redirect=false

Depends on: 1664147
Depends on: 1664182
Attachment #9175575 - Attachment description: Bug 1662273 - PROTOTYPE: Use stencil XDR in incremental encoding and off-thread single script decoding. → Bug 1662273 - Use stencil XDR in incremental encoding and off-thread single script decoding. r?tcampbell
Attachment #9175575 - Attachment description: Bug 1662273 - Use stencil XDR in incremental encoding and off-thread single script decoding. r?tcampbell → Bug 1662273 - Use stencil XDR in incremental encoding and off-thread single script decoding. r?tcampbell!
Assignee: nobody → arai.unmht
Status: NEW → ASSIGNED
Attachment #9175575 - Attachment is obsolete: true
Pushed by arai_a@mac.com:
https://hg.mozilla.org/integration/autoland/rev/b3ea886b0ae7
Use stencil XDR in incremental encoding and off-thread single script decoding. r=tcampbell
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 83 Branch
Regressed by: 1678243
No longer regressed by: 1678243
Regressions: 1678243
You need to log in before you can comment on or make changes to this bug.