Bug 1365187 - Keep track of which modules in a graph have been fetched using a visited set r=smaug
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 14 Dec 2017 15:13:57 -0600
changeset 448213 9eca4461d0799a310d610dadf3e78cc1b5e35b3e
parent 448212 ebcc9ceb0842d5e925d693d0e48eeef80c0d0877
child 448214 9ffdabd433a0ff7a2f2b3501cbdca88faf67e500
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1365187
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1365187 - Keep track of which modules in a graph have been fetched using a visited set r=smaug
dom/script/ModuleLoadRequest.cpp
dom/script/ModuleLoadRequest.h
dom/script/ScriptLoadRequest.cpp
dom/script/ScriptLoadRequest.h
dom/script/ScriptLoader.cpp
dom/script/ScriptLoader.h
--- a/dom/script/ModuleLoadRequest.cpp
+++ b/dom/script/ModuleLoadRequest.cpp
@@ -16,36 +16,59 @@ namespace dom {
   MOZ_LOG(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug, args)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ModuleLoadRequest)
 NS_INTERFACE_MAP_END_INHERITING(ScriptLoadRequest)
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(ModuleLoadRequest, ScriptLoadRequest,
                                    mBaseURL,
                                    mLoader,
-                                   mParent,
                                    mModuleScript,
                                    mImports)
 
 NS_IMPL_ADDREF_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
 NS_IMPL_RELEASE_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
 
-ModuleLoadRequest::ModuleLoadRequest(nsIScriptElement* aElement,
+ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI,
+                                     nsIScriptElement* aElement,
                                      ValidJSVersion aValidJSVersion,
                                      CORSMode aCORSMode,
                                      const SRIMetadata& aIntegrity,
                                      ScriptLoader* aLoader)
   : ScriptLoadRequest(ScriptKind::Module,
+                      aURI,
                       aElement,
                       aValidJSVersion,
                       aCORSMode,
                       aIntegrity),
     mIsTopLevel(true),
