Bug 1436400 - Part 7: Split ScriptLoader::MaybePrepareForBytecodeEncoding into 2 parts. r=nbp

As a preparation to use the bytecode encoding in the module evaluation code,
ScriptLoader::MaybePrepareForBytecodeEncoding is split into 2 parts:
  * one for performing preparation before executing script
  * one for queuing the request for bytecode encoding after executing script

In module's case, the bytecode encoding handling must be done on the entire
import tree, and also the module object's ScriptSlot is cleared on execution.
So, the script reference must be copied to the corresponding script load request
field before execution, and the script source must be queued for bytecode
encoding after executing the top-level script, so that incremental encoding
reflects functions called there.

Differential Revision: https://phabricator.services.mozilla.com/D140295
This commit is contained in:
Tooru Fujisawa
2022-03-15 04:24:51 +00:00
parent f21919623f
commit f23c9d2f7b
2 changed files with 49 additions and 25 deletions

View File

@@ -2130,26 +2130,34 @@ nsCString& ScriptLoader::BytecodeMimeTypeFor(ScriptLoadRequest* aRequest) {
return nsContentUtils::JSScriptBytecodeMimeType();
}
nsresult ScriptLoader::MaybePrepareForBytecodeEncoding(
JS::Handle<JSScript*> aScript, ScriptLoadRequest* aRequest, nsresult aRv) {
bool encodeBytecode = ShouldCacheBytecode(aRequest);
void ScriptLoader::MaybePrepareForBytecodeEncodingBeforeExecute(
ScriptLoadRequest* aRequest, JS::Handle<JSScript*> aScript) {
if (!ShouldCacheBytecode(aRequest)) {
return;
}
// Queue the current script load request to later save the bytecode.
if (aScript && encodeBytecode) {
aRequest->MarkForBytecodeEncoding(aScript);
aRequest->MarkForBytecodeEncoding(aScript);
}
nsresult ScriptLoader::MaybePrepareForBytecodeEncodingAfterExecute(
ScriptLoadRequest* aRequest, nsresult aRv) {
if (aRequest->IsMarkedForBytecodeEncoding()) {
TRACE_FOR_TEST(aRequest->GetLoadContext()->GetScriptElement(),
"scriptloader_encode");
// NOTE: This assertion will fail once we start encoding more data after the
// first encode.
MOZ_ASSERT(aRequest->mBytecodeOffset == aRequest->mScriptBytecode.length());
RegisterForBytecodeEncoding(aRequest);
} else {
LOG(
("ScriptLoadRequest (%p): Bytecode-cache: disabled (rv = %X, "
"script = %p)",
aRequest, unsigned(aRv), aScript.get()));
TRACE_FOR_TEST_NONE(aRequest->GetLoadContext()->GetScriptElement(),
"scriptloader_no_encode");
aRequest->mCacheInfo = nullptr;
return aRv;
}
LOG(("ScriptLoadRequest (%p): Bytecode-cache: disabled (rv = %X)", aRequest,
unsigned(aRv)));
TRACE_FOR_TEST_NONE(aRequest->GetLoadContext()->GetScriptElement(),
"scriptloader_no_encode");
aRequest->mCacheInfo = nullptr;
return aRv;
}
@@ -2192,17 +2200,23 @@ nsresult ScriptLoader::EvaluateScript(nsIGlobalObject* aGlobalObject,
// TODO (yulia): rewrite this section. rv can be a failing pattern other than
// NS_OK which will pass the NS_FAILED check above. If we call exec.GetScript
// in that case, it will crash.
JS::Rooted<JSScript*> script(cx);
if (rv == NS_OK) {
script = exec.GetScript();
LOG(("ScriptLoadRequest (%p): Evaluate Script", aRequest));
AUTO_PROFILER_MARKER_TEXT("ScriptExecution", JS,
MarkerInnerWindowIdFromJSContext(cx),
profilerLabelString);
JS::Rooted<JSScript*> script(cx, exec.GetScript());
MaybePrepareForBytecodeEncodingBeforeExecute(aRequest, script);
rv = ExecuteCompiledScript(cx, exec, classicScript);
{
LOG(("ScriptLoadRequest (%p): Evaluate Script", aRequest));
AUTO_PROFILER_MARKER_TEXT("ScriptExecution", JS,
MarkerInnerWindowIdFromJSContext(cx),
profilerLabelString);
rv = ExecuteCompiledScript(cx, exec, classicScript);
}
}
rv = MaybePrepareForBytecodeEncoding(script, aRequest, rv);
// This must be called also for compilation failure case, in order to
// dispatch test-only event.
rv = MaybePrepareForBytecodeEncodingAfterExecute(aRequest, rv);
// Even if we are not saving the bytecode of the current script, we have
// to trigger the encoding of the bytecode, as the current script can