Bug 1716934 - Use JS::Stencil in PrecompiledScript. r=nbp,mccr8

Differential Revision: https://phabricator.services.mozilla.com/D118317
This commit is contained in:
Tooru Fujisawa 2021-06-25 02:27:13 +00:00
Родитель f0edc4ed46
Коммит 3f259c48f8
4 изменённых файлов: 46 добавлений и 50 удалений

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

@ -98,6 +98,9 @@ extern JS_PUBLIC_API JSScript* FinishOffThreadScriptAndStartIncrementalEncoding(
extern JS_PUBLIC_API void CancelOffThreadScript(JSContext* cx, extern JS_PUBLIC_API void CancelOffThreadScript(JSContext* cx,
OffThreadToken* token); OffThreadToken* token);
extern JS_PUBLIC_API void CancelOffThreadCompileToStencil(
JSContext* cx, OffThreadToken* token);
extern JS_PUBLIC_API OffThreadToken* CompileOffThreadModule( extern JS_PUBLIC_API OffThreadToken* CompileOffThreadModule(
JSContext* cx, const ReadOnlyCompileOptions& options, JSContext* cx, const ReadOnlyCompileOptions& options,
SourceText<char16_t>& srcBuf, OffThreadCompileCallback callback, SourceText<char16_t>& srcBuf, OffThreadCompileCallback callback,

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

@ -137,6 +137,14 @@ JS_PUBLIC_API void JS::CancelOffThreadScript(JSContext* cx,
token); token);
} }
JS_PUBLIC_API void JS::CancelOffThreadCompileToStencil(
JSContext* cx, JS::OffThreadToken* token) {
MOZ_ASSERT(cx);
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
HelperThreadState().cancelParseTask(cx->runtime(),
ParseTaskKind::ScriptStencil, token);
}
JS_PUBLIC_API JS::OffThreadToken* JS::CompileOffThreadModule( JS_PUBLIC_API JS::OffThreadToken* JS::CompileOffThreadModule(
JSContext* cx, const ReadOnlyCompileOptions& options, JSContext* cx, const ReadOnlyCompileOptions& options,
JS::SourceText<char16_t>& srcBuf, OffThreadCompileCallback callback, JS::SourceText<char16_t>& srcBuf, OffThreadCompileCallback callback,

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

@ -15,6 +15,7 @@
#include "jsapi.h" #include "jsapi.h"
#include "jsfriendapi.h" #include "jsfriendapi.h"
#include "js/CompilationAndEvaluation.h" #include "js/CompilationAndEvaluation.h"
#include "js/experimental/JSStencil.h" // JS::CompileGlobalScriptToStencil, JS::InstantiateGlobalStencil, JS::OffThreadCompileToStencil
#include "js/SourceText.h" #include "js/SourceText.h"
#include "js/Utility.h" #include "js/Utility.h"
@ -70,7 +71,7 @@ class AsyncScriptCompiler final : public nsIIncrementalStreamLoaderObserver,
bool StartCompile(JSContext* aCx); bool StartCompile(JSContext* aCx);
void FinishCompile(JSContext* aCx); void FinishCompile(JSContext* aCx);
void Finish(JSContext* aCx, Handle<JSScript*> script); void Finish(JSContext* aCx, RefPtr<JS::Stencil> aStencil);
OwningCompileOptions mOptions; OwningCompileOptions mOptions;
nsCString mURL; nsCString mURL;
@ -135,17 +136,15 @@ static void OffThreadScriptLoaderCallback(JS::OffThreadToken* aToken,
} }
bool AsyncScriptCompiler::StartCompile(JSContext* aCx) { bool AsyncScriptCompiler::StartCompile(JSContext* aCx) {
Rooted<JSObject*> global(aCx, mGlobalObject->GetGlobalJSObject());
JS::SourceText<char16_t> srcBuf; JS::SourceText<char16_t> srcBuf;
if (!srcBuf.init(aCx, std::move(mScriptText), mScriptLength)) { if (!srcBuf.init(aCx, std::move(mScriptText), mScriptLength)) {
return false; return false;
} }
if (JS::CanCompileOffThread(aCx, mOptions, mScriptLength)) { if (JS::CanCompileOffThread(aCx, mOptions, mScriptLength)) {
if (!JS::CompileOffThread(aCx, mOptions, srcBuf, if (!JS::CompileToStencilOffThread(aCx, mOptions, srcBuf,
OffThreadScriptLoaderCallback, OffThreadScriptLoaderCallback,
static_cast<void*>(this))) { static_cast<void*>(this))) {
return false; return false;
} }
@ -153,12 +152,13 @@ bool AsyncScriptCompiler::StartCompile(JSContext* aCx) {
return true; return true;
} }
Rooted<JSScript*> script(aCx, JS::Compile(aCx, mOptions, srcBuf)); RefPtr<Stencil> stencil =
if (!script) { JS::CompileGlobalScriptToStencil(aCx, mOptions, srcBuf);
if (!stencil) {
return false; return false;
} }
Finish(aCx, script); Finish(aCx, stencil);
return true; return true;
} }
@ -169,7 +169,7 @@ AsyncScriptCompiler::Run() {
FinishCompile(jsapi.cx()); FinishCompile(jsapi.cx());
} else { } else {
jsapi.Init(); jsapi.Init();
JS::CancelOffThreadScript(jsapi.cx(), mToken); JS::CancelOffThreadCompileToStencil(jsapi.cx(), mToken);
mPromise->MaybeReject(NS_ERROR_FAILURE); mPromise->MaybeReject(NS_ERROR_FAILURE);
} }
@ -178,17 +178,18 @@ AsyncScriptCompiler::Run() {
} }
void AsyncScriptCompiler::FinishCompile(JSContext* aCx) { void AsyncScriptCompiler::FinishCompile(JSContext* aCx) {
Rooted<JSScript*> script(aCx, JS::FinishOffThreadScript(aCx, mToken)); RefPtr<JS::Stencil> stencil =
if (script) { JS::FinishOffThreadCompileToStencil(aCx, mToken);
Finish(aCx, script); if (stencil) {
Finish(aCx, stencil);
} else { } else {
Reject(aCx); Reject(aCx);
} }
} }
void AsyncScriptCompiler::Finish(JSContext* aCx, Handle<JSScript*> aScript) { void AsyncScriptCompiler::Finish(JSContext* aCx, RefPtr<JS::Stencil> aStencil) {
RefPtr<PrecompiledScript> result = RefPtr<PrecompiledScript> result =
new PrecompiledScript(mGlobalObject, aScript, mOptions); new PrecompiledScript(mGlobalObject, aStencil, mOptions);
mPromise->MaybeResolve(result); mPromise->MaybeResolve(result);
} }
@ -284,20 +285,16 @@ already_AddRefed<Promise> ChromeUtils::CompileScript(
} }
PrecompiledScript::PrecompiledScript(nsISupports* aParent, PrecompiledScript::PrecompiledScript(nsISupports* aParent,
Handle<JSScript*> aScript, RefPtr<JS::Stencil> aStencil,
JS::ReadOnlyCompileOptions& aOptions) JS::ReadOnlyCompileOptions& aOptions)
: mParent(aParent), : mParent(aParent),
mScript(aScript), mStencil(aStencil),
mURL(aOptions.filename()), mURL(aOptions.filename()),
mHasReturnValue(!aOptions.noScriptRval) { mHasReturnValue(!aOptions.noScriptRval) {
MOZ_ASSERT(aParent); MOZ_ASSERT(aParent);
MOZ_ASSERT(aScript); MOZ_ASSERT(aStencil);
mozilla::HoldJSObjects(this);
}; };
PrecompiledScript::~PrecompiledScript() { mozilla::DropJSObjects(this); }
void PrecompiledScript::ExecuteInGlobal(JSContext* aCx, HandleObject aGlobal, void PrecompiledScript::ExecuteInGlobal(JSContext* aCx, HandleObject aGlobal,
MutableHandleValue aRval, MutableHandleValue aRval,
ErrorResult& aRv) { ErrorResult& aRv) {
@ -305,8 +302,15 @@ void PrecompiledScript::ExecuteInGlobal(JSContext* aCx, HandleObject aGlobal,
RootedObject targetObj(aCx, JS_FindCompilationScope(aCx, aGlobal)); RootedObject targetObj(aCx, JS_FindCompilationScope(aCx, aGlobal));
JSAutoRealm ar(aCx, targetObj); JSAutoRealm ar(aCx, targetObj);
Rooted<JSScript*> script(aCx, mScript); CompileOptions options(aCx);
if (!JS::CloneAndExecuteScript(aCx, script, aRval)) { Rooted<JSScript*> script(
aCx, JS::InstantiateGlobalStencil(aCx, options, mStencil));
if (!script) {
aRv.NoteJSContextException(aCx);
return;
}
if (!JS_ExecuteScript(aCx, script, aRval)) {
aRv.NoteJSContextException(aCx); aRv.NoteJSContextException(aCx);
return; return;
} }
@ -329,34 +333,15 @@ bool PrecompiledScript::IsBlackForCC(bool aTracingNeeded) {
(!aTracingNeeded || HasNothingToTrace(this))); (!aTracingNeeded || HasNothingToTrace(this)));
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(PrecompiledScript) NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PrecompiledScript, mParent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PrecompiledScript) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PrecompiledScript)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PrecompiledScript)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
tmp->mScript = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PrecompiledScript)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(PrecompiledScript)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScript)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(PrecompiledScript) NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(PrecompiledScript)
if (tmp->IsBlackForCC(false)) { return tmp->IsBlackForCC(false);
tmp->mScript.exposeToActiveJS();
return true;
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(PrecompiledScript) NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(PrecompiledScript)

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

@ -8,8 +8,9 @@
#include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/PrecompiledScriptBinding.h" #include "mozilla/dom/PrecompiledScriptBinding.h"
#include "mozilla/RefPtr.h"
#include "js/RootingAPI.h" #include "js/experimental/JSStencil.h"
#include "js/TypeDecls.h" #include "js/TypeDecls.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -27,8 +28,7 @@ class PrecompiledScript : public nsISupports, public nsWrapperCache {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(PrecompiledScript) NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(PrecompiledScript)
explicit PrecompiledScript(nsISupports* aParent, explicit PrecompiledScript(nsISupports* aParent, RefPtr<JS::Stencil> aStencil,
JS::Handle<JSScript*> aScript,
JS::ReadOnlyCompileOptions& aOptions); JS::ReadOnlyCompileOptions& aOptions);
void ExecuteInGlobal(JSContext* aCx, JS::HandleObject aGlobal, void ExecuteInGlobal(JSContext* aCx, JS::HandleObject aGlobal,
@ -44,14 +44,14 @@ class PrecompiledScript : public nsISupports, public nsWrapperCache {
JS::Handle<JSObject*> aGivenProto) override; JS::Handle<JSObject*> aGivenProto) override;
protected: protected:
virtual ~PrecompiledScript(); virtual ~PrecompiledScript() = default;
private: private:
bool IsBlackForCC(bool aTracingNeeded); bool IsBlackForCC(bool aTracingNeeded);
nsCOMPtr<nsISupports> mParent; nsCOMPtr<nsISupports> mParent;
JS::Heap<JSScript*> mScript; RefPtr<JS::Stencil> mStencil;
nsCString mURL; nsCString mURL;
const bool mHasReturnValue; const bool mHasReturnValue;
}; };