-    mLoader(aLoader)
-{}
+    mLoader(aLoader),
+    mVisitedSet(new VisitedURLSet())
+{
+  mVisitedSet->PutEntry(aURI);
+}
+
+ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI,
+                                     ModuleLoadRequest* aParent)
+  : ScriptLoadRequest(ScriptKind::Module,
+                      aURI,
+                      aParent->mElement,
+                      aParent->mValidJSVersion,
+                      aParent->mCORSMode,
+                      aParent->mIntegrity),
+    mIsTopLevel(false),
+    mLoader(aParent->mLoader),
+    mVisitedSet(aParent->mVisitedSet)
+{
+  MOZ_ASSERT(mVisitedSet->Contains(aURI));
+
+  mTriggeringPrincipal = aParent->mTriggeringPrincipal;
+  mIsInline = false;
+  mReferrerPolicy = aParent->mReferrerPolicy;
+}
 
 void
 ModuleLoadRequest::Cancel()
 {
   ScriptLoadRequest::Cancel();
   mModuleScript = nullptr;
   mProgress = ScriptLoadRequest::Progress::Ready;
   CancelImports();
@@ -141,13 +164,12 @@ ModuleLoadRequest::LoadFailed()
 }
 
 void
 ModuleLoadRequest::LoadFinished()
 {
   mLoader->ProcessLoadedModuleTree(this);
 
   mLoader = nullptr;
-  mParent = nullptr;
 }
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/script/ModuleLoadRequest.h
+++ b/dom/script/ModuleLoadRequest.h
@@ -3,45 +3,62 @@
 /* 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 mozilla_dom_ModuleLoadRequest_h
 #define mozilla_dom_ModuleLoadRequest_h
 
 #include "ScriptLoadRequest.h"
+#include "nsURIHashKey.h"
 #include "mozilla/MozPromise.h"
 
 namespace mozilla {
 namespace dom {
 
 class ModuleScript;
 class ScriptLoader;
 
+// A reference counted set of URLs we have visited in the process of loading a
+// module graph.
+class VisitedURLSet : public nsTHashtable<nsURIHashKey>
+{
+  NS_INLINE_DECL_REFCOUNTING(VisitedURLSet)
+
+private:
+  ~VisitedURLSet() = default;
+};
+
 // A load request for a module, created for every top level module script and
 // every module import.  Load request can share an ModuleScript if there are
 // multiple imports of the same module.
 
 class ModuleLoadRequest final : public ScriptLoadRequest
 {
   ~ModuleLoadRequest() = default;
 
   ModuleLoadRequest(const ModuleLoadRequest& aOther) = delete;
   ModuleLoadRequest(ModuleLoadRequest&& aOther) = delete;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
 
-  ModuleLoadRequest(nsIScriptElement* aElement,
+  // Create a top-level module load request.
+  ModuleLoadRequest(nsIURI* aURI,
+                    nsIScriptElement* aElement,
                     ValidJSVersion aValidJSVersion,
                     CORSMode aCORSMode,
                     const SRIMetadata& aIntegrity,
                     ScriptLoader* aLoader);
 
+  // Create a module load request for an imported module.
+  ModuleLoadRequest(nsIURI* aURI,
+                    ModuleLoadRequest* aParent);
+
   bool IsTopLevel() const
   {
     return mIsTopLevel;
   }
 
   void SetReady() override;
   void Cancel() override;
 
@@ -51,38 +68,38 @@ public:
   void LoadFailed();
 
  private:
   void LoadFinished();
   void CancelImports();
 
  public:
   // Is this a request for a top level module script or an import?
-  bool mIsTopLevel;
+  const bool mIsTopLevel;
 
   // The base URL used for resolving relative module imports.
   nsCOMPtr<nsIURI> mBaseURL;
 
   // Pointer to the script loader, used to trigger actions when the module load
   // finishes.
   RefPtr<ScriptLoader> mLoader;
 
-  // The importing module, or nullptr for top level module scripts.  Used to
-  // implement the ancestor list checked when fetching module dependencies.
-  RefPtr<ModuleLoadRequest> mParent;
-
   // Set to a module script object after a successful load or nullptr on
   // failure.
   RefPtr<ModuleScript> mModuleScript;
 
   // A promise that is completed on successful load of this module and all of
   // its dependencies, indicating that the module is ready for instantiation and
   // evaluation.
   MozPromiseHolder<GenericPromise> mReady;
 
   // Array of imported modules.
   nsTArray<RefPtr<ModuleLoadRequest>> mImports;
+
+  // Set of module URLs visited while fetching the module graph this request is
+  // part of.
+  RefPtr<VisitedURLSet> mVisitedSet;
 };
 
 } // dom namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_ModuleLoadRequest_h
--- a/dom/script/ScriptLoadRequest.cpp
+++ b/dom/script/ScriptLoadRequest.cpp
@@ -34,16 +34,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheInfo)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadRequest)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScript)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 ScriptLoadRequest::ScriptLoadRequest(ScriptKind aKind,
+                                     nsIURI* aURI,
                                      nsIScriptElement* aElement,
                                      ValidJSVersion aValidJSVersion,
                                      mozilla::CORSMode aCORSMode,
                                      const mozilla::dom::SRIMetadata& aIntegrity)
   : mKind(aKind)
   , mElement(aElement)
   , mScriptFromHead(false)
   , mProgress(Progress::Loading)
@@ -59,16 +60,17 @@ ScriptLoadRequest::ScriptLoadRequest(Scr
   , mIsCanceled(false)
   , mWasCompiledOMT(false)
   , mIsTracking(false)
   , mOffThreadToken(nullptr)
   , mScriptText()
   , mScriptBytecode()
   , mBytecodeOffset(0)
   , mValidJSVersion(aValidJSVersion)
+  , mURI(aURI)
   , mLineNo(1)
   , mCORSMode(aCORSMode)
   , mIntegrity(aIntegrity)
   , mReferrerPolicy(mozilla::net::RP_Unset)
 {
 }
 
 ScriptLoadRequest::~ScriptLoadRequest()
--- a/dom/script/ScriptLoadRequest.h
+++ b/dom/script/ScriptLoadRequest.h
@@ -47,16 +47,17 @@ class ScriptLoadRequest : public nsISupp
   friend class mozilla::LinkedListElement<ScriptLoadRequest>;
   friend class ScriptLoadRequestList;
 
 protected:
   virtual ~ScriptLoadRequest();
 
 public:
   ScriptLoadRequest(ScriptKind aKind,
+                    nsIURI* aURI,
                     nsIScriptElement* aElement,
                     ValidJSVersion aValidJSVersion,
                     mozilla::CORSMode aCORSMode,
                     const mozilla::dom::SRIMetadata &aIntegrity);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ScriptLoadRequest)
 
@@ -181,17 +182,17 @@ public:
   mozilla::Vector<char16_t> mScriptText;
 
   // Holds the SRI serialized hash and the script bytecode for non-inline
   // scripts.
   mozilla::Vector<uint8_t> mScriptBytecode;
   uint32_t mBytecodeOffset; // Offset of the bytecode in mScriptBytecode
 
   ValidJSVersion mValidJSVersion;
-  nsCOMPtr<nsIURI> mURI;
+  const nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
   nsAutoCString mURL;     // Keep the URI's filename alive during off thread parsing.
   int32_t mLineNo;
   const mozilla::CORSMode mCORSMode;
   const mozilla::dom::SRIMetadata mIntegrity;
   mozilla::net::ReferrerPolicy mReferrerPolicy;
 
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -447,17 +447,17 @@ ScriptLoader::ProcessFetchedModuleSource
   if (!aRequest->mModuleScript->HasParseError()) {
     StartFetchingModuleDependencies(aRequest);
   }
 
   return NS_OK;
 }
 
 static nsresult
-ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>& aUrls);
+ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>* aUrlsOut);
 
 nsresult
 ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest)
 {
   MOZ_ASSERT(!aRequest->mModuleScript);
   MOZ_ASSERT(aRequest->mBaseURL);
 
   LOG(("ScriptLoadRequest (%p): Create module script", aRequest));
@@ -522,18 +522,17 @@ ScriptLoader::CreateModuleScript(ModuleL
       aRequest->ModuleErrored();
       return NS_OK;
     }
 
     moduleScript->SetModuleRecord(module);
 
     // Validate requested modules and treat failure to resolve module specifiers
     // the same as a parse error.
-    nsCOMArray<nsIURI> urls;
-    rv = ResolveRequestedModules(aRequest, urls);
+    rv = ResolveRequestedModules(aRequest, nullptr);
     if (NS_FAILED(rv)) {
       aRequest->ModuleErrored();
       return NS_OK;
     }
   }
 
   context->SetProcessingScriptTag(oldProcessingScriptTag);
 
@@ -607,43 +606,17 @@ ResolveModuleSpecifier(ModuleScript* aSc
   if (NS_SUCCEEDED(rv)) {
     return uri.forget();
   }
 
   return nullptr;
 }
 
 static nsresult
-RequestedModuleIsInAncestorList(ModuleLoadRequest* aRequest, nsIURI* aURL, bool* aResult)
-{
-  const size_t ImportDepthLimit = 100;
-
-  *aResult = false;
-  size_t depth = 0;
-  while (aRequest) {
-    if (depth++ == ImportDepthLimit) {
-      return NS_ERROR_FAILURE;
-    }
-
-    bool equal;
-    nsresult rv = aURL->Equals(aRequest->mURI, &equal);
-    NS_ENSURE_SUCCESS(rv, rv);
-    if (equal) {
-      *aResult = true;
-      return NS_OK;
-    }
-
-    aRequest = aRequest->mParent;
-  }
-
-  return NS_OK;
-}
-
-static nsresult
-ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>& aUrls)
+ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>* aUrlsOut)
 {
   ModuleScript* ms = aRequest->mModuleScript;
 
   AutoJSAPI jsapi;
   if (!jsapi.Init(ms->ModuleRecord())) {
     return NS_ERROR_FAILURE;
   }
 
@@ -679,103 +652,108 @@ ResolveRequestedModules(ModuleLoadReques
       uint32_t columnNumber = 0;
       JS::GetRequestedModuleSourcePos(cx, element, &lineNumber, &columnNumber);
 
       nsresult rv = HandleResolveFailure(cx, ms, specifier, lineNumber, columnNumber);
       NS_ENSURE_SUCCESS(rv, rv);
       return NS_ERROR_FAILURE;
     }
 
-    bool isAncestor;
-    nsresult rv = RequestedModuleIsInAncestorList(aRequest, uri, &isAncestor);
-    NS_ENSURE_SUCCESS(rv, rv);
-    if (!isAncestor) {
-      aUrls.AppendElement(uri.forget());
+    if (aUrlsOut) {
+      aUrlsOut->AppendElement(uri.forget());
     }
   }
 
   return NS_OK;
 }
 
 void
 ScriptLoader::StartFetchingModuleDependencies(ModuleLoadRequest* aRequest)
 {
+  LOG(("ScriptLoadRequest (%p): Start fetching module dependencies", aRequest));
+
   MOZ_ASSERT(aRequest->mModuleScript);
   MOZ_ASSERT(!aRequest->mModuleScript->HasParseError());
   MOZ_ASSERT(!aRequest->IsReadyToRun());
 
-  LOG(("ScriptLoadRequest (%p): Start fetching module dependencies", aRequest));
+  auto visitedSet = aRequest->mVisitedSet;
+  MOZ_ASSERT(visitedSet->Contains(aRequest->mURI));
 
   aRequest->mProgress = ModuleLoadRequest::Progress::FetchingImports;
 
   nsCOMArray<nsIURI> urls;
-  nsresult rv = ResolveRequestedModules(aRequest, urls);
+  nsresult rv = ResolveRequestedModules(aRequest, &urls);
   if (NS_FAILED(rv)) {
     aRequest->ModuleErrored();
     return;
   }
 
-  if (urls.Length() == 0) {
-    // There are no descendents to load so this request is ready.
+  // Remove already visited URLs from the list. Put unvisited URLs into the
+  // visited set.
+  int32_t i = 0;
+  while (i < urls.Count()) {
+    nsIURI* url = urls[i];
+    if (visitedSet->Contains(url)) {
+      urls.RemoveObjectAt(i);
+    } else {
+      visitedSet->PutEntry(url);
+      i++;
+    }
+  }
+
+  if (urls.Count() == 0) {
+    // There are no descendants to load so this request is ready.
     aRequest->DependenciesLoaded();
     return;
   }
 
   // For each url in urls, fetch a module script tree given url, module script's
   // CORS setting, and module script's settings object.
   nsTArray<RefPtr<GenericPromise>> importsReady;
-  for (size_t i = 0; i < urls.Length(); i++) {
+  for (auto url : urls) {
     RefPtr<GenericPromise> childReady =
-      StartFetchingModuleAndDependencies(aRequest, urls[i]);
+      StartFetchingModuleAndDependencies(aRequest, url);
     importsReady.AppendElement(childReady);
   }
 
   // Wait for all imports to become ready.
   RefPtr<GenericPromise::AllPromiseType> allReady =
     GenericPromise::All(GetMainThreadSerialEventTarget(), importsReady);
   allReady->Then(GetMainThreadSerialEventTarget(), __func__, aRequest,
                  &ModuleLoadRequest::DependenciesLoaded,
                  &ModuleLoadRequest::ModuleErrored);
 }
 
 RefPtr<GenericPromise>
-ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest,
+ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent,
                                                  nsIURI* aURI)
 {
   MOZ_ASSERT(aURI);
 
-  RefPtr<ModuleLoadRequest> childRequest =
-    new ModuleLoadRequest(aRequest->mElement, aRequest->mValidJSVersion,
-                            aRequest->mCORSMode, aRequest->mIntegrity, this);
-
-  childRequest->mIsTopLevel = false;
-  childRequest->mURI = aURI;
-  childRequest->mTriggeringPrincipal = aRequest->mTriggeringPrincipal;
-  childRequest->mIsInline = false;
-  childRequest->mReferrerPolicy = aRequest->mReferrerPolicy;
-  childRequest->mParent = aRequest;
-  aRequest->mImports.AppendElement(childRequest);
+  RefPtr<ModuleLoadRequest> childRequest = new ModuleLoadRequest(aURI, aParent);
+
+  aParent->mImports.AppendElement(childRequest);
 
   if (LOG_ENABLED()) {
     nsAutoCString url1;
-    aRequest->mURI->GetAsciiSpec(url1);
+    aParent->mURI->GetAsciiSpec(url1);
 
     nsAutoCString url2;
     aURI->GetAsciiSpec(url2);
 
-    LOG(("ScriptLoadRequest (%p): Start fetching dependency %p", aRequest, childRequest.get()));
+    LOG(("ScriptLoadRequest (%p): Start fetching dependency %p", aParent, childRequest.get()));
     LOG(("StartFetchingModuleAndDependencies \"%s\" -> \"%s\"", url1.get(), url2.get()));
   }
 
   RefPtr<GenericPromise> ready = childRequest->mReady.Ensure(__func__);
 
   nsresult rv = StartLoad(childRequest);
   if (NS_FAILED(rv)) {
     MOZ_ASSERT(!childRequest->mModuleScript);
-    LOG(("ScriptLoadRequest (%p):   rejecting %p", aRequest, &childRequest->mReady));
+    LOG(("ScriptLoadRequest (%p):   rejecting %p", aParent, &childRequest->mReady));
     childRequest->mReady.Reject(rv, __func__);
     return ready;
   }
 
   return ready;
 }
 
 // 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
@@ -1276,32 +1254,32 @@ CSPAllowsInlineScript(nsIScriptElement* 
                             nonce, parserCreated, aElement,
                             aElement->GetScriptLineNumber(),
                             &allowInlineScript);
   return allowInlineScript;
 }
 
 ScriptLoadRequest*
 ScriptLoader::CreateLoadRequest(ScriptKind aKind,
+                                nsIURI* aURI,
                                 nsIScriptElement* aElement,
                                 ValidJSVersion aValidJSVersion,
                                 CORSMode aCORSMode,
                                 const SRIMetadata& aIntegrity)
 {
   if (aKind == ScriptKind::Classic) {
-    ScriptLoadRequest* slr = new ScriptLoadRequest(aKind, aElement,
-                                 aValidJSVersion, aCORSMode,
-                                 aIntegrity);
+    ScriptLoadRequest* slr = new ScriptLoadRequest(aKind, aURI, aElement,
+                                 aValidJSVersion, aCORSMode, aIntegrity);
 
     LOG(("ScriptLoader %p creates ScriptLoadRequest %p", this, slr));
     return slr;
   }
 
   MOZ_ASSERT(aKind == ScriptKind::Module);
-  return new ModuleLoadRequest(aElement, aValidJSVersion, aCORSMode,
+  return new ModuleLoadRequest(aURI, aElement, aValidJSVersion, aCORSMode,
                                aIntegrity, this);
 }
 
 bool
 ScriptLoader::ProcessScriptElement(nsIScriptElement* aElement)
 {
   // We need a document to evaluate scripts.
   NS_ENSURE_TRUE(mDocument, false);
@@ -1430,19 +1408,18 @@ ScriptLoader::ProcessScriptElement(nsISc
         }
       }
 
       nsCOMPtr<nsIPrincipal> principal = aElement->GetScriptURITriggeringPrincipal();
       if (!principal) {
         principal = scriptContent->NodePrincipal();
       }
 
-      request = CreateLoadRequest(scriptKind, aElement, validJSVersion, ourCORSMode,
-                                  sriMetadata);
-      request->mURI = scriptURI;
+      request = CreateLoadRequest(scriptKind, scriptURI, aElement,
+                                  validJSVersion, ourCORSMode, sriMetadata);
       request->mTriggeringPrincipal = Move(principal);
       request->mIsInline = false;
       request->mReferrerPolicy = ourRefPolicy;
       // keep request->mScriptFromHead to false so we don't treat non preloaded
       // scripts as blockers for full page load. See bug 792438.
 
       rv = StartLoad(request);
       if (NS_FAILED(rv)) {
@@ -1573,21 +1550,21 @@ ScriptLoader::ProcessScriptElement(nsISc
   }
 
   // Does CSP allow this inline script to run?
   if (!CSPAllowsInlineScript(aElement, mDocument)) {
     return false;
   }
 
   // Inline scripts ignore ther CORS mode and are always CORS_NONE
-  request = CreateLoadRequest(scriptKind, aElement, validJSVersion, CORS_NONE,
+  request = CreateLoadRequest(scriptKind, mDocument->GetDocumentURI(), aElement,
+                              validJSVersion, CORS_NONE,
                               SRIMetadata()); // SRI doesn't apply
   request->mValidJSVersion = validJSVersion;
   request->mIsInline = true;
-  request->mURI = mDocument->GetDocumentURI();
   request->mTriggeringPrincipal = mDocument->NodePrincipal();
   request->mLineNo = aElement->GetScriptLineNumber();
   request->mProgress = ScriptLoadRequest::Progress::Loading_Source;
   request->mDataType = ScriptLoadRequest::DataType::Source;
   TRACE_FOR_TEST_BOOL(request->mElement, "scriptloader_load_source");
   CollectScriptTelemetry(nullptr, request);
 
   LOG(("ScriptLoadRequest (%p): Created request for inline script",
@@ -3162,19 +3139,18 @@ ScriptLoader::PreloadURI(nsIURI* aURI, c
     nsAutoCString sourceUri;
     if (mDocument->GetDocumentURI()) {
       mDocument->GetDocumentURI()->GetAsciiSpec(sourceUri);
     }
     SRICheck::IntegrityMetadata(aIntegrity, sourceUri, mReporter, &sriMetadata);
   }
 
   RefPtr<ScriptLoadRequest> request =
-    CreateLoadRequest(ScriptKind::Classic, nullptr, ValidJSVersion::Valid,
+    CreateLoadRequest(ScriptKind::Classic, aURI, nullptr, ValidJSVersion::Valid,
                       Element::StringToCORSMode(aCrossOrigin), sriMetadata);
-  request->mURI = aURI;
   request->mTriggeringPrincipal = mDocument->NodePrincipal();
   request->mIsInline = false;
   request->mReferrerPolicy = aReferrerPolicy;
   request->mScriptFromHead = aScriptFromHead;
   request->mPreloadAsAsync = aAsync;
   request->mPreloadAsDefer = aDefer;
 
   nsresult rv = StartLoad(request);
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -335,16 +335,17 @@ public:
   {
     GiveUpBytecodeEncoding();
   }
 
 private:
   virtual ~ScriptLoader();
 
   ScriptLoadRequest* CreateLoadRequest(ScriptKind aKind,
+                                       nsIURI* aURI,
                                        nsIScriptElement* aElement,
                                        ValidJSVersion aValidJSVersion,
                                        mozilla::CORSMode aCORSMode,
                                        const mozilla::dom::SRIMetadata& aIntegrity);
 
   /**
    * Unblocks the creator parser of the parser-blocking scripts.
    */
@@ -487,17 +488,17 @@ private:
   nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
   void CheckModuleDependenciesLoaded(ModuleLoadRequest* aRequest);
   void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest);
   bool InstantiateModuleTree(ModuleLoadRequest* aRequest);
   JS::Value FindFirstParseError(ModuleLoadRequest* aRequest);
   void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest);
 
   RefPtr<mozilla::GenericPromise>
-  StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, nsIURI* aURI);
+  StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent, nsIURI* aURI);
 
   nsIDocument* mDocument;                   // [WEAK]
   nsCOMArray<nsIScriptLoaderObserver> mObservers;
   ScriptLoadRequestList mNonAsyncExternalScriptInsertedRequests;
   // mLoadingAsyncRequests holds async requests while they're loading; when they
   // have been loaded they are moved to mLoadedAsyncRequests.
   ScriptLoadRequestList mLoadingAsyncRequests;
   ScriptLoadRequestList mLoadedAsyncRequests;