Bug 1763372 - Add LoadContextBase; r=jonco,smaug

Differential Revision: https://phabricator.services.mozilla.com/D143036
This commit is contained in:
Yulia Startsev 2022-04-22 13:24:09 +00:00
parent 2b0e6156c2
commit f1dd84285f
9 changed files with 159 additions and 47 deletions

View File

@ -15,7 +15,9 @@
#include "js/OffThreadScriptCompilation.h"
#include "js/SourceText.h"
#include "js/loader/ScriptLoadRequest.h"
#include "js/loader/LoadContextBase.h"
#include "ScriptLoadContext.h"
#include "ModuleLoadRequest.h"
#include "nsContentUtils.h"
#include "nsICacheInfoChannel.h"
@ -30,30 +32,29 @@ namespace dom {
//////////////////////////////////////////////////////////////
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptLoadContext)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoadContext)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadContext)
NS_INTERFACE_MAP_END_INHERITING(JS::loader::LoadContextBase)
NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoadBlockedDocument, mRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ScriptLoadContext,
JS::loader::LoadContextBase)
if (Runnable* runnable = tmp->mRunnable.exchange(nullptr)) {
runnable->Release();
}
tmp->MaybeUnblockOnload();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDocument, mRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ScriptLoadContext,
JS::loader::LoadContextBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadContext)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_ADDREF_INHERITED(ScriptLoadContext, JS::loader::LoadContextBase)
NS_IMPL_RELEASE_INHERITED(ScriptLoadContext, JS::loader::LoadContextBase)
ScriptLoadContext::ScriptLoadContext()
: mScriptMode(ScriptMode::eBlocking),
: JS::loader::LoadContextBase(JS::loader::ContextKind::Window),
mScriptMode(ScriptMode::eBlocking),
mScriptFromHead(false),
mIsInline(true),
mInDeferList(false),
@ -67,7 +68,6 @@ ScriptLoadContext::ScriptLoadContext()
mRunnable(nullptr),
mLineNo(1),
mIsPreload(false),
mRequest(nullptr),
mUnreportedPreloadError(NS_OK) {}
ScriptLoadContext::~ScriptLoadContext() {
@ -126,11 +126,6 @@ void ScriptLoadContext::MaybeCancelOffThreadScript() {
mOffThreadToken = nullptr;
}
void ScriptLoadContext::SetRequest(JS::loader::ScriptLoadRequest* aRequest) {
MOZ_ASSERT(!mRequest);
mRequest = aRequest;
}
void ScriptLoadContext::SetScriptMode(bool aDeferAttr, bool aAsyncAttr,
bool aLinkPreload) {
if (aLinkPreload) {

View File

@ -11,8 +11,8 @@
#include "js/RootingAPI.h"
#include "js/SourceText.h"
#include "js/TypeDecls.h"
#include "js/loader/LoadContextBase.h"
#include "js/loader/ScriptKind.h"
#include "js/loader/ScriptLoadRequest.h"
#include "mozilla/Atomics.h"
#include "mozilla/Assertions.h"
#include "mozilla/CORSMode.h"
@ -28,15 +28,11 @@
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIScriptElement.h"
#include "js/loader/ScriptKind.h"
class nsICacheInfoChannel;
namespace JS {
class OffThreadToken;
namespace loader {
class ScriptLoadRequest;
}
} // namespace JS
namespace mozilla {
@ -79,17 +75,17 @@ class Element;
*
*/
class ScriptLoadContext : public PreloaderBase {
class ScriptLoadContext : public JS::loader::LoadContextBase,
public PreloaderBase {
protected:
virtual ~ScriptLoadContext();
public:
explicit ScriptLoadContext();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ScriptLoadContext)
void SetRequest(JS::loader::ScriptLoadRequest* aRequest);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ScriptLoadContext,
JS::loader::LoadContextBase)
// PreloaderBase
static void PrioritizeAsPreload(nsIChannel* aChannel);
@ -154,7 +150,7 @@ class ScriptLoadContext : public PreloaderBase {
}
// Used to output a string for the Gecko Profiler.
void GetProfilerLabel(nsACString& aOutString);
void GetProfilerLabel(nsACString& aOutString) override;
void MaybeCancelOffThreadScript();
@ -188,8 +184,6 @@ class ScriptLoadContext : public PreloaderBase {
// Set on scripts and top level modules.
bool mIsPreload;
RefPtr<JS::loader::ScriptLoadRequest> mRequest;
// Non-null if there is a document that this request is blocking from loading.
RefPtr<Document> mLoadBlockedDocument;

View File

@ -122,7 +122,7 @@ ScriptLoadHandler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
if (!mPreloadStartNotified) {
mPreloadStartNotified = true;
mRequest->mLoadContext->NotifyStart(channelRequest);
mRequest->GetLoadContext()->NotifyStart(channelRequest);
}
if (mRequest->IsCanceled()) {
@ -222,8 +222,9 @@ bool ScriptLoadHandler::TrySetDecoder(nsIIncrementalStreamLoader* aLoader,
// Check the hint charset from the script element or preload
// request.
nsAutoString hintCharset;
if (!mRequest->mLoadContext->IsPreload()) {
mRequest->mLoadContext->GetScriptElement()->GetScriptCharset(hintCharset);
if (!mRequest->GetLoadContext()->IsPreload()) {
mRequest->GetLoadContext()->GetScriptElement()->GetScriptCharset(
hintCharset);
} else {
nsTArray<ScriptLoader::PreloadInfo>::index_type i =
mScriptLoader->mPreloads.IndexOf(
@ -296,7 +297,7 @@ nsresult ScriptLoadHandler::EnsureKnownDataType(
if (mRequest->mFetchSourceOnly) {
mRequest->SetTextSource();
TRACE_FOR_TEST(mRequest->mLoadContext->GetScriptElement(),
TRACE_FOR_TEST(mRequest->GetLoadContext()->GetScriptElement(),
"scriptloader_load_source");
return NS_OK;
}
@ -307,7 +308,7 @@ nsresult ScriptLoadHandler::EnsureKnownDataType(
cic->GetAlternativeDataType(altDataType);
if (altDataType.Equals(ScriptLoader::BytecodeMimeTypeFor(mRequest))) {
mRequest->SetBytecode();
TRACE_FOR_TEST(mRequest->mLoadContext->GetScriptElement(),
TRACE_FOR_TEST(mRequest->GetLoadContext()->GetScriptElement(),
"scriptloader_load_bytecode");
return NS_OK;
}
@ -315,7 +316,7 @@ nsresult ScriptLoadHandler::EnsureKnownDataType(
}
mRequest->SetTextSource();
TRACE_FOR_TEST(mRequest->mLoadContext->GetScriptElement(),
TRACE_FOR_TEST(mRequest->GetLoadContext()->GetScriptElement(),
"scriptloader_load_source");
MOZ_ASSERT(!mRequest->IsUnknownDataType());
@ -341,11 +342,11 @@ ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
if (!mPreloadStartNotified) {
mPreloadStartNotified = true;
mRequest->mLoadContext->NotifyStart(channelRequest);
mRequest->GetLoadContext()->NotifyStart(channelRequest);
}
auto notifyStop = MakeScopeExit(
[&] { mRequest->mLoadContext->NotifyStop(channelRequest, rv); });
[&] { mRequest->GetLoadContext()->NotifyStop(channelRequest, rv); });
if (!mRequest->IsCanceled()) {
if (mRequest->IsUnknownDataType()) {

View File

@ -11,6 +11,7 @@
#include "js/loader/LoadedScript.h"
#include "js/loader/ScriptKind.h"
#include "js/loader/ScriptLoadRequest.h"
#include "mozilla/dom/ScriptLoadContext.h"
#include "nsCOMPtr.h"
#include "nsRefPtrHashtable.h"
#include "nsIScriptElement.h"

View File

@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ScriptLoadContext.h"
#include "js/loader/LoadContextBase.h"
#include "js/loader/ScriptLoadRequest.h"
namespace JS::loader {
////////////////////////////////////////////////////////////////
// LoadContextBase
////////////////////////////////////////////////////////////////
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(LoadContextBase)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(LoadContextBase)
NS_IMPL_CYCLE_COLLECTING_RELEASE(LoadContextBase)
NS_IMPL_CYCLE_COLLECTION_CLASS(LoadContextBase)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(LoadContextBase)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(LoadContextBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
LoadContextBase::LoadContextBase(ContextKind kind)
: mKind(kind), mRequest(nullptr) {}
void LoadContextBase::SetRequest(ScriptLoadRequest* aRequest) {
MOZ_ASSERT(!mRequest);
mRequest = aRequest;
}
void LoadContextBase::GetProfilerLabel(nsACString& aOutString) {
aOutString.Append("Unknown Script Element");
}
mozilla::dom::ScriptLoadContext* LoadContextBase::AsWindowContext() {
MOZ_ASSERT(IsWindowContext());
return static_cast<mozilla::dom::ScriptLoadContext*>(this);
}
} // namespace JS::loader

View File

@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef js_loader_BaseLoadContext_h
#define js_loader_BaseLoadContext_h
#include "js/loader/ScriptLoadRequest.h"
#include "nsIStringBundle.h"
namespace mozilla::dom {
class ScriptLoadContext;
}
namespace JS::loader {
class ScriptLoadRequest;
/*
* LoadContextBase
*
* LoadContexts augment the loading of a ScriptLoadRequest. This class
* is used as a base for all LoadContexts, and provides shared functionality.
*
* Different loading environments have different rules applied to how a script
* is loaded. In DOM scripts, there are flags controlling load order (Async,
* Deferred, normal) as well as other elements that impact the loading of a
* script (<preload>). In the case of workers, service workers are potentially
* loaded from the Cache. For more detailed information per context see
* * The ScriptLoadContext: dom/script/ScriptLoadContext.h
*
*/
// TODO: implement worker LoadContext
enum class ContextKind { Window };
class LoadContextBase : public nsISupports {
private:
ContextKind mKind;
protected:
virtual ~LoadContextBase() = default;
public:
explicit LoadContextBase(ContextKind);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(LoadContextBase)
void SetRequest(JS::loader::ScriptLoadRequest* aRequest);
// Used to output a string for the Gecko Profiler.
virtual void GetProfilerLabel(nsACString& aOutString);
// Casting to the different contexts
bool IsWindowContext() const { return mKind == ContextKind::Window; }
mozilla::dom::ScriptLoadContext* AsWindowContext();
RefPtr<JS::loader::ScriptLoadRequest> mRequest;
};
} // namespace JS::loader
#endif // js_loader_BaseLoadContext_h

View File

@ -79,7 +79,7 @@ ScriptLoadRequest::ScriptLoadRequest(ScriptKind aKind, nsIURI* aURI,
ScriptFetchOptions* aFetchOptions,
const SRIMetadata& aIntegrity,
nsIURI* aReferrer,
mozilla::dom::ScriptLoadContext* aContext)
LoadContextBase* aContext)
: mKind(aKind),
mState(State::Fetching),
mFetchSourceOnly(false),
@ -123,6 +123,11 @@ void ScriptLoadRequest::DropBytecodeCacheReferences() {
DropJSObjects(this);
}
mozilla::dom::ScriptLoadContext* ScriptLoadRequest::GetLoadContext() {
MOZ_ASSERT(mLoadContext);
return mLoadContext->AsWindowContext();
}
ModuleLoadRequest* ScriptLoadRequest::AsModuleRequest() {
MOZ_ASSERT(IsModuleRequest());
return static_cast<ModuleLoadRequest*>(this);

View File

@ -14,8 +14,8 @@
#include "mozilla/Atomics.h"
#include "mozilla/Assertions.h"
#include "mozilla/CORSMode.h"
#include "mozilla/dom/ScriptLoadContext.h"
#include "mozilla/dom/SRIMetadata.h"
#include "mozilla/dom/ReferrerPolicyBinding.h"
#include "mozilla/LinkedList.h"
#include "mozilla/Maybe.h"
#include "mozilla/MaybeOneOf.h"
@ -28,6 +28,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsIGlobalObject.h"
#include "ScriptKind.h"
#include "nsIScriptElement.h"
class nsICacheInfoChannel;
@ -44,6 +45,7 @@ namespace loader {
using Utf8Unit = mozilla::Utf8Unit;
class LoadContextBase;
class ModuleLoadRequest;
class ScriptLoadRequestList;
@ -158,7 +160,7 @@ class ScriptLoadRequest
ScriptLoadRequest(ScriptKind aKind, nsIURI* aURI,
ScriptFetchOptions* aFetchOptions,
const SRIMetadata& aIntegrity, nsIURI* aReferrer,
mozilla::dom::ScriptLoadContext* aContext);
LoadContextBase* aContext);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ScriptLoadRequest)
@ -293,10 +295,7 @@ class ScriptLoadRequest
bool HasLoadContext() { return mLoadContext; }
mozilla::dom::ScriptLoadContext* GetLoadContext() {
MOZ_ASSERT(mLoadContext);
return mLoadContext;
}
mozilla::dom::ScriptLoadContext* GetLoadContext();
const ScriptKind mKind; // Whether this is a classic script or a module
// script.
@ -343,9 +342,9 @@ class ScriptLoadRequest
// on the cache entry, such that we can load it the next time.
nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
// ScriptLoadContext for augmenting the load depending on the loading
// LoadContext for augmenting the load depending on the loading
// context (DOM, Worker, etc.)
RefPtr<mozilla::dom::ScriptLoadContext> mLoadContext;
RefPtr<LoadContextBase> mLoadContext;
};
class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest> {

View File

@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.js.loader += [
"LoadContextBase.h",
"LoadedScript.h",
"ModuleLoaderBase.h",
"ModuleLoadRequest.h",
@ -13,6 +14,7 @@ EXPORTS.js.loader += [
]
UNIFIED_SOURCES += [
"LoadContextBase.cpp",
"LoadedScript.cpp",
"ModuleLoaderBase.cpp",
"ModuleLoadRequest.cpp",