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,
OffThreadToken* token);
extern JS_PUBLIC_API void CancelOffThreadCompileToStencil(
JSContext* cx, OffThreadToken* token);
extern JS_PUBLIC_API OffThreadToken* CompileOffThreadModule(
JSContext* cx, const ReadOnlyCompileOptions& options,
SourceText<char16_t>& srcBuf, OffThreadCompileCallback callback,

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

@ -137,6 +137,14 @@ JS_PUBLIC_API void JS::CancelOffThreadScript(JSContext* cx,
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(
JSContext* cx, const ReadOnlyCompileOptions& options,
JS::SourceText<char16_t>& srcBuf, OffThreadCompileCallback callback,

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

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

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

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