From ec821c6d197aeb73d007ad74b2a0ee3198e304c9 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Thu, 10 Aug 2023 10:03:11 +0000 Subject: [PATCH] Bug 1845416 - Add JS::ReadOnlyDecodeOptions and JS::OwningDecodeOptions. r=bthrall Differential Revision: https://phabricator.services.mozilla.com/D184543 --- dom/xul/nsXULElement.cpp | 2 +- js/public/CompileOptions.h | 70 ++++++++++++++++++------ js/public/OffThreadScriptCompilation.h | 7 +-- js/public/experimental/JSStencil.h | 26 ++++----- js/src/frontend/Stencil.cpp | 14 ++--- js/src/frontend/StencilXdr.cpp | 15 ++--- js/src/frontend/StencilXdr.h | 10 ++-- js/src/jsapi.cpp | 37 +++++++++++++ js/src/vm/HelperThreads.cpp | 4 +- js/src/vm/HelperThreads.h | 3 +- js/src/vm/OffThreadScriptCompilation.cpp | 12 ++-- js/xpconnect/loader/ScriptPreloader.cpp | 13 +++-- js/xpconnect/loader/ScriptPreloader.h | 28 +++++----- js/xpconnect/loader/mozJSLoaderUtils.cpp | 3 +- js/xpconnect/loader/mozJSLoaderUtils.h | 4 +- 15 files changed, 164 insertions(+), 84 deletions(-) diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp index 68a9201370aa..92adaf792490 100644 --- a/dom/xul/nsXULElement.cpp +++ b/dom/xul/nsXULElement.cpp @@ -1566,7 +1566,7 @@ static nsresult WriteStencil(nsIObjectOutputStream* aStream, JSContext* aCx, } static nsresult ReadStencil(nsIObjectInputStream* aStream, JSContext* aCx, - const JS::DecodeOptions& aOptions, + const JS::ReadOnlyDecodeOptions& aOptions, JS::Stencil** aStencilOut) { // We don't serialize mutedError-ness of scripts, which is fine as long as // we only serialize system and XUL-y things. We can detect this by checking diff --git a/js/public/CompileOptions.h b/js/public/CompileOptions.h index 272dd69a86da..6217f824af08 100644 --- a/js/public/CompileOptions.h +++ b/js/public/CompileOptions.h @@ -115,7 +115,7 @@ enum class DelazificationOption : uint8_t { }; class JS_PUBLIC_API InstantiateOptions; -class JS_PUBLIC_API DecodeOptions; +class JS_PUBLIC_API ReadOnlyDecodeOptions; // Compilation-specific part of JS::ContextOptions which is supposed to be // configured by user prefs. @@ -211,7 +211,7 @@ class JS_PUBLIC_API PrefableCompileOptions { * compilation unit to another. */ class JS_PUBLIC_API TransitiveCompileOptions { - friend class JS_PUBLIC_API DecodeOptions; + friend class JS_PUBLIC_API ReadOnlyDecodeOptions; protected: // non-POD options: @@ -765,49 +765,85 @@ class JS_PUBLIC_API InstantiateOptions { /** * Subset of CompileOptions fields used while decoding Stencils. */ -class JS_PUBLIC_API DecodeOptions { +class JS_PUBLIC_API ReadOnlyDecodeOptions { public: bool borrowBuffer = false; bool usePinnedBytecode = false; bool allocateInstantiationStorage = false; bool forceAsync = false; - const JS::ConstUTF8CharsZ introducerFilename; + protected: + JS::ConstUTF8CharsZ introducerFilename_; + public: // See `TransitiveCompileOptions::introductionType` field for details. const char* introductionType = nullptr; unsigned introductionLineno = 0; uint32_t introductionOffset = 0; - DecodeOptions() = default; + protected: + ReadOnlyDecodeOptions() = default; - explicit DecodeOptions(const ReadOnlyCompileOptions& options) - : borrowBuffer(options.borrowBuffer), - usePinnedBytecode(options.usePinnedBytecode), - allocateInstantiationStorage(options.allocateInstantiationStorage), - forceAsync(options.forceAsync), - introducerFilename(options.introducerFilename()), - introductionType(options.introductionType), - introductionLineno(options.introductionLineno), - introductionOffset(options.introductionOffset) {} + ReadOnlyDecodeOptions(const ReadOnlyDecodeOptions&) = delete; + ReadOnlyDecodeOptions& operator=(const ReadOnlyDecodeOptions&) = delete; + template + void copyPODOptions(const T& options) { + borrowBuffer = options.borrowBuffer; + usePinnedBytecode = options.usePinnedBytecode; + allocateInstantiationStorage = options.allocateInstantiationStorage; + forceAsync = options.forceAsync; + introductionType = options.introductionType; + introductionLineno = options.introductionLineno; + introductionOffset = options.introductionOffset; + } + + public: void copyTo(CompileOptions& options) const { options.borrowBuffer = borrowBuffer; options.usePinnedBytecode = usePinnedBytecode; options.allocateInstantiationStorage = allocateInstantiationStorage; options.forceAsync = forceAsync; - options.introducerFilename_ = introducerFilename; + options.introducerFilename_ = introducerFilename_; options.introductionType = introductionType; options.introductionLineno = introductionLineno; options.introductionOffset = introductionOffset; } - bool hasExternalData() const { - return introducerFilename || introductionType; + JS::ConstUTF8CharsZ introducerFilename() const { return introducerFilename_; } +}; + +class MOZ_STACK_CLASS JS_PUBLIC_API DecodeOptions final + : public ReadOnlyDecodeOptions { + public: + DecodeOptions() = default; + + explicit DecodeOptions(const ReadOnlyCompileOptions& options) { + copyPODOptions(options); + + introducerFilename_ = options.introducerFilename(); } }; +class JS_PUBLIC_API OwningDecodeOptions final : public ReadOnlyDecodeOptions { + public: + OwningDecodeOptions() = default; + + ~OwningDecodeOptions(); + + bool copy(JS::FrontendContext* maybeFc, const ReadOnlyDecodeOptions& rhs); + void infallibleCopy(const ReadOnlyDecodeOptions& rhs); + + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + + private: + void release(); + + OwningDecodeOptions(const OwningDecodeOptions&) = delete; + OwningDecodeOptions& operator=(const OwningDecodeOptions&) = delete; +}; + } // namespace JS #endif /* js_CompileOptions_h */ diff --git a/js/public/OffThreadScriptCompilation.h b/js/public/OffThreadScriptCompilation.h index 3ae3c9e45954..6ab4fd898e1f 100644 --- a/js/public/OffThreadScriptCompilation.h +++ b/js/public/OffThreadScriptCompilation.h @@ -15,7 +15,7 @@ #include "jstypes.h" // JS_PUBLIC_API -#include "js/CompileOptions.h" // JS::DecodeOptions, JS::ReadOnlyCompileOptions +#include "js/CompileOptions.h" // JS::ReadOnlyDecodeOptions, JS::ReadOnlyCompileOptions struct JS_PUBLIC_API JSContext; @@ -49,9 +49,8 @@ using OffThreadCompileCallback = void (*)(OffThreadToken* token, extern JS_PUBLIC_API bool CanCompileOffThread( JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); -extern JS_PUBLIC_API bool CanDecodeOffThread(JSContext* cx, - const DecodeOptions& options, - size_t length); +extern JS_PUBLIC_API bool CanDecodeOffThread( + JSContext* cx, const ReadOnlyDecodeOptions& options, size_t length); } // namespace JS diff --git a/js/public/experimental/JSStencil.h b/js/public/experimental/JSStencil.h index 66080c6a39e7..cc3f1715bb65 100644 --- a/js/public/experimental/JSStencil.h +++ b/js/public/experimental/JSStencil.h @@ -23,7 +23,7 @@ #include "jstypes.h" // JS_PUBLIC_API -#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions, JS::InstantiateOptions, JS::DecodeOptions +#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions, JS::InstantiateOptions, JS::ReadOnlyDecodeOptions #include "js/OffThreadScriptCompilation.h" // JS::OffThreadCompileCallback #include "js/SourceText.h" // JS::SourceText #include "js/Transcoding.h" // JS::TranscodeBuffer, JS::TranscodeRange @@ -201,14 +201,12 @@ extern JS_PUBLIC_API TranscodeResult EncodeStencil(JSContext* cx, TranscodeBuffer& buffer); // Deserialize data and create a new Stencil. -extern JS_PUBLIC_API TranscodeResult DecodeStencil(JSContext* cx, - const DecodeOptions& options, - const TranscodeRange& range, - Stencil** stencilOut); -extern JS_PUBLIC_API TranscodeResult DecodeStencil(JS::FrontendContext* fc, - const DecodeOptions& options, - const TranscodeRange& range, - Stencil** stencilOut); +extern JS_PUBLIC_API TranscodeResult +DecodeStencil(JSContext* cx, const ReadOnlyDecodeOptions& options, + const TranscodeRange& range, Stencil** stencilOut); +extern JS_PUBLIC_API TranscodeResult +DecodeStencil(JS::FrontendContext* fc, const ReadOnlyDecodeOptions& options, + const TranscodeRange& range, Stencil** stencilOut); // Register an encoder on its script source, such that all functions can be // encoded as they are delazified. @@ -255,8 +253,9 @@ extern JS_PUBLIC_API OffThreadToken* CompileModuleToStencilOffThread( // // `buffer` should be alive until the end of `FinishDecodeStencilOffThread`. extern JS_PUBLIC_API OffThreadToken* DecodeStencilOffThread( - JSContext* cx, const DecodeOptions& options, const TranscodeBuffer& buffer, - size_t cursor, OffThreadCompileCallback callback, void* callbackData); + JSContext* cx, const ReadOnlyDecodeOptions& options, + const TranscodeBuffer& buffer, size_t cursor, + OffThreadCompileCallback callback, void* callbackData); // The start of `range` should meet IsTranscodingBytecodeAligned and // AlignTranscodingBytecodeOffset. @@ -264,8 +263,9 @@ extern JS_PUBLIC_API OffThreadToken* DecodeStencilOffThread( // // `range` should be alive until the end of `FinishDecodeStencilOffThread`. extern JS_PUBLIC_API OffThreadToken* DecodeStencilOffThread( - JSContext* cx, const DecodeOptions& options, const TranscodeRange& range, - OffThreadCompileCallback callback, void* callbackData); + JSContext* cx, const ReadOnlyDecodeOptions& options, + const TranscodeRange& range, OffThreadCompileCallback callback, + void* callbackData); // Finish the off-thread task to compile the source text into a JS::Stencil, // started by JS::CompileToStencilOffThread, and return the result JS::Stencil. diff --git a/js/src/frontend/Stencil.cpp b/js/src/frontend/Stencil.cpp index 127ebd036710..8853b7d3e463 100644 --- a/js/src/frontend/Stencil.cpp +++ b/js/src/frontend/Stencil.cpp @@ -28,11 +28,11 @@ #include "frontend/ParserAtom.h" // ParserAtom, ParserAtomIndex, TaggedParserAtomIndex, ParserAtomsTable, Length{1,2,3}StaticParserString, InstantiateMarkedAtoms, InstantiateMarkedAtomsAsPermanent, GetWellKnownAtom #include "frontend/ScopeBindingCache.h" // ScopeBindingCache #include "frontend/SharedContext.h" -#include "frontend/StencilXdr.h" // XDRStencilEncoder, XDRStencilDecoder -#include "gc/AllocKind.h" // gc::AllocKind -#include "gc/Tracer.h" // TraceNullableRoot -#include "js/CallArgs.h" // JSNative -#include "js/CompileOptions.h" // JS::DecodeOptions +#include "frontend/StencilXdr.h" // XDRStencilEncoder, XDRStencilDecoder +#include "gc/AllocKind.h" // gc::AllocKind +#include "gc/Tracer.h" // TraceNullableRoot +#include "js/CallArgs.h" // JSNative +#include "js/CompileOptions.h" // JS::DecodeOptions, JS::ReadOnlyDecodeOptions #include "js/experimental/JSStencil.h" // JS::Stencil #include "js/GCAPI.h" // JS::AutoCheckCannotGC #include "js/Printer.h" // js::Fprinter @@ -5542,7 +5542,7 @@ JS::TranscodeResult JS::EncodeStencil(JSContext* cx, JS::Stencil* stencil, } JS::TranscodeResult JS::DecodeStencil(JSContext* cx, - const JS::DecodeOptions& options, + const JS::ReadOnlyDecodeOptions& options, const JS::TranscodeRange& range, JS::Stencil** stencilOut) { AutoReportFrontendContext fc(cx); @@ -5550,7 +5550,7 @@ JS::TranscodeResult JS::DecodeStencil(JSContext* cx, } JS::TranscodeResult JS::DecodeStencil(JS::FrontendContext* fc, - const JS::DecodeOptions& options, + const JS::ReadOnlyDecodeOptions& options, const JS::TranscodeRange& range, JS::Stencil** stencilOut) { RefPtr source = fc->getAllocator()->new_(); diff --git a/js/src/frontend/StencilXdr.cpp b/js/src/frontend/StencilXdr.cpp index e3737b95798c..1b4b303a2ab7 100644 --- a/js/src/frontend/StencilXdr.cpp +++ b/js/src/frontend/StencilXdr.cpp @@ -1216,7 +1216,7 @@ XDRResult StencilXDR::codeSourceData(XDRState* const xdr, template /* static */ XDRResult StencilXDR::codeSource(XDRState* xdr, - const JS::DecodeOptions* maybeOptions, + const JS::ReadOnlyDecodeOptions* maybeOptions, RefPtr& source) { FrontendContext* fc = xdr->fc(); @@ -1310,9 +1310,9 @@ XDRResult StencilXDR::codeSource(XDRState* xdr, if (mode == XDR_DECODE) { source->introductionType_ = maybeOptions->introductionType; source->setIntroductionOffset(maybeOptions->introductionOffset); - if (maybeOptions->introducerFilename) { + if (maybeOptions->introducerFilename()) { if (!source->setIntroducerFilename( - fc, maybeOptions->introducerFilename.c_str())) { + fc, maybeOptions->introducerFilename().c_str())) { return xdr->fail(JS::TranscodeResult::Throw); } } @@ -1326,12 +1326,12 @@ XDRResult StencilXDR::codeSource(XDRState* xdr, template /* static */ XDRResult StencilXDR::codeSource(XDRState* xdr, - const JS::DecodeOptions* maybeOptions, + const JS::ReadOnlyDecodeOptions* maybeOptions, RefPtr& holder); template /* static */ XDRResult StencilXDR::codeSource(XDRState* xdr, - const JS::DecodeOptions* maybeOptions, + const JS::ReadOnlyDecodeOptions* maybeOptions, RefPtr& holder); JS_PUBLIC_API bool JS::GetScriptTranscodingBuildId( @@ -1406,7 +1406,7 @@ static XDRResult VersionCheck(XDRState* xdr) { template static XDRResult XDRStencilHeader(XDRState* xdr, - const JS::DecodeOptions* maybeOptions, + const JS::ReadOnlyDecodeOptions* maybeOptions, RefPtr& source) { // The XDR-Stencil header is inserted at beginning of buffer, but it is // computed at the end the incremental-encoding process. @@ -1468,7 +1468,8 @@ bool StencilIncrementalEncoderPtr::addDelazification( } XDRResult XDRStencilDecoder::codeStencil( - const JS::DecodeOptions& options, frontend::CompilationStencil& stencil) { + const JS::ReadOnlyDecodeOptions& options, + frontend::CompilationStencil& stencil) { #ifdef DEBUG auto sanityCheck = mozilla::MakeScopeExit( [&] { MOZ_ASSERT(validateResultCode(fc(), resultCode())); }); diff --git a/js/src/frontend/StencilXdr.h b/js/src/frontend/StencilXdr.h index 9f60b1f8110d..d3bcd98bf53d 100644 --- a/js/src/frontend/StencilXdr.h +++ b/js/src/frontend/StencilXdr.h @@ -15,7 +15,7 @@ namespace JS { -class DecodeOptions; +class ReadOnlyDecodeOptions; } // namespace JS @@ -88,7 +88,7 @@ class StencilXDR { public: template static XDRResult codeSource(XDRState* xdr, - const JS::DecodeOptions* maybeOptions, + const JS::ReadOnlyDecodeOptions* maybeOptions, RefPtr& source); template @@ -182,16 +182,16 @@ class XDRStencilDecoder : public XDRState { MOZ_ASSERT(JS::IsTranscodingBytecodeAligned(range.begin().get())); } - XDRResult codeStencil(const JS::DecodeOptions& options, + XDRResult codeStencil(const JS::ReadOnlyDecodeOptions& options, frontend::CompilationStencil& stencil); - const JS::DecodeOptions& options() { + const JS::ReadOnlyDecodeOptions& options() { MOZ_ASSERT(options_); return *options_; } private: - const JS::DecodeOptions* options_ = nullptr; + const JS::ReadOnlyDecodeOptions* options_ = nullptr; }; class XDRStencilEncoder : public XDRState { diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 99e3d9b0710b..81b2288b5be7 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2447,6 +2447,43 @@ CompileOptions& CompileOptions::setIntroductionInfoToCaller( return setIntroductionType(introductionType); } +JS::OwningDecodeOptions::~OwningDecodeOptions() { release(); } + +void JS::OwningDecodeOptions::release() { + js_free(const_cast(introducerFilename_.c_str())); + + introducerFilename_ = JS::ConstUTF8CharsZ(); +} + +bool JS::OwningDecodeOptions::copy(JS::FrontendContext* maybeFc, + const JS::ReadOnlyDecodeOptions& rhs) { + copyPODOptions(rhs); + + if (rhs.introducerFilename()) { + MOZ_ASSERT(maybeFc); + const char* str = + DuplicateString(maybeFc, rhs.introducerFilename().c_str()).release(); + if (!str) { + return false; + } + introducerFilename_ = JS::ConstUTF8CharsZ(str); + } + + return true; +} + +void JS::OwningDecodeOptions::infallibleCopy( + const JS::ReadOnlyDecodeOptions& rhs) { + copyPODOptions(rhs); + + MOZ_ASSERT(!rhs.introducerFilename()); +} + +size_t JS::OwningDecodeOptions::sizeOfExcludingThis( + mozilla::MallocSizeOf mallocSizeOf) const { + return mallocSizeOf(introducerFilename_.c_str()); +} + JS_PUBLIC_API JSObject* JS_GetGlobalFromScript(JSScript* script) { return &script->global(); } diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index 6820d8e73701..b0007e32806c 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -19,7 +19,7 @@ #include "jit/IonCompileTask.h" #include "jit/JitRuntime.h" #include "jit/JitScript.h" -#include "js/CompileOptions.h" // JS::CompileOptions, JS::DecodeOptions, JS::ReadOnlyCompileOptions +#include "js/CompileOptions.h" // JS::CompileOptions, JS::ReadOnlyDecodeOptions, JS::ReadOnlyCompileOptions #include "js/experimental/CompileScript.h" #include "js/experimental/JSStencil.h" #include "js/friend/StackLimits.h" // js::ReportOverRecursed @@ -1104,7 +1104,7 @@ JS::OffThreadToken* js::StartOffThreadCompileModuleToStencil( } JS::OffThreadToken* js::StartOffThreadDecodeStencil( - JSContext* cx, const JS::DecodeOptions& options, + JSContext* cx, const JS::ReadOnlyDecodeOptions& options, const JS::TranscodeRange& range, JS::OffThreadCompileCallback callback, void* callbackData) { auto task = diff --git a/js/src/vm/HelperThreads.h b/js/src/vm/HelperThreads.h index 81b9b9ee6bde..e28bb44df8b0 100644 --- a/js/src/vm/HelperThreads.h +++ b/js/src/vm/HelperThreads.h @@ -28,6 +28,7 @@ union Utf8Unit; namespace JS { class OffThreadToken {}; class JS_PUBLIC_API ReadOnlyCompileOptions; +class JS_PUBLIC_API ReadOnlyDecodeOptions; class Zone; template @@ -234,7 +235,7 @@ JS::OffThreadToken* StartOffThreadCompileModuleToStencil( JS::OffThreadCompileCallback callback, void* callbackData); JS::OffThreadToken* StartOffThreadDecodeStencil( - JSContext* cx, const JS::DecodeOptions& options, + JSContext* cx, const JS::ReadOnlyDecodeOptions& options, const JS::TranscodeRange& range, JS::OffThreadCompileCallback callback, void* callbackData); diff --git a/js/src/vm/OffThreadScriptCompilation.cpp b/js/src/vm/OffThreadScriptCompilation.cpp index f84cae3ebe6a..66564ac15572 100644 --- a/js/src/vm/OffThreadScriptCompilation.cpp +++ b/js/src/vm/OffThreadScriptCompilation.cpp @@ -91,8 +91,9 @@ JS_PUBLIC_API JS::OffThreadToken* JS::CompileModuleToStencilOffThread( } JS_PUBLIC_API JS::OffThreadToken* JS::DecodeStencilOffThread( - JSContext* cx, const DecodeOptions& options, const TranscodeBuffer& buffer, - size_t cursor, OffThreadCompileCallback callback, void* callbackData) { + JSContext* cx, const ReadOnlyDecodeOptions& options, + const TranscodeBuffer& buffer, size_t cursor, + OffThreadCompileCallback callback, void* callbackData) { JS::TranscodeRange range(buffer.begin() + cursor, buffer.length() - cursor); MOZ_ASSERT(CanDecodeOffThread(cx, options, range.length())); return StartOffThreadDecodeStencil(cx, options, range, callback, @@ -100,8 +101,9 @@ JS_PUBLIC_API JS::OffThreadToken* JS::DecodeStencilOffThread( } JS_PUBLIC_API JS::OffThreadToken* JS::DecodeStencilOffThread( - JSContext* cx, const DecodeOptions& options, const TranscodeRange& range, - OffThreadCompileCallback callback, void* callbackData) { + JSContext* cx, const ReadOnlyDecodeOptions& options, + const TranscodeRange& range, OffThreadCompileCallback callback, + void* callbackData) { MOZ_ASSERT(CanDecodeOffThread(cx, options, range.length())); return StartOffThreadDecodeStencil(cx, options, range, callback, callbackData); @@ -125,7 +127,7 @@ JS_PUBLIC_API void JS::CancelOffThreadToken(JSContext* cx, } JS_PUBLIC_API bool JS::CanDecodeOffThread(JSContext* cx, - const DecodeOptions& options, + const ReadOnlyDecodeOptions& options, size_t length) { return CanDoOffThread(cx, options, length); } diff --git a/js/xpconnect/loader/ScriptPreloader.cpp b/js/xpconnect/loader/ScriptPreloader.cpp index 058ee5cee431..0419ebcbaf5f 100644 --- a/js/xpconnect/loader/ScriptPreloader.cpp +++ b/js/xpconnect/loader/ScriptPreloader.cpp @@ -939,7 +939,8 @@ void ScriptPreloader::FillDecodeOptionsForCachedStencil( } already_AddRefed ScriptPreloader::GetCachedStencil( - JSContext* cx, const JS::DecodeOptions& options, const nsCString& path) { + JSContext* cx, const JS::ReadOnlyDecodeOptions& options, + const nsCString& path) { MOZ_RELEASE_ASSERT( !(XRE_IsContentProcess() && !mCacheInitialized), "ScriptPreloader must be initialized before getting cached " @@ -965,7 +966,8 @@ already_AddRefed ScriptPreloader::GetCachedStencil( } already_AddRefed ScriptPreloader::GetCachedStencilInternal( - JSContext* cx, const JS::DecodeOptions& options, const nsCString& path) { + JSContext* cx, const JS::ReadOnlyDecodeOptions& options, + const nsCString& path) { auto* cachedScript = mScripts.Get(path); if (cachedScript) { return WaitForCachedStencil(cx, options, cachedScript); @@ -974,7 +976,8 @@ already_AddRefed ScriptPreloader::GetCachedStencilInternal( } already_AddRefed ScriptPreloader::WaitForCachedStencil( - JSContext* cx, const JS::DecodeOptions& options, CachedStencil* script) { + JSContext* cx, const JS::ReadOnlyDecodeOptions& options, + CachedStencil* script) { if (!script->mReadyToExecute) { MOZ_ASSERT(mDecodedStencils); @@ -1184,7 +1187,7 @@ void ScriptPreloader::StartDecodeTask(JS::HandleObject scope) { } bool ScriptPreloader::StartDecodeTask( - JS::DecodeOptions decodeOptions, + const JS::ReadOnlyDecodeOptions& decodeOptions, Vector&& decodingSources) { mDecodedStencils.emplace(decodingSources.length()); MOZ_ASSERT(mDecodedStencils); @@ -1269,7 +1272,7 @@ bool ScriptPreloader::CachedStencil::XDREncode(JSContext* cx) { } already_AddRefed ScriptPreloader::CachedStencil::GetStencil( - JSContext* cx, const JS::DecodeOptions& options) { + JSContext* cx, const JS::ReadOnlyDecodeOptions& options) { MOZ_ASSERT(mReadyToExecute); if (mStencil) { return do_AddRef(mStencil); diff --git a/js/xpconnect/loader/ScriptPreloader.h b/js/xpconnect/loader/ScriptPreloader.h index 9ab69bc33da0..a46d3ca51ace 100644 --- a/js/xpconnect/loader/ScriptPreloader.h +++ b/js/xpconnect/loader/ScriptPreloader.h @@ -29,7 +29,7 @@ #include "nsIThread.h" #include "nsITimer.h" -#include "js/CompileOptions.h" // JS::DecodeOptions +#include "js/CompileOptions.h" // JS::DecodeOptions, JS::ReadOnlyDecodeOptions #include "js/experimental/JSStencil.h" // JS::Stencil #include "js/GCAnnotations.h" // for JS_HAZ_NON_GC_POINTER #include "js/RootingAPI.h" // for Handle, Heap @@ -108,7 +108,8 @@ class ScriptPreloader : public nsIObserver, // Retrieves the stencil with the given cache key from the cache. // Returns null if the stencil is not cached. already_AddRefed GetCachedStencil( - JSContext* cx, const JS::DecodeOptions& options, const nsCString& path); + JSContext* cx, const JS::ReadOnlyDecodeOptions& options, + const nsCString& path); // Notes the execution of a script with the given URL and cache key. // Depending on the stage of startup, the script may be serialized and @@ -137,7 +138,8 @@ class ScriptPreloader : public nsIObserver, private: Result InitCacheInternal(JS::Handle scope = nullptr); already_AddRefed GetCachedStencilInternal( - JSContext* cx, const JS::DecodeOptions& options, const nsCString& path); + JSContext* cx, const JS::ReadOnlyDecodeOptions& options, + const nsCString& path); public: static ProcessType CurrentProcessType() { @@ -310,8 +312,8 @@ class ScriptPreloader : public nsIObserver, bool HasArray() { return mXDRData.constructed>(); } - already_AddRefed GetStencil(JSContext* cx, - const JS::DecodeOptions& options); + already_AddRefed GetStencil( + JSContext* cx, const JS::ReadOnlyDecodeOptions& options); size_t HeapSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { auto size = mallocSizeOf(this); @@ -436,30 +438,28 @@ class ScriptPreloader : public nsIObserver, // Waits for the given cached script to finish compiling off-thread, or // decodes it synchronously on the main thread, as appropriate. already_AddRefed WaitForCachedStencil( - JSContext* cx, const JS::DecodeOptions& options, CachedStencil* script); + JSContext* cx, const JS::ReadOnlyDecodeOptions& options, + CachedStencil* script); void StartDecodeTask(JS::Handle scope); private: - bool StartDecodeTask(JS::DecodeOptions decodeOptions, + bool StartDecodeTask(const JS::ReadOnlyDecodeOptions& decodeOptions, Vector&& decodingSources); class DecodeTask : public Runnable { ScriptPreloader* mPreloader; - JS::DecodeOptions mDecodeOptions; + JS::OwningDecodeOptions mDecodeOptions; Vector mDecodingSources; public: - DecodeTask(ScriptPreloader* preloader, JS::DecodeOptions decodeOptions, + DecodeTask(ScriptPreloader* preloader, + const JS::ReadOnlyDecodeOptions& decodeOptions, Vector&& decodingSources) : Runnable("ScriptPreloaderDecodeTask"), mPreloader(preloader), - mDecodeOptions(decodeOptions), mDecodingSources(std::move(decodingSources)) { - // NOTE: the JS::DecodeOptions is created on the main thread and is going - // to be used off main thread. There shouldn't be any external data - // reference, such as filename. - MOZ_ASSERT(!decodeOptions.hasExternalData()); + mDecodeOptions.infallibleCopy(decodeOptions); } NS_IMETHOD Run() override; diff --git a/js/xpconnect/loader/mozJSLoaderUtils.cpp b/js/xpconnect/loader/mozJSLoaderUtils.cpp index 3f54e87d3b09..b59da16702e0 100644 --- a/js/xpconnect/loader/mozJSLoaderUtils.cpp +++ b/js/xpconnect/loader/mozJSLoaderUtils.cpp @@ -35,7 +35,8 @@ static nsresult HandleTranscodeResult(JSContext* cx, } nsresult ReadCachedStencil(StartupCache* cache, nsACString& cachePath, - JSContext* cx, const JS::DecodeOptions& options, + JSContext* cx, + const JS::ReadOnlyDecodeOptions& options, JS::Stencil** stencilOut) { MOZ_ASSERT(options.borrowBuffer); MOZ_ASSERT(!options.usePinnedBytecode); diff --git a/js/xpconnect/loader/mozJSLoaderUtils.h b/js/xpconnect/loader/mozJSLoaderUtils.h index 8c996c17be6f..95b4cefb2d6e 100644 --- a/js/xpconnect/loader/mozJSLoaderUtils.h +++ b/js/xpconnect/loader/mozJSLoaderUtils.h @@ -10,7 +10,7 @@ #include "nsString.h" #include "js/experimental/JSStencil.h" -#include "js/CompileOptions.h" // JS::DecodeOptions +#include "js/CompileOptions.h" // JS::ReadOnlyDecodeOptions namespace mozilla { namespace scache { @@ -20,7 +20,7 @@ class StartupCache; nsresult ReadCachedStencil(mozilla::scache::StartupCache* cache, nsACString& cachePath, JSContext* cx, - const JS::DecodeOptions& options, + const JS::ReadOnlyDecodeOptions& options, JS::Stencil** stencilOut); nsresult WriteCachedStencil(mozilla::scache::StartupCache* cache,