Bug 1788977 - Share stencil-instantiate code in JSExecutionContext. r=arai

Differential Revision: https://phabricator.services.mozilla.com/D156339
This commit is contained in:
Ted Campbell 2022-09-06 12:01:36 +00:00
Родитель 5b24c97520
Коммит 63b0610c8f
3 изменённых файлов: 44 добавлений и 98 удалений

Просмотреть файл

@ -87,15 +87,14 @@ JSExecutionContext::JSExecutionContext(
}
}
nsresult JSExecutionContext::JoinCompile(JS::OffThreadToken** aOffThreadToken) {
nsresult JSExecutionContext::JoinOffThread(
JS::OffThreadToken** aOffThreadToken) {
if (mSkip) {
return mRv;
}
MOZ_ASSERT(!mWantsReturnValue);
MOZ_ASSERT(!mScript);
JS::InstantiateOptions instantiateOptions(mCompileOptions);
JS::Rooted<JS::InstantiationStorage> storage(mCx);
RefPtr<JS::Stencil> stencil = JS::FinishOffThreadStencil(
mCx, *aOffThreadToken, storage.address());
@ -106,29 +105,7 @@ nsresult JSExecutionContext::JoinCompile(JS::OffThreadToken** aOffThreadToken) {
return mRv;
}
JS::Rooted<JSScript*> script(
mCx, JS::InstantiateGlobalStencil(mCx, instantiateOptions, stencil,
storage.address()));
if (!script) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
if (mEncodeBytecode) {
if (!JS::StartIncrementalEncoding(mCx, std::move(stencil))) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
}
mScript.set(script);
if (!UpdateDebugMetadata()) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
return InstantiateStencil(std::move(stencil), storage.address());
}
template <typename Unit>
@ -143,26 +120,15 @@ nsresult JSExecutionContext::InternalCompile(JS::SourceText<Unit>& aSrcBuf) {
mWantsReturnValue = !mCompileOptions.noScriptRval;
#endif
MOZ_ASSERT(!mScript);
if (mEncodeBytecode) {
mScript =
JS::CompileAndStartIncrementalEncoding(mCx, mCompileOptions, aSrcBuf);
} else {
mScript = JS::Compile(mCx, mCompileOptions, aSrcBuf);
}
if (!mScript) {
RefPtr<JS::Stencil> stencil =
CompileGlobalScriptToStencil(mCx, mCompileOptions, aSrcBuf);
if (!stencil) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
if (!UpdateDebugMetadata()) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
return InstantiateStencil(std::move(stencil));
}
nsresult JSExecutionContext::Compile(JS::SourceText<char16_t>& aSrcBuf) {
@ -196,9 +162,7 @@ nsresult JSExecutionContext::Decode(mozilla::Vector<uint8_t>& aBytecodeBuf,
return mRv;
}
JS::CompileOptions options(mCx, mCompileOptions);
JS::DecodeOptions decodeOptions(options);
JS::DecodeOptions decodeOptions(mCompileOptions);
decodeOptions.borrowBuffer = true;
JS::TranscodeRange range(aBytecodeBuf.begin() + aBytecodeIndex,
@ -218,57 +182,38 @@ nsresult JSExecutionContext::Decode(mozilla::Vector<uint8_t>& aBytecodeBuf,
return mRv;
}
JS::InstantiateOptions instantiateOptions(options);
mScript = JS::InstantiateGlobalStencil(mCx, instantiateOptions, stencil);
if (!mScript) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!UpdateDebugMetadata()) {
return NS_ERROR_OUT_OF_MEMORY;
}
return mRv;
return InstantiateStencil(std::move(stencil));
}
bool JSExecutionContext::UpdateDebugMetadata() {
JS::InstantiateOptions options(mCompileOptions);
if (!options.deferDebugMetadata) {
return true;
}
return JS::UpdateDebugMetadata(mCx, mScript, options, mDebuggerPrivateValue,
nullptr, mDebuggerIntroductionScript, nullptr);
}
nsresult JSExecutionContext::JoinDecode(JS::OffThreadToken** aOffThreadToken) {
if (mSkip) {
return mRv;
}
MOZ_ASSERT(!mWantsReturnValue);
JS::Rooted<JS::InstantiationStorage> storage(mCx);
RefPtr<JS::Stencil> stencil = JS::FinishOffThreadStencil(
mCx, *aOffThreadToken, storage.address());
*aOffThreadToken = nullptr; // Mark the token as having been finished.
if (!stencil) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
nsresult JSExecutionContext::InstantiateStencil(
RefPtr<JS::Stencil>&& aStencil, JS::InstantiationStorage* aStorage) {
JS::InstantiateOptions instantiateOptions(mCompileOptions);
mScript.set(JS::InstantiateGlobalStencil(mCx, instantiateOptions, stencil,
storage.address()));
if (!mScript) {
JS::Rooted<JSScript*> script(
mCx, JS::InstantiateGlobalStencil(mCx, instantiateOptions, aStencil,
aStorage));
if (!script) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
if (!UpdateDebugMetadata()) {
return NS_ERROR_OUT_OF_MEMORY;
if (mEncodeBytecode) {
if (!JS::StartIncrementalEncoding(mCx, std::move(aStencil))) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
}
MOZ_ASSERT(!mScript);
mScript.set(script);
if (instantiateOptions.deferDebugMetadata) {
if (!JS::UpdateDebugMetadata(mCx, mScript, instantiateOptions,
mDebuggerPrivateValue, nullptr,
mDebuggerIntroductionScript, nullptr)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
return NS_OK;

Просмотреть файл

@ -11,6 +11,7 @@
#include "js/OffThreadScriptCompilation.h"
#include "js/TypeDecls.h"
#include "js/Value.h"
#include "js/experimental/JSStencil.h"
#include "jsapi.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
@ -76,13 +77,16 @@ class MOZ_STACK_CLASS JSExecutionContext final {
bool mScriptUsed;
#endif
bool UpdateDebugMetadata();
private:
// Compile a script contained in a SourceText.
template <typename Unit>
nsresult InternalCompile(JS::SourceText<Unit>& aSrcBuf);
// Instantiate (on main-thread) a JS::Stencil generated by off-thread or
// main-thread parsing or decoding.
nsresult InstantiateStencil(RefPtr<JS::Stencil>&& aStencil,
JS::InstantiationStorage* aStorage = nullptr);
public:
// Enter compartment in which the code would be executed. The JSContext
// must come from an AutoEntryScript.
@ -123,10 +127,10 @@ class MOZ_STACK_CLASS JSExecutionContext final {
return *this;
}
// After getting a notification that an off-thread compilation terminated,
// After getting a notification that an off-thread compile/decode finished,
// this function will take the result of the parser and move it to the main
// thread.
[[nodiscard]] nsresult JoinCompile(JS::OffThreadToken** aOffThreadToken);
[[nodiscard]] nsresult JoinOffThread(JS::OffThreadToken** aOffThreadToken);
// Compile a script contained in a SourceText.
nsresult Compile(JS::SourceText<char16_t>& aSrcBuf);
@ -139,11 +143,6 @@ class MOZ_STACK_CLASS JSExecutionContext final {
nsresult Decode(mozilla::Vector<uint8_t>& aBytecodeBuf,
size_t aBytecodeIndex);
// After getting a notification that an off-thread decoding terminated, this
// function will get the result of the decoder and move it to the main
// thread.
nsresult JoinDecode(JS::OffThreadToken** aOffThreadToken);
// Get a successfully compiled script.
JSScript* GetScript();

Просмотреть файл

@ -2218,7 +2218,8 @@ nsresult ScriptLoader::CompileOrDecodeClassicScript(
if (aRequest->GetScriptLoadContext()->mOffThreadToken) {
LOG(("ScriptLoadRequest (%p): Decode Bytecode & Join and Execute",
aRequest));
rv = aExec.JoinDecode(&aRequest->GetScriptLoadContext()->mOffThreadToken);
rv = aExec.JoinOffThread(
&aRequest->GetScriptLoadContext()->mOffThreadToken);
} else {
LOG(("ScriptLoadRequest (%p): Decode Bytecode and Execute", aRequest));
AUTO_PROFILER_MARKER_TEXT("BytecodeDecodeMainThread", JS,
@ -2245,7 +2246,8 @@ nsresult ScriptLoader::CompileOrDecodeClassicScript(
"Execute",
aRequest));
MOZ_ASSERT(aRequest->IsTextSource());
rv = aExec.JoinCompile(&aRequest->GetScriptLoadContext()->mOffThreadToken);
rv =
aExec.JoinOffThread(&aRequest->GetScriptLoadContext()->mOffThreadToken);
} else {
// Main thread parsing (inline and small scripts)
LOG(("ScriptLoadRequest (%p): Compile And Exec", aRequest));