Backed out changeset a8abdd77a92c (bug 1362119)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 08 May 2017 09:54:08 +0200
changeset 357081 0a935b38ef4550c6e050fea1f6f641be8807a2bc
parent 357080 c440a4d4cc6c7b8e78b48efd42c3b16b925ecf7c
child 357082 62680dc80fb74c2809059b9013b07e10ba679e1b
push id31782
push userkwierso@gmail.com
push dateMon, 08 May 2017 23:07:35 +0000
treeherdermozilla-central@b21b974d60d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1362119
milestone55.0a1
backs outa8abdd77a92c38aef9e9fcaee013bab5618e96ac
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
Backed out changeset a8abdd77a92c (bug 1362119)
dom/script/ModuleLoadRequest.cpp
dom/script/ModuleLoadRequest.h
dom/script/ModuleScript.cpp
dom/script/ModuleScript.h
dom/script/ScriptLoadHandler.cpp
dom/script/ScriptLoadHandler.h
dom/script/ScriptLoadRequest.cpp
dom/script/ScriptLoadRequest.h
dom/script/ScriptLoader.cpp
dom/script/ScriptLoader.h
dom/script/ScriptTrace.cpp
dom/script/ScriptTrace.h
dom/script/moz.build
deleted file mode 100644
--- a/dom/script/ModuleLoadRequest.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- 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 "ModuleLoadRequest.h"
-#include "ModuleScript.h"
-#include "ScriptLoader.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(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,
-                                     uint32_t aVersion,
-                                     CORSMode aCORSMode,
-                                     const SRIMetadata &aIntegrity,
-                                     ScriptLoader* aLoader)
-  : ScriptLoadRequest(ScriptKind::Module,
-                      aElement,
-                      aVersion,
-                      aCORSMode,
-                      aIntegrity),
-    mIsTopLevel(true),
-    mLoader(aLoader)
-{}
-
-void
-ModuleLoadRequest::Cancel()
-{
-  ScriptLoadRequest::Cancel();
-  mModuleScript = nullptr;
-  mProgress = ScriptLoadRequest::Progress::Ready;
-  for (size_t i = 0; i < mImports.Length(); i++) {
-    mImports[i]->Cancel();
-  }
-  mReady.RejectIfExists(NS_ERROR_FAILURE, __func__);
-}
-
-void
-ModuleLoadRequest::SetReady()
-{
-#ifdef DEBUG
-  for (size_t i = 0; i < mImports.Length(); i++) {
-    MOZ_ASSERT(mImports[i]->IsReadyToRun());
-  }
-#endif
-
-  ScriptLoadRequest::SetReady();
-  mReady.ResolveIfExists(true, __func__);
-}
-
-void
-ModuleLoadRequest::ModuleLoaded()
-{
-  // A module that was found to be marked as fetching in the module map has now
-  // been loaded.
-
-  mModuleScript = mLoader->GetFetchedModule(mURI);
-  mLoader->StartFetchingModuleDependencies(this);
-}
-
-void
-ModuleLoadRequest::DependenciesLoaded()
-{
-  // The module and all of its dependencies have been successfully fetched and
-  // compiled.
-
-  if (!mLoader->InstantiateModuleTree(this)) {
-    LoadFailed();
-    return;
-  }
-
-  SetReady();
-  mLoader->ProcessLoadedModuleTree(this);
-  mLoader = nullptr;
-  mParent = nullptr;
-}
-
-void
-ModuleLoadRequest::LoadFailed()
-{
-  Cancel();
-  mLoader->ProcessLoadedModuleTree(this);
-  mLoader = nullptr;
-  mParent = nullptr;
-}
-
-} // dom namespace
-} // mozilla namespace
deleted file mode 100644
--- a/dom/script/ModuleLoadRequest.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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 mozilla_dom_ModuleLoadRequest_h
-#define mozilla_dom_ModuleLoadRequest_h
-
-#include "ScriptLoadRequest.h"
-#include "mozilla/MozPromise.h"
-
-namespace mozilla {
-namespace dom {
-
-class ModuleScript;
-class ScriptLoader;
-
-// 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,
-                    uint32_t aVersion,
-                    CORSMode aCORSMode,
-                    const SRIMetadata& aIntegrity,
-                    ScriptLoader* aLoader);
-
-  bool IsTopLevel() const {
-    return mIsTopLevel;
-  }
-
-  void SetReady() override;
-  void Cancel() override;
-
-  void ModuleLoaded();
-  void DependenciesLoaded();
-  void LoadFailed();
-
-  // Is this a request for a top level module script or an import?
-  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;
-};
-
-} // dom namespace
-} // mozilla namespace
-
-#endif // mozilla_dom_ModuleLoadRequest_h
deleted file mode 100644
--- a/dom/script/ModuleScript.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- 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 "ModuleScript.h"
-#include "mozilla/HoldDropJSObjects.h"
-#include "ScriptLoader.h"
-
-namespace mozilla {
-namespace dom {
-
-// A single module script.  May be used to satisfy multiple load requests.
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ModuleScript)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleScript)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ModuleScript)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL)
-  tmp->UnlinkModuleRecord();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ModuleScript)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ModuleScript)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRecord)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mException)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(ModuleScript)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(ModuleScript)
-
-ModuleScript::ModuleScript(ScriptLoader *aLoader, nsIURI* aBaseURL,
-                           JS::Handle<JSObject*> aModuleRecord)
- : mLoader(aLoader),
-   mBaseURL(aBaseURL),
-   mModuleRecord(aModuleRecord),
-   mInstantiationState(Uninstantiated)
-{
-  MOZ_ASSERT(mLoader);
-  MOZ_ASSERT(mBaseURL);
-  MOZ_ASSERT(mModuleRecord);
-  MOZ_ASSERT(mException.isUndefined());
-
-  // Make module's host defined field point to this module script object.
-  // This is cleared in the UnlinkModuleRecord().
-  JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this));
-  HoldJSObjects(this);
-}
-
-void
-ModuleScript::UnlinkModuleRecord()
-{
-  // Remove module's back reference to this object request if present.
-  if (mModuleRecord) {
-    MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() ==
-               this);
-    JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue());
-  }
-  mModuleRecord = nullptr;
-  mException.setUndefined();
-}
-
-ModuleScript::~ModuleScript()
-{
-  if (mModuleRecord) {
-    // The object may be destroyed without being unlinked first.
-    UnlinkModuleRecord();
-  }
-  DropJSObjects(this);
-}
-
-void
-ModuleScript::SetInstantiationResult(JS::Handle<JS::Value> aMaybeException)
-{
-  MOZ_ASSERT(mInstantiationState == Uninstantiated);
-  MOZ_ASSERT(mModuleRecord);
-  MOZ_ASSERT(mException.isUndefined());
-
-  if (aMaybeException.isUndefined()) {
-    mInstantiationState = Instantiated;
-  } else {
-    mModuleRecord = nullptr;
-    mException = aMaybeException;
-    mInstantiationState = Errored;
-  }
-}
-
-} // dom namespace
-} // mozilla namespace
deleted file mode 100644
--- a/dom/script/ModuleScript.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- 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 mozilla_dom_ModuleScript_h
-#define mozilla_dom_ModuleScript_h
-
-#include "nsCOMPtr.h"
-#include "nsCycleCollectionParticipant.h"
-#include "jsapi.h"
-
-class nsIURI;
-
-namespace mozilla {
-namespace dom {
-
-class ScriptLoader;
-
-class ModuleScript final : public nsISupports
-{
-  enum InstantiationState {
-    Uninstantiated,
-    Instantiated,
-    Errored
-  };
-
-  RefPtr<ScriptLoader> mLoader;
-  nsCOMPtr<nsIURI> mBaseURL;
-  JS::Heap<JSObject*> mModuleRecord;
-  JS::Heap<JS::Value> mException;
-  InstantiationState mInstantiationState;
-
-  ~ModuleScript();
-
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ModuleScript)
-
-  ModuleScript(ScriptLoader* aLoader,
-               nsIURI* aBaseURL,
-               JS::Handle<JSObject*> aModuleRecord);
-
-  ScriptLoader* Loader() const { return mLoader; }
-  JSObject* ModuleRecord() const { return mModuleRecord; }
-  JS::Value Exception() const { return mException; }
-  nsIURI* BaseURL() const { return mBaseURL; }
-
-  void SetInstantiationResult(JS::Handle<JS::Value> aMaybeException);
-  bool IsUninstantiated() const {
-    return mInstantiationState == Uninstantiated;
-  }
-  bool IsInstantiated() const {
-    return mInstantiationState == Instantiated;
-  }
-  bool InstantiationFailed() const {
-    return mInstantiationState == Errored;
-  }
-
-  void UnlinkModuleRecord();
-};
-
-} // dom namespace
-} // mozilla namespace
-
-#endif // mozilla_dom_ModuleScript_h
deleted file mode 100644
--- a/dom/script/ScriptLoadHandler.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/* -*- 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 "ScriptLoadHandler.h"
-#include "ScriptLoader.h"
-#include "ScriptTrace.h"
-
-#include "mozilla/dom/EncodingUtils.h"
-#include "mozilla/Telemetry.h"
-
-namespace mozilla {
-namespace dom {
-
-#undef LOG
-#define LOG(args) \
-  MOZ_LOG(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug, args)
-
-#define LOG_ENABLED() \
-  MOZ_LOG_TEST(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug)
-
-ScriptLoadHandler::ScriptLoadHandler(ScriptLoader *aScriptLoader,
-                                     ScriptLoadRequest *aRequest,
-                                     mozilla::dom::SRICheckDataVerifier *aSRIDataVerifier)
-  : mScriptLoader(aScriptLoader),
-    mRequest(aRequest),
-    mSRIDataVerifier(aSRIDataVerifier),
-    mSRIStatus(NS_OK),
-    mDecoder()
-{
-  MOZ_ASSERT(mRequest->IsUnknownDataType());
-  MOZ_ASSERT(mRequest->IsLoading());
-}
-
-ScriptLoadHandler::~ScriptLoadHandler()
-{}
-
-NS_IMPL_ISUPPORTS(ScriptLoadHandler, nsIIncrementalStreamLoaderObserver)
-
-NS_IMETHODIMP
-ScriptLoadHandler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
-                                     nsISupports* aContext,
-                                     uint32_t aDataLength,
-                                     const uint8_t* aData,
-                                     uint32_t *aConsumedLength)
-{
-  if (mRequest->IsCanceled()) {
-    // If request cancelled, ignore any incoming data.
-    *aConsumedLength = aDataLength;
-    return NS_OK;
-  }
-
-  nsresult rv = NS_OK;
-  if (mRequest->IsUnknownDataType()) {
-    rv = EnsureKnownDataType(aLoader);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if (mRequest->IsSource()) {
-    if (!EnsureDecoder(aLoader, aData, aDataLength,
-                       /* aEndOfStream = */ false)) {
-      return NS_OK;
-    }
-
-    // Below we will/shall consume entire data chunk.
-    *aConsumedLength = aDataLength;
-
-    // Decoder has already been initialized. -- trying to decode all loaded bytes.
-    rv = DecodeRawData(aData, aDataLength, /* aEndOfStream = */ false);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // If SRI is required for this load, appending new bytes to the hash.
-    if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
-      mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
-    }
-  } else {
-    MOZ_ASSERT(mRequest->IsBytecode());
-    if (!mRequest->mScriptBytecode.append(aData, aDataLength)) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    *aConsumedLength = aDataLength;
-    rv = MaybeDecodeSRI();
-    if (NS_FAILED(rv)) {
-      nsCOMPtr<nsIRequest> channelRequest;
-      aLoader->GetRequest(getter_AddRefs(channelRequest));
-      return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
-    }
-  }
-
-  return rv;
-}
-
-nsresult
-ScriptLoadHandler::DecodeRawData(const uint8_t* aData,
-                                 uint32_t aDataLength,
-                                 bool aEndOfStream)
-{
-  int32_t srcLen = aDataLength;
-  const char* src = reinterpret_cast<const char *>(aData);
-  int32_t dstLen;
-  nsresult rv =
-    mDecoder->GetMaxLength(src, srcLen, &dstLen);
-
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  uint32_t haveRead = mRequest->mScriptText.length();
-
-  CheckedInt<uint32_t> capacity = haveRead;
-  capacity += dstLen;
-
-  if (!capacity.isValid() || !mRequest->mScriptText.reserve(capacity.value())) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  rv = mDecoder->Convert(src,
-                         &srcLen,
-                         mRequest->mScriptText.begin() + haveRead,
-                         &dstLen);
-
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  haveRead += dstLen;
-  MOZ_ASSERT(haveRead <= capacity.value(), "mDecoder produced more data than expected");
-  MOZ_ALWAYS_TRUE(mRequest->mScriptText.resizeUninitialized(haveRead));
-
-  return NS_OK;
-}
-
-bool
-ScriptLoadHandler::EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
-                                 const uint8_t* aData,
-                                 uint32_t aDataLength,
-                                 bool aEndOfStream)
-{
-  // Check if decoder has already been created.
-  if (mDecoder) {
-    return true;
-  }
-
-  nsAutoCString charset;
-  if (!EnsureDecoder(aLoader, aData, aDataLength, aEndOfStream, charset)) {
-    return false;
-  }
-  if (charset.Length() == 0) {
-    charset = "?";
-  }
-  mozilla::Telemetry::Accumulate(mozilla::Telemetry::DOM_SCRIPT_SRC_ENCODING,
-    charset);
-  return true;
-}
-
-bool
-ScriptLoadHandler::EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
-                                 const uint8_t* aData,
-                                 uint32_t aDataLength,
-                                 bool aEndOfStream,
-                                 nsCString& oCharset)
-{
-  // JavaScript modules are always UTF-8.
-  if (mRequest->IsModuleRequest()) {
-    oCharset = "UTF-8";
-    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
-    return true;
-  }
-
-  // Determine if BOM check should be done.  This occurs either
-  // if end-of-stream has been reached, or at least 3 bytes have
-  // been read from input.
-  if (!aEndOfStream && (aDataLength < 3)) {
-    return false;
-  }
-
-  // Do BOM detection.
-  if (nsContentUtils::CheckForBOM(aData, aDataLength, oCharset)) {
-    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
-    return true;
-  }
-
-  // BOM detection failed, check content stream for charset.
-  nsCOMPtr<nsIRequest> req;
-  nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
-  NS_ASSERTION(req, "StreamLoader's request went away prematurely");
-  NS_ENSURE_SUCCESS(rv, false);
-
-  nsCOMPtr<nsIChannel> channel = do_QueryInterface(req);
-
-  if (channel &&
-      NS_SUCCEEDED(channel->GetContentCharset(oCharset)) &&
-      EncodingUtils::FindEncodingForLabel(oCharset, oCharset)) {
-    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
-    return true;
-  }
-
-  // Check the hint charset from the script element or preload
-  // request.
-  nsAutoString hintCharset;
-  if (!mRequest->IsPreload()) {
-    mRequest->mElement->GetScriptCharset(hintCharset);
-  } else {
-    nsTArray<ScriptLoader::PreloadInfo>::index_type i =
-      mScriptLoader->mPreloads.IndexOf(mRequest, 0,
-            ScriptLoader::PreloadRequestComparator());
-
-    NS_ASSERTION(i != mScriptLoader->mPreloads.NoIndex,
-                 "Incorrect preload bookkeeping");
-    hintCharset = mScriptLoader->mPreloads[i].mCharset;
-  }
-
-  if (EncodingUtils::FindEncodingForLabel(hintCharset, oCharset)) {
-    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
-    return true;
-  }
-
-  // Get the charset from the charset of the document.
-  if (mScriptLoader->mDocument) {
-    oCharset = mScriptLoader->mDocument->GetDocumentCharacterSet();
-    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
-    return true;
-  }
-
-  // Curiously, there are various callers that don't pass aDocument. The
-  // fallback in the old code was ISO-8859-1, which behaved like
-  // windows-1252. Saying windows-1252 for clarity and for compliance
-  // with the Encoding Standard.
-  oCharset = "windows-1252";
-  mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
-
-  return true;
-}
-
-nsresult
-ScriptLoadHandler::MaybeDecodeSRI()
-{
-  if (!mSRIDataVerifier || mSRIDataVerifier->IsComplete() || NS_FAILED(mSRIStatus)) {
-    return NS_OK;
-  }
-
-  // Skip until the content is large enough to be decoded.
-  if (mRequest->mScriptBytecode.length() <= mSRIDataVerifier->DataSummaryLength()) {
-    return NS_OK;
-  }
-
-  mSRIStatus = mSRIDataVerifier->ImportDataSummary(
-    mRequest->mScriptBytecode.length(), mRequest->mScriptBytecode.begin());
-
-  if (NS_FAILED(mSRIStatus)) {
-    // We are unable to decode the hash contained in the alternate data which
-    // contains the bytecode, or it does not use the same algorithm.
-    LOG(("ScriptLoadHandler::MaybeDecodeSRI, failed to decode SRI, restart request"));
-    return mSRIStatus;
-  }
-
-  mRequest->mBytecodeOffset = mSRIDataVerifier->DataSummaryLength();
-  return NS_OK;
-}
-
-nsresult
-ScriptLoadHandler::EnsureKnownDataType(nsIIncrementalStreamLoader *aLoader)
-{
-  MOZ_ASSERT(mRequest->IsUnknownDataType());
-  MOZ_ASSERT(mRequest->IsLoading());
-  if (mRequest->IsLoadingSource()) {
-    mRequest->mDataType = ScriptLoadRequest::DataType::Source;
-    TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIRequest> req;
-  nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
-  MOZ_ASSERT(req, "StreamLoader's request went away prematurely");
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsICacheInfoChannel> cic(do_QueryInterface(req));
-  if (cic) {
-    nsAutoCString altDataType;
-    cic->GetAlternativeDataType(altDataType);
-    if (altDataType.EqualsLiteral("javascript/moz-bytecode-" NS_STRINGIFY(MOZ_BUILDID))) {
-      mRequest->mDataType = ScriptLoadRequest::DataType::Bytecode;
-      TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_bytecode");
-    } else {
-      mRequest->mDataType = ScriptLoadRequest::DataType::Source;
-      TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
-    }
-  } else {
-    mRequest->mDataType = ScriptLoadRequest::DataType::Source;
-    TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
-  }
-  MOZ_ASSERT(!mRequest->IsUnknownDataType());
-  MOZ_ASSERT(mRequest->IsLoading());
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
-                                    nsISupports* aContext,
-                                    nsresult aStatus,
-                                    uint32_t aDataLength,
-                                    const uint8_t* aData)
-{
-  nsresult rv = NS_OK;
-  if (LOG_ENABLED()) {
-    nsAutoCString url;
-    mRequest->mURI->GetAsciiSpec(url);
-    LOG(("ScriptLoadRequest (%p): Stream complete (url = %s)",
-         mRequest.get(), url.get()));
-  }
-
-  nsCOMPtr<nsIRequest> channelRequest;
-  aLoader->GetRequest(getter_AddRefs(channelRequest));
-
-  if (!mRequest->IsCanceled()) {
-    if (mRequest->IsUnknownDataType()) {
-      rv = EnsureKnownDataType(aLoader);
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    if (mRequest->IsSource()) {
-      DebugOnly<bool> encoderSet =
-        EnsureDecoder(aLoader, aData, aDataLength, /* aEndOfStream = */ true);
-      MOZ_ASSERT(encoderSet);
-      rv = DecodeRawData(aData, aDataLength, /* aEndOfStream = */ true);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      LOG(("ScriptLoadRequest (%p): Source length = %u",
-           mRequest.get(), unsigned(mRequest->mScriptText.length())));
-
-      // If SRI is required for this load, appending new bytes to the hash.
-      if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
-        mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
-      }
-    } else {
-      MOZ_ASSERT(mRequest->IsBytecode());
-      if (!mRequest->mScriptBytecode.append(aData, aDataLength)) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      LOG(("ScriptLoadRequest (%p): Bytecode length = %u",
-           mRequest.get(), unsigned(mRequest->mScriptBytecode.length())));
-
-      // If we abort while decoding the SRI, we fallback on explictly requesting
-      // the source. Thus, we should not continue in
-      // ScriptLoader::OnStreamComplete, which removes the request from the
-      // waiting lists.
-      rv = MaybeDecodeSRI();
-      if (NS_FAILED(rv)) {
-        return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
-      }
-
-      // The bytecode cache always starts with the SRI hash, thus even if there
-      // is no SRI data verifier instance, we still want to skip the hash.
-      rv = SRICheckDataVerifier::DataSummaryLength(mRequest->mScriptBytecode.length(),
-                                                   mRequest->mScriptBytecode.begin(),
-                                                   &mRequest->mBytecodeOffset);
-      if (NS_FAILED(rv)) {
-        return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
-      }
-    }
-  }
-
-  // Everything went well, keep the CacheInfoChannel alive such that we can
-  // later save the bytecode on the cache entry.
-  if (NS_SUCCEEDED(rv) && mRequest->IsSource() &&
-      ScriptLoader::IsBytecodeCacheEnabled()) {
-    mRequest->mCacheInfo = do_QueryInterface(channelRequest);
-    LOG(("ScriptLoadRequest (%p): nsICacheInfoChannel = %p",
-         mRequest.get(), mRequest->mCacheInfo.get()));
-  }
-
-  // we have to mediate and use mRequest.
-  rv = mScriptLoader->OnStreamComplete(aLoader, mRequest, aStatus, mSRIStatus,
-                                       mSRIDataVerifier);
-
-  // In case of failure, clear the mCacheInfoChannel to avoid keeping it alive.
-  if (NS_FAILED(rv)) {
-    mRequest->mCacheInfo = nullptr;
-  }
-
-  return rv;
-}
-
-#undef LOG_ENABLED
-#undef LOG
-
-} // dom namespace
-} // mozilla namespace
deleted file mode 100644
--- a/dom/script/ScriptLoadHandler.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- 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/. */
-
-/*
- * A class that handles loading and evaluation of <script> elements.
- */
-
-#ifndef mozilla_dom_ScriptLoadHandler_h
-#define mozilla_dom_ScriptLoadHandler_h
-
-#include "nsIIncrementalStreamLoader.h"
-
-namespace mozilla {
-namespace dom {
-
-class ScriptLoadRequest;
-class ScriptLoader;
-class SRICheckDataVerifier;
-
-class ScriptLoadHandler final : public nsIIncrementalStreamLoaderObserver
-{
-public:
-  explicit ScriptLoadHandler(ScriptLoader* aScriptLoader,
-                             ScriptLoadRequest* aRequest,
-                             SRICheckDataVerifier* aSRIDataVerifier);
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER
-
-private:
-  virtual ~ScriptLoadHandler();
-
-  /*
-   * Once the charset is found by the EnsureDecoder function, we can
-   * incrementally convert the charset to the one expected by the JS Parser.
-   */
-  nsresult DecodeRawData(const uint8_t* aData, uint32_t aDataLength,
-                         bool aEndOfStream);
-
-  /*
-   * Discover the charset by looking at the stream data, the script
-   * tag, and other indicators.  Returns true if charset has been
-   * discovered.
-   */
-  bool EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
-                     const uint8_t* aData, uint32_t aDataLength,
-                     bool aEndOfStream);
-  bool EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
-                     const uint8_t* aData, uint32_t aDataLength,
-                     bool aEndOfStream, nsCString& oCharset);
-
-  /*
-   * When streaming bytecode, we have the opportunity to fallback early if SRI
-   * does not match the expectation of the document.
-   */
-  nsresult MaybeDecodeSRI();
-
-  // Query the channel to find the data type associated with the input stream.
-  nsresult EnsureKnownDataType(nsIIncrementalStreamLoader *aLoader);
-
-  // ScriptLoader which will handle the parsed script.
-  RefPtr<ScriptLoader>        mScriptLoader;
-
-  // The ScriptLoadRequest for this load. Decoded data are accumulated on it.
-  RefPtr<ScriptLoadRequest>   mRequest;
-
-  // SRI data verifier.
-  nsAutoPtr<SRICheckDataVerifier> mSRIDataVerifier;
-
-  // Status of SRI data operations.
-  nsresult                      mSRIStatus;
-
-  // Unicode decoder for charset.
-  nsCOMPtr<nsIUnicodeDecoder>   mDecoder;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_ScriptLoadHandler_h
deleted file mode 100644
--- a/dom/script/ScriptLoadRequest.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- 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 "ModuleLoadRequest.h"
-#include "mozilla/HoldDropJSObjects.h"
-#include "nsICacheInfoChannel.h"
-#include "ScriptLoadRequest.h"
-#include "ScriptSettings.h"
-
-namespace mozilla {
-namespace dom {
-
-//////////////////////////////////////////////////////////////
-// ScriptLoadRequest
-//////////////////////////////////////////////////////////////
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptLoadRequest)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoadRequest)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadRequest)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheInfo)
-  tmp->DropBytecodeCacheReferences();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest)
-  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,
-                                     nsIScriptElement* aElement,
-                                     uint32_t aVersion,
-                                     mozilla::CORSMode aCORSMode,
-                                     const mozilla::dom::SRIMetadata &aIntegrity)
-  : mKind(aKind)
-  , mElement(aElement)
-  , mScriptFromHead(false)
-  , mProgress(Progress::Loading)
-  , mDataType(DataType::Unknown)
-  , mIsInline(true)
-  , mHasSourceMapURL(false)
-  , mIsDefer(false)
-  , mIsAsync(false)
-  , mIsNonAsyncScriptInserted(false)
-  , mIsXSLT(false)
-  , mIsCanceled(false)
-  , mWasCompiledOMT(false)
-  , mIsTracking(false)
-  , mOffThreadToken(nullptr)
-  , mScriptText()
-  , mScriptBytecode()
-  , mBytecodeOffset(0)
-  , mJSVersion(aVersion)
-  , mLineNo(1)
-  , mCORSMode(aCORSMode)
-  , mIntegrity(aIntegrity)
-  , mReferrerPolicy(mozilla::net::RP_Unset)
-{
-}
-
-ScriptLoadRequest::~ScriptLoadRequest()
-{
-  // We should always clean up any off-thread script parsing resources.
-  MOZ_ASSERT(!mOffThreadToken);
-
-  // But play it safe in release builds and try to clean them up here
-  // as a fail safe.
-  MaybeCancelOffThreadScript();
-
-  if (mScript) {
-    DropBytecodeCacheReferences();
-  }
-}
-
-void
-ScriptLoadRequest::SetReady()
-{
-  MOZ_ASSERT(mProgress != Progress::Ready);
-  mProgress = Progress::Ready;
-}
-
-void
-ScriptLoadRequest::Cancel()
-{
-  MaybeCancelOffThreadScript();
-  mIsCanceled = true;
-}
-
-void
-ScriptLoadRequest::MaybeCancelOffThreadScript()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!mOffThreadToken) {
-    return;
-  }
-
-  JSContext* cx = danger::GetJSContext();
-  // Follow the same conditions as ScriptLoader::AttemptAsyncScriptCompile
-  if (IsModuleRequest()) {
-    JS::CancelOffThreadModule(cx, mOffThreadToken);
-  } else if (IsSource()) {
-    JS::CancelOffThreadScript(cx, mOffThreadToken);
-  } else {
-    MOZ_ASSERT(IsBytecode());
-    JS::CancelOffThreadScriptDecoder(cx, mOffThreadToken);
-  }
-  mOffThreadToken = nullptr;
-}
-
-void
-ScriptLoadRequest::DropBytecodeCacheReferences()
-{
-  mCacheInfo = nullptr;
-  mScript = nullptr;
-  DropJSObjects(this);
-}
-
-inline ModuleLoadRequest*
-ScriptLoadRequest::AsModuleRequest()
-{
-  MOZ_ASSERT(IsModuleRequest());
-  return static_cast<ModuleLoadRequest*>(this);
-}
-
-//////////////////////////////////////////////////////////////
-// ScriptLoadRequestList
-//////////////////////////////////////////////////////////////
-
-ScriptLoadRequestList::~ScriptLoadRequestList()
-{
-  Clear();
-}
-
-void
-ScriptLoadRequestList::Clear()
-{
-  while (!isEmpty()) {
-    RefPtr<ScriptLoadRequest> first = StealFirst();
-    first->Cancel();
-    // And just let it go out of scope and die.
-  }
-}
-
-#ifdef DEBUG
-bool
-ScriptLoadRequestList::Contains(ScriptLoadRequest* aElem) const
-{
-  for (const ScriptLoadRequest* req = getFirst();
-       req; req = req->getNext()) {
-    if (req == aElem) {
-      return true;
-    }
-  }
-
-  return false;
-}
-#endif // DEBUG
-
-inline void
-ImplCycleCollectionUnlink(ScriptLoadRequestList& aField)
-{
-  while (!aField.isEmpty()) {
-    RefPtr<ScriptLoadRequest> first = aField.StealFirst();
-  }
-}
-
-inline void
-ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
-                            ScriptLoadRequestList& aField,
-                            const char* aName,
-                            uint32_t aFlags)
-{
-  for (ScriptLoadRequest* request = aField.getFirst();
-       request; request = request->getNext())
-  {
-    CycleCollectionNoteChild(aCallback, request, aName, aFlags);
-  }
-}
-
-} // dom namespace
-} // mozilla namespace
deleted file mode 100644
--- a/dom/script/ScriptLoadRequest.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/* -*- 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 mozilla_dom_ScriptLoadRequest_h
-#define mozilla_dom_ScriptLoadRequest_h
-
-#include "mozilla/CORSMode.h"
-#include "mozilla/dom/SRIMetadata.h"
-#include "mozilla/LinkedList.h"
-#include "mozilla/net/ReferrerPolicy.h"
-#include "mozilla/Vector.h"
-#include "nsCOMPtr.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsIScriptElement.h"
-
-class nsICacheInfoChannel;
-
-namespace mozilla {
-namespace dom {
-
-class ModuleLoadRequest;
-class ScriptLoadRequestList;
-
-enum class ScriptKind {
-  Classic,
-  Module
-};
-
-/*
- * A class that handles loading and evaluation of <script> elements.
- */
-
-class ScriptLoadRequest : public nsISupports,
-                          private mozilla::LinkedListElement<ScriptLoadRequest>
-{
-  typedef LinkedListElement<ScriptLoadRequest> super;
-
-  // Allow LinkedListElement<ScriptLoadRequest> to cast us to itself as needed.
-  friend class mozilla::LinkedListElement<ScriptLoadRequest>;
-  friend class ScriptLoadRequestList;
-
-protected:
-  virtual ~ScriptLoadRequest();
-
-public:
-  ScriptLoadRequest(ScriptKind aKind,
-                    nsIScriptElement* aElement,
-                    uint32_t aVersion,
-                    mozilla::CORSMode aCORSMode,
-                    const mozilla::dom::SRIMetadata &aIntegrity);
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ScriptLoadRequest)
-
-  bool IsModuleRequest() const
-  {
-    return mKind == ScriptKind::Module;
-  }
-
-  ModuleLoadRequest* AsModuleRequest();
-
-  void FireScriptAvailable(nsresult aResult)
-  {
-    mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
-  }
-  void FireScriptEvaluated(nsresult aResult)
-  {
-    mElement->ScriptEvaluated(aResult, mElement, mIsInline);
-  }
-
-  bool IsPreload()
-  {
-    return mElement == nullptr;
-  }
-
-  virtual void Cancel();
-
-  bool IsCanceled() const
-  {
-    return mIsCanceled;
-  }
-
-  virtual void SetReady();
-
-  void** OffThreadTokenPtr()
-  {
-    return mOffThreadToken ?  &mOffThreadToken : nullptr;
-  }
-
-  bool IsTracking() const
-  {
-    return mIsTracking;
-  }
-  void SetIsTracking()
-  {
-    MOZ_ASSERT(!mIsTracking);
-    mIsTracking = true;
-  }
-
-  enum class Progress : uint8_t {
-    Loading,        // Request either source or bytecode
-    Loading_Source, // Explicitly Request source stream
-    Compiling,
-    FetchingImports,
-    Ready
-  };
-
-  bool IsReadyToRun() const {
-    return mProgress == Progress::Ready;
-  }
-  bool IsLoading() const {
-    return mProgress == Progress::Loading ||
-           mProgress == Progress::Loading_Source;
-  }
-  bool IsLoadingSource() const {
-    return mProgress == Progress::Loading_Source;
-  }
-  bool InCompilingStage() const {
-    return mProgress == Progress::Compiling ||
-           (IsReadyToRun() && mWasCompiledOMT);
-  }
-
-  // Type of data provided by the nsChannel.
-  enum class DataType : uint8_t {
-    Unknown,
-    Source,
-    Bytecode
-  };
-
-  bool IsUnknownDataType() const {
-    return mDataType == DataType::Unknown;
-  }
-  bool IsSource() const {
-    return mDataType == DataType::Source;
-  }
-  bool IsBytecode() const {
-    return mDataType == DataType::Bytecode;
-  }
-
-  void MaybeCancelOffThreadScript();
-  void DropBytecodeCacheReferences();
-
-  using super::getNext;
-  using super::isInList;
-
-  const ScriptKind mKind;
-  nsCOMPtr<nsIScriptElement> mElement;
-  bool mScriptFromHead;   // Synchronous head script block loading of other non js/css content.
-  Progress mProgress;     // Are we still waiting for a load to complete?
-  DataType mDataType;     // Does this contain Source or Bytecode?
-  bool mIsInline;         // Is the script inline or loaded?
-  bool mHasSourceMapURL;  // Does the HTTP header have a source map url?
-  bool mIsDefer;          // True if we live in mDeferRequests.
-  bool mIsAsync;          // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
-  bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
-  bool mIsXSLT;           // True if we live in mXSLTRequests.
-  bool mIsCanceled;       // True if we have been explicitly canceled.
-  bool mWasCompiledOMT;   // True if the script has been compiled off main thread.
-  bool mIsTracking;       // True if the script comes from a source on our tracking protection list.
-  void* mOffThreadToken;  // Off-thread parsing token.
-  nsString mSourceMapURL; // Holds source map url for loaded scripts
-
-  // Holds the top-level JSScript that corresponds to the current source, once
-  // it is parsed, and planned to be saved in the bytecode cache.
-  JS::Heap<JSScript*> mScript;
-
-  // Holds script text for non-inline scripts. Don't use nsString so we can give
-  // ownership to jsapi.
-  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
-
-  uint32_t mJSVersion;
-  nsCOMPtr<nsIURI> mURI;
-  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;
-
-  // Holds the Cache information, which is used to register the bytecode
-  // on the cache entry, such that we can load it the next time.
-  nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
-};
-
-class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest>
-{
-  typedef mozilla::LinkedList<ScriptLoadRequest> super;
-
-public:
-  ~ScriptLoadRequestList();
-
-  void Clear();
-
-#ifdef DEBUG
-  bool Contains(ScriptLoadRequest* aElem) const;
-#endif // DEBUG
-
-  using super::getFirst;
-  using super::isEmpty;
-
-  void AppendElement(ScriptLoadRequest* aElem)
-  {
-    MOZ_ASSERT(!aElem->isInList());
-    NS_ADDREF(aElem);
-    insertBack(aElem);
-  }
-
-  MOZ_MUST_USE
-  already_AddRefed<ScriptLoadRequest> Steal(ScriptLoadRequest* aElem)
-  {
-    aElem->removeFrom(*this);
-    return dont_AddRef(aElem);
-  }
-
-  MOZ_MUST_USE
-  already_AddRefed<ScriptLoadRequest> StealFirst()
-  {
-    MOZ_ASSERT(!isEmpty());
-    return Steal(getFirst());
-  }
-
-  void Remove(ScriptLoadRequest* aElem)
-  {
-    aElem->removeFrom(*this);
-    NS_RELEASE(aElem);
-  }
-};
-
-void
-ImplCycleCollectionUnlink(ScriptLoadRequestList& aField);
-
-void
-ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
-                            ScriptLoadRequestList& aField,
-                            const char* aName,
-                            uint32_t aFlags);
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_ScriptLoadRequest_h
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -1,20 +1,19 @@
 /* -*- 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/. */
 
+/*
+ * A class that handles loading and evaluation of <script> elements.
+ */
+
 #include "ScriptLoader.h"
-#include "ScriptLoadHandler.h"
-#include "ScriptLoadRequest.h"
-#include "ScriptTrace.h"
-#include "ModuleLoadRequest.h"
-#include "ModuleScript.h"
 
 #include "prsystem.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Utility.h"
 #include "xpcpublic.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIContent.h"
@@ -65,28 +64,507 @@
 #include "nsIScriptError.h"
 #include "nsIOutputStream.h"
 
 using JS::SourceBufferHolder;
 
 namespace mozilla {
 namespace dom {
 
-LazyLogModule ScriptLoader::gCspPRLog("CSP");
-LazyLogModule ScriptLoader::gScriptLoaderLog("ScriptLoader");
-
-#define LOG(args) \
+static LazyLogModule gCspPRLog("CSP");
+static LazyLogModule gScriptLoaderLog("ScriptLoader");
+
+#define LOG_VERBOSE(args)                                                     \
+  MOZ_LOG(gScriptLoaderLog, mozilla::LogLevel::Verbose, args)
+#define LOG(args)                                                             \
   MOZ_LOG(gScriptLoaderLog, mozilla::LogLevel::Debug, args)
+#define LOG_WARN(args)                                                        \
+  MOZ_LOG(gScriptLoaderLog, mozilla::LogLevel::Warning, args)
+#define LOG_ERROR(args)                                                       \
+  MOZ_LOG(gScriptLoaderLog, mozilla::LogLevel::Error, args)
+
+#define LOG_ENABLED() MOZ_LOG_TEST(gScriptLoaderLog, mozilla::LogLevel::Debug)
 
 // These are the Alternate Data MIME type used by the ScriptLoader to
 // register and read bytecode out of the nsCacheInfoChannel.
 static NS_NAMED_LITERAL_CSTRING(
   kBytecodeMimeType, "javascript/moz-bytecode-" NS_STRINGIFY(MOZ_BUILDID));
 static NS_NAMED_LITERAL_CSTRING(kNullMimeType, "javascript/null");
 
+void
+ImplCycleCollectionUnlink(ScriptLoadRequestList& aField);
+
+void
+ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
+                            ScriptLoadRequestList& aField,
+                            const char* aName,
+                            uint32_t aFlags = 0);
+
+// This macro is used to wrap a tracing mechanism which is scheduling events
+// which are then used by the JavaScript code of test cases to track the code
+// path to verify the optimizations are working as expected.
+#define TRACE_FOR_TEST(elem, str)                               \
+  PR_BEGIN_MACRO                                                \
+    nsresult rv = NS_OK;                                        \
+    rv = TestingDispatchEvent(elem, NS_LITERAL_STRING(str));    \
+    NS_ENSURE_SUCCESS(rv, rv);                                  \
+  PR_END_MACRO
+#define TRACE_FOR_TEST_BOOL(elem, str)                          \
+  PR_BEGIN_MACRO                                                \
+    nsresult rv = NS_OK;                                        \
+    rv = TestingDispatchEvent(elem, NS_LITERAL_STRING(str));    \
+    NS_ENSURE_SUCCESS(rv, false);                               \
+  PR_END_MACRO
+#define TRACE_FOR_TEST_NONE(elem, str)                          \
+  PR_BEGIN_MACRO                                                \
+    TestingDispatchEvent(elem, NS_LITERAL_STRING(str));         \
+  PR_END_MACRO
+
+static nsresult
+TestingDispatchEvent(nsIScriptElement* aScriptElement,
+                     const nsAString& aEventType)
+{
+  static bool sExposeTestInterfaceEnabled = false;
+  static bool sExposeTestInterfacePrefCached = false;
+  if (!sExposeTestInterfacePrefCached) {
+    sExposeTestInterfacePrefCached = true;
+    Preferences::AddBoolVarCache(&sExposeTestInterfaceEnabled,
+                                 "dom.expose_test_interfaces",
+                                 false);
+  }
+  if (!sExposeTestInterfaceEnabled) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsINode> target(do_QueryInterface(aScriptElement));
+  if (!target) {
+    return NS_OK;
+  }
+
+  RefPtr<AsyncEventDispatcher> dispatcher =
+    new AsyncEventDispatcher(target, aEventType, true, false);
+  return dispatcher->PostDOMEvent();
+}
+
+//////////////////////////////////////////////////////////////
+// ScriptLoadRequest
+//////////////////////////////////////////////////////////////
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptLoadRequest)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoadRequest)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadRequest)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheInfo)
+  tmp->DropBytecodeCacheReferences();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest)
+  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()
+{
+  // We should always clean up any off-thread script parsing resources.
+  MOZ_ASSERT(!mOffThreadToken);
+
+  // But play it safe in release builds and try to clean them up here
+  // as a fail safe.
+  MaybeCancelOffThreadScript();
+
+  if (mScript) {
+    DropBytecodeCacheReferences();
+  }
+}
+
+void
+ScriptLoadRequest::SetReady()
+{
+  MOZ_ASSERT(mProgress != Progress::Ready);
+  mProgress = Progress::Ready;
+}
+
+void
+ScriptLoadRequest::Cancel()
+{
+  MaybeCancelOffThreadScript();
+  mIsCanceled = true;
+}
+
+void
+ScriptLoadRequest::MaybeCancelOffThreadScript()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (!mOffThreadToken) {
+    return;
+  }
+
+  JSContext* cx = danger::GetJSContext();
+  // Follow the same conditions as ScriptLoader::AttemptAsyncScriptCompile
+  if (IsModuleRequest()) {
+    JS::CancelOffThreadModule(cx, mOffThreadToken);
+  } else if (IsSource()) {
+    JS::CancelOffThreadScript(cx, mOffThreadToken);
+  } else {
+    MOZ_ASSERT(IsBytecode());
+    JS::CancelOffThreadScriptDecoder(cx, mOffThreadToken);
+  }
+  mOffThreadToken = nullptr;
+}
+
+//////////////////////////////////////////////////////////////
+// ModuleLoadRequest
+//////////////////////////////////////////////////////////////
+
+// 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,
+                    uint32_t aVersion,
+                    CORSMode aCORSMode,
+                    const SRIMetadata& aIntegrity,
+                    ScriptLoader* aLoader);
+
+  bool IsTopLevel() const {
+    return mIsTopLevel;
+  }
+
+  void SetReady() override;
+  void Cancel() override;
+
+  void ModuleLoaded();
+  void DependenciesLoaded();
+  void LoadFailed();
+
+  // Is this a request for a top level module script or an import?
+  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;
+};
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(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,
+                                     uint32_t aVersion,
+                                     CORSMode aCORSMode,
+                                     const SRIMetadata &aIntegrity,
+                                     ScriptLoader* aLoader)
+  : ScriptLoadRequest(ScriptKind::Module,
+                      aElement,
+                      aVersion,
+                      aCORSMode,
+                      aIntegrity),
+    mIsTopLevel(true),
+    mLoader(aLoader)
+{}
+
+inline ModuleLoadRequest*
+ScriptLoadRequest::AsModuleRequest()
+{
+  MOZ_ASSERT(IsModuleRequest());
+  return static_cast<ModuleLoadRequest*>(this);
+}
+
+void ModuleLoadRequest::Cancel()
+{
+  ScriptLoadRequest::Cancel();
+  mModuleScript = nullptr;
+  mProgress = ScriptLoadRequest::Progress::Ready;
+  for (size_t i = 0; i < mImports.Length(); i++) {
+    mImports[i]->Cancel();
+  }
+  mReady.RejectIfExists(NS_ERROR_FAILURE, __func__);
+}
+
+void
+ModuleLoadRequest::SetReady()
+{
+#ifdef DEBUG
+  for (size_t i = 0; i < mImports.Length(); i++) {
+    MOZ_ASSERT(mImports[i]->IsReadyToRun());
+  }
+#endif
+
+  ScriptLoadRequest::SetReady();
+  mReady.ResolveIfExists(true, __func__);
+}
+
+void
+ModuleLoadRequest::ModuleLoaded()
+{
+  // A module that was found to be marked as fetching in the module map has now
+  // been loaded.
+
+  mModuleScript = mLoader->GetFetchedModule(mURI);
+  mLoader->StartFetchingModuleDependencies(this);
+}
+
+void
+ModuleLoadRequest::DependenciesLoaded()
+{
+  // The module and all of its dependencies have been successfully fetched and
+  // compiled.
+
+  if (!mLoader->InstantiateModuleTree(this)) {
+    LoadFailed();
+    return;
+  }
+
+  SetReady();
+  mLoader->ProcessLoadedModuleTree(this);
+  mLoader = nullptr;
+  mParent = nullptr;
+}
+
+void
+ModuleLoadRequest::LoadFailed()
+{
+  Cancel();
+  mLoader->ProcessLoadedModuleTree(this);
+  mLoader = nullptr;
+  mParent = nullptr;
+}
+
+//////////////////////////////////////////////////////////////
+// ModuleScript
+//////////////////////////////////////////////////////////////
+
+// A single module script.  May be used to satisfy multiple load requests.
+
+class ModuleScript final : public nsISupports
+{
+  enum InstantiationState {
+    Uninstantiated,
+    Instantiated,
+    Errored
+  };
+
+  RefPtr<ScriptLoader> mLoader;
+  nsCOMPtr<nsIURI> mBaseURL;
+  JS::Heap<JSObject*> mModuleRecord;
+  JS::Heap<JS::Value> mException;
+  InstantiationState mInstantiationState;
+
+  ~ModuleScript();
+
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ModuleScript)
+
+  ModuleScript(ScriptLoader* aLoader,
+               nsIURI* aBaseURL,
+               JS::Handle<JSObject*> aModuleRecord);
+
+  ScriptLoader* Loader() const { return mLoader; }
+  JSObject* ModuleRecord() const { return mModuleRecord; }
+  JS::Value Exception() const { return mException; }
+  nsIURI* BaseURL() const { return mBaseURL; }
+
+  void SetInstantiationResult(JS::Handle<JS::Value> aMaybeException);
+  bool IsUninstantiated() const {
+    return mInstantiationState == Uninstantiated;
+  }
+  bool IsInstantiated() const {
+    return mInstantiationState == Instantiated;
+  }
+  bool InstantiationFailed() const {
+    return mInstantiationState == Errored;
+  }
+
+  void UnlinkModuleRecord();
+};
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ModuleScript)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleScript)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ModuleScript)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL)
+  tmp->UnlinkModuleRecord();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ModuleScript)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ModuleScript)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRecord)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mException)
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(ModuleScript)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(ModuleScript)
+
+ModuleScript::ModuleScript(ScriptLoader *aLoader, nsIURI* aBaseURL,
+                           JS::Handle<JSObject*> aModuleRecord)
+ : mLoader(aLoader),
+   mBaseURL(aBaseURL),
+   mModuleRecord(aModuleRecord),
+   mInstantiationState(Uninstantiated)
+{
+  MOZ_ASSERT(mLoader);
+  MOZ_ASSERT(mBaseURL);
+  MOZ_ASSERT(mModuleRecord);
+  MOZ_ASSERT(mException.isUndefined());
+
+  // Make module's host defined field point to this module script object.
+  // This is cleared in the UnlinkModuleRecord().
+  JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this));
+  HoldJSObjects(this);
+}
+
+void
+ModuleScript::UnlinkModuleRecord()
+{
+  // Remove module's back reference to this object request if present.
+  if (mModuleRecord) {
+    MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() ==
+               this);
+    JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue());
+  }
+  mModuleRecord = nullptr;
+  mException.setUndefined();
+}
+
+ModuleScript::~ModuleScript()
+{
+  if (mModuleRecord) {
+    // The object may be destroyed without being unlinked first.
+    UnlinkModuleRecord();
+  }
+  DropJSObjects(this);
+}
+
+void
+ModuleScript::SetInstantiationResult(JS::Handle<JS::Value> aMaybeException)
+{
+  MOZ_ASSERT(mInstantiationState == Uninstantiated);
+  MOZ_ASSERT(mModuleRecord);
+  MOZ_ASSERT(mException.isUndefined());
+
+  if (aMaybeException.isUndefined()) {
+    mInstantiationState = Instantiated;
+  } else {
+    mModuleRecord = nullptr;
+    mException = aMaybeException;
+    mInstantiationState = Errored;
+  }
+}
+
+//////////////////////////////////////////////////////////////
+
+// ScriptLoadRequestList
+//////////////////////////////////////////////////////////////
+
+ScriptLoadRequestList::~ScriptLoadRequestList()
+{
+  Clear();
+}
+
+void
+ScriptLoadRequestList::Clear()
+{
+  while (!isEmpty()) {
+    RefPtr<ScriptLoadRequest> first = StealFirst();
+    first->Cancel();
+    // And just let it go out of scope and die.
+  }
+}
+
+#ifdef DEBUG
+bool
+ScriptLoadRequestList::Contains(ScriptLoadRequest* aElem) const
+{
+  for (const ScriptLoadRequest* req = getFirst();
+       req; req = req->getNext()) {
+    if (req == aElem) {
+      return true;
+    }
+  }
+
+  return false;
+}
+#endif // DEBUG
+
+inline void
+ImplCycleCollectionUnlink(ScriptLoadRequestList& aField)
+{
+  while (!aField.isEmpty()) {
+    RefPtr<ScriptLoadRequest> first = aField.StealFirst();
+  }
+}
+
+inline void
+ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
+                            ScriptLoadRequestList& aField,
+                            const char* aName,
+                            uint32_t aFlags)
+{
+  for (ScriptLoadRequest* request = aField.getFirst();
+       request; request = request->getNext())
+  {
+    CycleCollectionNoteChild(aCallback, request, aName, aFlags);
+  }
+}
+
 //////////////////////////////////////////////////////////////
 // ScriptLoader::PreloadInfo
 //////////////////////////////////////////////////////////////
 
 inline void
 ImplCycleCollectionUnlink(ScriptLoader::PreloadInfo& aField)
 {
   ImplCycleCollectionUnlink(aField.mRequest);
@@ -799,18 +1277,18 @@ ScriptLoader::InstantiateModuleTree(Modu
         return false;
       }
     }
   }
 
   return true;
 }
 
-/* static */ bool
-ScriptLoader::IsBytecodeCacheEnabled()
+static bool
+IsBytecodeCacheEnabled()
 {
   static bool sExposeTestInterfaceEnabled = false;
   static bool sExposeTestInterfacePrefCached = false;
   if (!sExposeTestInterfacePrefCached) {
     sExposeTestInterfacePrefCached = true;
     Preferences::AddBoolVarCache(&sExposeTestInterfaceEnabled,
                                  "dom.script_loader.bytecode_cache.enabled",
                                  false);
@@ -2173,16 +2651,24 @@ ScriptLoader::EncodeRequestBytecode(JSCo
     return;
   }
 
   bytecodeFailed.release();
   TRACE_FOR_TEST_NONE(aRequest->mElement, "scriptloader_bytecode_saved");
 }
 
 void
+ScriptLoadRequest::DropBytecodeCacheReferences()
+{
+  mCacheInfo = nullptr;
+  mScript = nullptr;
+  DropJSObjects(this);
+}
+
+void
 ScriptLoader::GiveUpBytecodeEncoding()
 {
   // Ideally we prefer to properly end the incremental encoder, such that we
   // would not keep a large buffer around.  If we cannot, we fallback on the
   // removal of all request from the current list.
   nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
   if (globalObject) {
     nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext();
@@ -2912,16 +3398,383 @@ ScriptLoader::MaybeRemovedDeferRequests(
       mBlockingDOMContentLoaded) {
     mBlockingDOMContentLoaded = false;
     mDocument->UnblockDOMContentLoaded();
     return true;
   }
   return false;
 }
 
+//////////////////////////////////////////////////////////////
+// ScriptLoadHandler
+//////////////////////////////////////////////////////////////
+
+ScriptLoadHandler::ScriptLoadHandler(ScriptLoader *aScriptLoader,
+                                     ScriptLoadRequest *aRequest,
+                                     mozilla::dom::SRICheckDataVerifier *aSRIDataVerifier)
+  : mScriptLoader(aScriptLoader),
+    mRequest(aRequest),
+    mSRIDataVerifier(aSRIDataVerifier),
+    mSRIStatus(NS_OK),
+    mDecoder()
+{
+  MOZ_ASSERT(mRequest->IsUnknownDataType());
+  MOZ_ASSERT(mRequest->IsLoading());
+}
+
+ScriptLoadHandler::~ScriptLoadHandler()
+{}
+
+NS_IMPL_ISUPPORTS(ScriptLoadHandler, nsIIncrementalStreamLoaderObserver)
+
+NS_IMETHODIMP
+ScriptLoadHandler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
+                                     nsISupports* aContext,
+                                     uint32_t aDataLength,
+                                     const uint8_t* aData,
+                                     uint32_t *aConsumedLength)
+{
+  if (mRequest->IsCanceled()) {
+    // If request cancelled, ignore any incoming data.
+    *aConsumedLength = aDataLength;
+    return NS_OK;
+  }
+
+  nsresult rv = NS_OK;
+  if (mRequest->IsUnknownDataType()) {
+    rv = EnsureKnownDataType(aLoader);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  if (mRequest->IsSource()) {
+    if (!EnsureDecoder(aLoader, aData, aDataLength,
+                       /* aEndOfStream = */ false)) {
+      return NS_OK;
+    }
+
+    // Below we will/shall consume entire data chunk.
+    *aConsumedLength = aDataLength;
+
+    // Decoder has already been initialized. -- trying to decode all loaded bytes.
+    rv = DecodeRawData(aData, aDataLength, /* aEndOfStream = */ false);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // If SRI is required for this load, appending new bytes to the hash.
+    if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
+      mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
+    }
+  } else {
+    MOZ_ASSERT(mRequest->IsBytecode());
+    if (!mRequest->mScriptBytecode.append(aData, aDataLength)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    *aConsumedLength = aDataLength;
+    rv = MaybeDecodeSRI();
+    if (NS_FAILED(rv)) {
+      nsCOMPtr<nsIRequest> channelRequest;
+      aLoader->GetRequest(getter_AddRefs(channelRequest));
+      return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
+    }
+  }
+
+  return rv;
+}
+
+nsresult
+ScriptLoadHandler::DecodeRawData(const uint8_t* aData,
+                                 uint32_t aDataLength,
+                                 bool aEndOfStream)
+{
+  int32_t srcLen = aDataLength;
+  const char* src = reinterpret_cast<const char *>(aData);
+  int32_t dstLen;
+  nsresult rv =
+    mDecoder->GetMaxLength(src, srcLen, &dstLen);
+
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  uint32_t haveRead = mRequest->mScriptText.length();
+
+  CheckedInt<uint32_t> capacity = haveRead;
+  capacity += dstLen;
+
+  if (!capacity.isValid() || !mRequest->mScriptText.reserve(capacity.value())) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  rv = mDecoder->Convert(src,
+                         &srcLen,
+                         mRequest->mScriptText.begin() + haveRead,
+                         &dstLen);
+
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  haveRead += dstLen;
+  MOZ_ASSERT(haveRead <= capacity.value(), "mDecoder produced more data than expected");
+  MOZ_ALWAYS_TRUE(mRequest->mScriptText.resizeUninitialized(haveRead));
+
+  return NS_OK;
+}
+
+bool
+ScriptLoadHandler::EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
+                                 const uint8_t* aData,
+                                 uint32_t aDataLength,
+                                 bool aEndOfStream)
+{
+  // Check if decoder has already been created.
+  if (mDecoder) {
+    return true;
+  }
+
+  nsAutoCString charset;
+  if (!EnsureDecoder(aLoader, aData, aDataLength, aEndOfStream, charset)) {
+    return false;
+  }
+  if (charset.Length() == 0) {
+    charset = "?";
+  }
+  mozilla::Telemetry::Accumulate(mozilla::Telemetry::DOM_SCRIPT_SRC_ENCODING,
+    charset);
+  return true;
+}
+
+bool
+ScriptLoadHandler::EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
+                                 const uint8_t* aData,
+                                 uint32_t aDataLength,
+                                 bool aEndOfStream,
+                                 nsCString& oCharset)
+{
+  // JavaScript modules are always UTF-8.
+  if (mRequest->IsModuleRequest()) {
+    oCharset = "UTF-8";
+    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
+    return true;
+  }
+
+  // Determine if BOM check should be done.  This occurs either
+  // if end-of-stream has been reached, or at least 3 bytes have
+  // been read from input.
+  if (!aEndOfStream && (aDataLength < 3)) {
+    return false;
+  }
+
+  // Do BOM detection.
+  if (nsContentUtils::CheckForBOM(aData, aDataLength, oCharset)) {
+    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
+    return true;
+  }
+
+  // BOM detection failed, check content stream for charset.
+  nsCOMPtr<nsIRequest> req;
+  nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
+  NS_ASSERTION(req, "StreamLoader's request went away prematurely");
+  NS_ENSURE_SUCCESS(rv, false);
+
+  nsCOMPtr<nsIChannel> channel = do_QueryInterface(req);
+
+  if (channel &&
+      NS_SUCCEEDED(channel->GetContentCharset(oCharset)) &&
+      EncodingUtils::FindEncodingForLabel(oCharset, oCharset)) {
+    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
+    return true;
+  }
+
+  // Check the hint charset from the script element or preload
+  // request.
+  nsAutoString hintCharset;
+  if (!mRequest->IsPreload()) {
+    mRequest->mElement->GetScriptCharset(hintCharset);
+  } else {
+    nsTArray<ScriptLoader::PreloadInfo>::index_type i =
+      mScriptLoader->mPreloads.IndexOf(mRequest, 0,
+            ScriptLoader::PreloadRequestComparator());
+
+    NS_ASSERTION(i != mScriptLoader->mPreloads.NoIndex,
+                 "Incorrect preload bookkeeping");
+    hintCharset = mScriptLoader->mPreloads[i].mCharset;
+  }
+
+  if (EncodingUtils::FindEncodingForLabel(hintCharset, oCharset)) {
+    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
+    return true;
+  }
+
+  // Get the charset from the charset of the document.
+  if (mScriptLoader->mDocument) {
+    oCharset = mScriptLoader->mDocument->GetDocumentCharacterSet();
+    mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
+    return true;
+  }
+
+  // Curiously, there are various callers that don't pass aDocument. The
+  // fallback in the old code was ISO-8859-1, which behaved like
+  // windows-1252. Saying windows-1252 for clarity and for compliance
+  // with the Encoding Standard.
+  oCharset = "windows-1252";
+  mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
+
+  return true;
+}
+
+nsresult
+ScriptLoadHandler::MaybeDecodeSRI()
+{
+  if (!mSRIDataVerifier || mSRIDataVerifier->IsComplete() || NS_FAILED(mSRIStatus)) {
+    return NS_OK;
+  }
+
+  // Skip until the content is large enough to be decoded.
+  if (mRequest->mScriptBytecode.length() <= mSRIDataVerifier->DataSummaryLength()) {
+    return NS_OK;
+  }
+
+  mSRIStatus = mSRIDataVerifier->ImportDataSummary(
+    mRequest->mScriptBytecode.length(), mRequest->mScriptBytecode.begin());
+
+  if (NS_FAILED(mSRIStatus)) {
+    // We are unable to decode the hash contained in the alternate data which
+    // contains the bytecode, or it does not use the same algorithm.
+    LOG(("ScriptLoadHandler::MaybeDecodeSRI, failed to decode SRI, restart request"));
+    return mSRIStatus;
+  }
+
+  mRequest->mBytecodeOffset = mSRIDataVerifier->DataSummaryLength();
+  return NS_OK;
+}
+
+nsresult
+ScriptLoadHandler::EnsureKnownDataType(nsIIncrementalStreamLoader *aLoader)
+{
+  MOZ_ASSERT(mRequest->IsUnknownDataType());
+  MOZ_ASSERT(mRequest->IsLoading());
+  if (mRequest->IsLoadingSource()) {
+    mRequest->mDataType = ScriptLoadRequest::DataType::Source;
+    TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIRequest> req;
+  nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
+  MOZ_ASSERT(req, "StreamLoader's request went away prematurely");
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsICacheInfoChannel> cic(do_QueryInterface(req));
+  if (cic) {
+    nsAutoCString altDataType;
+    cic->GetAlternativeDataType(altDataType);
+    if (altDataType == kBytecodeMimeType) {
+      mRequest->mDataType = ScriptLoadRequest::DataType::Bytecode;
+      TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_bytecode");
+    } else {
+      mRequest->mDataType = ScriptLoadRequest::DataType::Source;
+      TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
+    }
+  } else {
+    mRequest->mDataType = ScriptLoadRequest::DataType::Source;
+    TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
+  }
+  MOZ_ASSERT(!mRequest->IsUnknownDataType());
+  MOZ_ASSERT(mRequest->IsLoading());
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
+                                    nsISupports* aContext,
+                                    nsresult aStatus,
+                                    uint32_t aDataLength,
+                                    const uint8_t* aData)
+{
+  nsresult rv = NS_OK;
+  if (LOG_ENABLED()) {
+    nsAutoCString url;
+    mRequest->mURI->GetAsciiSpec(url);
+    LOG(("ScriptLoadRequest (%p): Stream complete (url = %s)",
+         mRequest.get(), url.get()));
+  }
+
+  nsCOMPtr<nsIRequest> channelRequest;
+  aLoader->GetRequest(getter_AddRefs(channelRequest));
+
+  if (!mRequest->IsCanceled()) {
+    if (mRequest->IsUnknownDataType()) {
+      rv = EnsureKnownDataType(aLoader);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+
+    if (mRequest->IsSource()) {
+      DebugOnly<bool> encoderSet =
+        EnsureDecoder(aLoader, aData, aDataLength, /* aEndOfStream = */ true);
+      MOZ_ASSERT(encoderSet);
+      rv = DecodeRawData(aData, aDataLength, /* aEndOfStream = */ true);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      LOG(("ScriptLoadRequest (%p): Source length = %u",
+           mRequest.get(), unsigned(mRequest->mScriptText.length())));
+
+      // If SRI is required for this load, appending new bytes to the hash.
+      if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
+        mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
+      }
+    } else {
+      MOZ_ASSERT(mRequest->IsBytecode());
+      if (!mRequest->mScriptBytecode.append(aData, aDataLength)) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
+
+      LOG(("ScriptLoadRequest (%p): Bytecode length = %u",
+           mRequest.get(), unsigned(mRequest->mScriptBytecode.length())));
+
+      // If we abort while decoding the SRI, we fallback on explictly requesting
+      // the source. Thus, we should not continue in
+      // ScriptLoader::OnStreamComplete, which removes the request from the
+      // waiting lists.
+      rv = MaybeDecodeSRI();
+      if (NS_FAILED(rv)) {
+        return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
+      }
+
+      // The bytecode cache always starts with the SRI hash, thus even if there
+      // is no SRI data verifier instance, we still want to skip the hash.
+      rv = SRICheckDataVerifier::DataSummaryLength(mRequest->mScriptBytecode.length(),
+                                                   mRequest->mScriptBytecode.begin(),
+                                                   &mRequest->mBytecodeOffset);
+      if (NS_FAILED(rv)) {
+        return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
+      }
+    }
+  }
+
+  // Everything went well, keep the CacheInfoChannel alive such that we can
+  // later save the bytecode on the cache entry.
+  if (NS_SUCCEEDED(rv) && mRequest->IsSource() && IsBytecodeCacheEnabled()) {
+    mRequest->mCacheInfo = do_QueryInterface(channelRequest);
+    LOG(("ScriptLoadRequest (%p): nsICacheInfoChannel = %p",
+         mRequest.get(), mRequest->mCacheInfo.get()));
+  }
+
+  // we have to mediate and use mRequest.
+  rv = mScriptLoader->OnStreamComplete(aLoader, mRequest, aStatus, mSRIStatus,
+                                       mSRIDataVerifier);
+
+  // In case of failure, clear the mCacheInfoChannel to avoid keeping it alive.
+  if (NS_FAILED(rv)) {
+    mRequest->mCacheInfo = nullptr;
+  }
+
+  return rv;
+}
+
 #undef TRACE_FOR_TEST
 #undef TRACE_FOR_TEST_BOOL
 #undef TRACE_FOR_TEST_NONE
 
+#undef LOG_ENABLED
+#undef LOG_ERROR
+#undef LOG_WARN
 #undef LOG
+#undef LOG_VERBOSE
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -1,51 +1,289 @@
 /* -*- 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/. */
 
+/*
+ * A class that handles loading and evaluation of <script> elements.
+ */
+
 #ifndef mozilla_dom_ScriptLoader_h
 #define mozilla_dom_ScriptLoader_h
 
 #include "nsCOMPtr.h"
 #include "nsRefPtrHashtable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsIScriptElement.h"
 #include "nsCOMArray.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsICacheInfoChannel.h"
 #include "nsIDocument.h"
 #include "nsIIncrementalStreamLoader.h"
 #include "nsURIHashKey.h"
 #include "mozilla/CORSMode.h"
-#include "mozilla/dom/ScriptLoadRequest.h"
 #include "mozilla/dom/SRIMetadata.h"
 #include "mozilla/dom/SRICheck.h"
+#include "mozilla/LinkedList.h"
 #include "mozilla/MozPromise.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "mozilla/Vector.h"
 
 class nsIURI;
 
 namespace JS {
   class SourceBufferHolder;
 } // namespace JS
 
 namespace mozilla {
 namespace dom {
 
 class AutoJSAPI;
 class ModuleLoadRequest;
 class ModuleScript;
-class ScriptLoadHandler;
-class ScriptRequestProcessor;
+class ScriptLoadRequestList;
+
+//////////////////////////////////////////////////////////////
+// Per-request data structure
+//////////////////////////////////////////////////////////////
+
+enum class ScriptKind {
+  Classic,
+  Module
+};
+
+class ScriptLoadRequest : public nsISupports,
+                          private mozilla::LinkedListElement<ScriptLoadRequest>
+{
+  typedef LinkedListElement<ScriptLoadRequest> super;
+
+  // Allow LinkedListElement<ScriptLoadRequest> to cast us to itself as needed.
+  friend class mozilla::LinkedListElement<ScriptLoadRequest>;
+  friend class ScriptLoadRequestList;
+
+protected:
+  virtual ~ScriptLoadRequest();
+
+public:
+  ScriptLoadRequest(ScriptKind aKind,
+                    nsIScriptElement* aElement,
+                      uint32_t aVersion,
+                      mozilla::CORSMode aCORSMode,
+                      const mozilla::dom::SRIMetadata &aIntegrity)
+    : mKind(aKind),
+      mElement(aElement),
+      mScriptFromHead(false),
+      mProgress(Progress::Loading),
+      mDataType(DataType::Unknown),
+      mIsInline(true),
+      mHasSourceMapURL(false),
+      mIsDefer(false),
+      mIsAsync(false),
+      mIsNonAsyncScriptInserted(false),
+      mIsXSLT(false),
+      mIsCanceled(false),
+      mWasCompiledOMT(false),
+      mIsTracking(false),
+      mOffThreadToken(nullptr),
+      mScriptText(),
+      mScriptBytecode(),
+      mBytecodeOffset(0),
+      mJSVersion(aVersion),
+      mLineNo(1),
+      mCORSMode(aCORSMode),
+      mIntegrity(aIntegrity),
+      mReferrerPolicy(mozilla::net::RP_Unset)
+  {
+  }
+
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ScriptLoadRequest)
+
+  bool IsModuleRequest() const
+  {
+    return mKind == ScriptKind::Module;
+  }
+
+  ModuleLoadRequest* AsModuleRequest();
+
+  void FireScriptAvailable(nsresult aResult)
+  {
+    mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
+  }
+  void FireScriptEvaluated(nsresult aResult)
+  {
+    mElement->ScriptEvaluated(aResult, mElement, mIsInline);
+  }
+
+  bool IsPreload()
+  {
+    return mElement == nullptr;
+  }
+
+  virtual void Cancel();
+
+  bool IsCanceled() const
+  {
+    return mIsCanceled;
+  }
+
+  virtual void SetReady();
+
+  void** OffThreadTokenPtr()
+  {
+    return mOffThreadToken ?  &mOffThreadToken : nullptr;
+  }
+
+  bool IsTracking() const
+  {
+    return mIsTracking;
+  }
+  void SetIsTracking()
+  {
+    MOZ_ASSERT(!mIsTracking);
+    mIsTracking = true;
+  }
+
+  enum class Progress : uint8_t {
+    Loading,        // Request either source or bytecode
+    Loading_Source, // Explicitly Request source stream
+    Compiling,
+    FetchingImports,
+    Ready
+  };
+
+  bool IsReadyToRun() const {
+    return mProgress == Progress::Ready;
+  }
+  bool IsLoading() const {
+    return mProgress == Progress::Loading ||
+           mProgress == Progress::Loading_Source;
+  }
+  bool IsLoadingSource() const {
+    return mProgress == Progress::Loading_Source;
+  }
+  bool InCompilingStage() const {
+    return mProgress == Progress::Compiling ||
+           (IsReadyToRun() && mWasCompiledOMT);
+  }
+
+  // Type of data provided by the nsChannel.
+  enum class DataType : uint8_t {
+    Unknown,
+    Source,
+    Bytecode
+  };
+
+  bool IsUnknownDataType() const {
+    return mDataType == DataType::Unknown;
+  }
+  bool IsSource() const {
+    return mDataType == DataType::Source;
+  }
+  bool IsBytecode() const {
+    return mDataType == DataType::Bytecode;
+  }
+
+  void MaybeCancelOffThreadScript();
+  void DropBytecodeCacheReferences();
+
+  using super::getNext;
+  using super::isInList;
+
+  const ScriptKind mKind;
+  nsCOMPtr<nsIScriptElement> mElement;
+  bool mScriptFromHead;   // Synchronous head script block loading of other non js/css content.
+  Progress mProgress;     // Are we still waiting for a load to complete?
+  DataType mDataType;     // Does this contain Source or Bytecode?
+  bool mIsInline;         // Is the script inline or loaded?
+  bool mHasSourceMapURL;  // Does the HTTP header have a source map url?
+  bool mIsDefer;          // True if we live in mDeferRequests.
+  bool mIsAsync;          // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
+  bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
+  bool mIsXSLT;           // True if we live in mXSLTRequests.
+  bool mIsCanceled;       // True if we have been explicitly canceled.
+  bool mWasCompiledOMT;   // True if the script has been compiled off main thread.
+  bool mIsTracking;       // True if the script comes from a source on our tracking protection list.
+  void* mOffThreadToken;  // Off-thread parsing token.
+  nsString mSourceMapURL; // Holds source map url for loaded scripts
+
+  // Holds the top-level JSScript that corresponds to the current source, once
+  // it is parsed, and planned to be saved in the bytecode cache.
+  JS::Heap<JSScript*> mScript;
+
+  // Holds script text for non-inline scripts. Don't use nsString so we can give
+  // ownership to jsapi.
+  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
+
+  uint32_t mJSVersion;
+  nsCOMPtr<nsIURI> mURI;
+  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;
+
+  // Holds the Cache information, which is used to register the bytecode
+  // on the cache entry, such that we can load it the next time.
+  nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
+};
+
+class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest>
+{
+  typedef mozilla::LinkedList<ScriptLoadRequest> super;
+
+public:
+  ~ScriptLoadRequestList();
+
+  void Clear();
+
+#ifdef DEBUG
+  bool Contains(ScriptLoadRequest* aElem) const;
+#endif // DEBUG
+
+  using super::getFirst;
+  using super::isEmpty;
+
+  void AppendElement(ScriptLoadRequest* aElem)
+  {
+    MOZ_ASSERT(!aElem->isInList());
+    NS_ADDREF(aElem);
+    insertBack(aElem);
+  }
+
+  MOZ_MUST_USE
+  already_AddRefed<ScriptLoadRequest> Steal(ScriptLoadRequest* aElem)
+  {
+    aElem->removeFrom(*this);
+    return dont_AddRef(aElem);
+  }
+
+  MOZ_MUST_USE
+  already_AddRefed<ScriptLoadRequest> StealFirst()
+  {
+    MOZ_ASSERT(!isEmpty());
+    return Steal(getFirst());
+  }
+
+  void Remove(ScriptLoadRequest* aElem)
+  {
+    aElem->removeFrom(*this);
+    NS_RELEASE(aElem);
+  }
+};
 
 //////////////////////////////////////////////////////////////
 // Script loader implementation
 //////////////////////////////////////////////////////////////
 
 class ScriptLoader final : public nsISupports
 {
   class MOZ_STACK_CLASS AutoCurrentScriptUpdater
@@ -458,19 +696,16 @@ private:
 
   bool ModuleMapContainsModule(ModuleLoadRequest *aRequest) const;
   RefPtr<mozilla::GenericPromise> WaitForModuleFetch(ModuleLoadRequest *aRequest);
   ModuleScript* GetFetchedModule(nsIURI* aURL) const;
 
   friend bool
   HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp);
 
-  static bool
-  IsBytecodeCacheEnabled();
-
   nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
   nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
   void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest);
   bool InstantiateModuleTree(ModuleLoadRequest* aRequest);
   void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest);
 
   RefPtr<mozilla::GenericPromise>
   StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, nsIURI* aURI);
@@ -525,20 +760,73 @@ private:
   bool mBlockingDOMContentLoaded;
   bool mLoadEventFired;
 
   // Module map
   nsRefPtrHashtable<nsURIHashKey, mozilla::GenericPromise::Private> mFetchingModules;
   nsRefPtrHashtable<nsURIHashKey, ModuleScript> mFetchedModules;
 
   nsCOMPtr<nsIConsoleReportCollector> mReporter;
+};
 
-  // Logging
-  static LazyLogModule gCspPRLog;
-  static LazyLogModule gScriptLoaderLog;
+class ScriptLoadHandler final : public nsIIncrementalStreamLoaderObserver
+{
+public:
+  explicit ScriptLoadHandler(ScriptLoader* aScriptLoader,
+                             ScriptLoadRequest *aRequest,
+                             mozilla::dom::SRICheckDataVerifier *aSRIDataVerifier);
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER
+
+private:
+  virtual ~ScriptLoadHandler();
+
+  /*
+   * Once the charset is found by the EnsureDecoder function, we can
+   * incrementally convert the charset to the one expected by the JS Parser.
+   */
+  nsresult DecodeRawData(const uint8_t* aData, uint32_t aDataLength,
+                         bool aEndOfStream);
+
+  /*
+   * Discover the charset by looking at the stream data, the script
+   * tag, and other indicators.  Returns true if charset has been
+   * discovered.
+   */
+  bool EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
+                     const uint8_t* aData, uint32_t aDataLength,
+                     bool aEndOfStream);
+  bool EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
+                     const uint8_t* aData, uint32_t aDataLength,
+                     bool aEndOfStream, nsCString& oCharset);
+
+  /*
+   * When streaming bytecode, we have the opportunity to fallback early if SRI
+   * does not match the expectation of the document.
+   */
+  nsresult MaybeDecodeSRI();
+
+  // Query the channel to find the data type associated with the input stream.
+  nsresult EnsureKnownDataType(nsIIncrementalStreamLoader *aLoader);
+
+  // ScriptLoader which will handle the parsed script.
+  RefPtr<ScriptLoader>        mScriptLoader;
+
+  // The ScriptLoadRequest for this load. Decoded data are accumulated on it.
+  RefPtr<ScriptLoadRequest>   mRequest;
+
+  // SRI data verifier.
+  nsAutoPtr<mozilla::dom::SRICheckDataVerifier> mSRIDataVerifier;
+
+  // Status of SRI data operations.
+  nsresult                      mSRIStatus;
+
+  // Unicode decoder for charset.
+  nsCOMPtr<nsIUnicodeDecoder>   mDecoder;
 };
 
 class nsAutoScriptLoaderDisabler
 {
 public:
   explicit nsAutoScriptLoaderDisabler(nsIDocument* aDoc)
   {
     mLoader = aDoc->ScriptLoader();
deleted file mode 100644
--- a/dom/script/ScriptTrace.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- 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 "ScriptTrace.h"
-
-namespace mozilla {
-namespace dom {
-namespace script {
-
-static nsresult
-TestingDispatchEvent(nsIScriptElement* aScriptElement,
-                     const nsAString& aEventType)
-{
-  static bool sExposeTestInterfaceEnabled = false;
-  static bool sExposeTestInterfacePrefCached = false;
-  if (!sExposeTestInterfacePrefCached) {
-    sExposeTestInterfacePrefCached = true;
-    Preferences::AddBoolVarCache(&sExposeTestInterfaceEnabled,
-                                 "dom.expose_test_interfaces",
-                                 false);
-  }
-  if (!sExposeTestInterfaceEnabled) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsINode> target(do_QueryInterface(aScriptElement));
-  if (!target) {
-    return NS_OK;
-  }
-
-  RefPtr<AsyncEventDispatcher> dispatcher =
-    new AsyncEventDispatcher(target, aEventType, true, false);
-  return dispatcher->PostDOMEvent();
-}
-
-} // script namespace
-} // dom namespace
-} // mozilla namespace
deleted file mode 100644
--- a/dom/script/ScriptTrace.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- 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 mozilla_dom_ScriptTrace_h
-#define mozilla_dom_ScriptTrace_h
-
-#include "ScriptLoader.h"
-
-namespace mozilla {
-namespace dom {
-namespace script {
-
-// This macro is used to wrap a tracing mechanism which is scheduling events
-// which are then used by the JavaScript code of test cases to track the code
-// path to verify the optimizations are working as expected.
-#define TRACE_FOR_TEST(elem, str)                                    \
-  PR_BEGIN_MACRO                                                     \
-    nsresult rv = NS_OK;                                             \
-    rv = script::TestingDispatchEvent(elem, NS_LITERAL_STRING(str)); \
-    NS_ENSURE_SUCCESS(rv, rv);                                       \
-  PR_END_MACRO
-
-#define TRACE_FOR_TEST_BOOL(elem, str)                               \
-  PR_BEGIN_MACRO                                                     \
-    nsresult rv = NS_OK;                                             \
-    rv = script::TestingDispatchEvent(elem, NS_LITERAL_STRING(str)); \
-    NS_ENSURE_SUCCESS(rv, false);                                    \
-  PR_END_MACRO
-
-#define TRACE_FOR_TEST_NONE(elem, str)                          \
-  PR_BEGIN_MACRO                                                \
-    script::TestingDispatchEvent(elem, NS_LITERAL_STRING(str)); \
-  PR_END_MACRO
-
-static nsresult
-TestingDispatchEvent(nsIScriptElement* aScriptElement,
-                     const nsAString& aEventType);
-
-} // script namespace
-} // dom namespace
-} // mozilla namespace
-
-#endif // mozilla_dom_ScriptTrace_h
--- a/dom/script/moz.build
+++ b/dom/script/moz.build
@@ -15,29 +15,23 @@ XPIDL_MODULE = 'dom'
 
 EXPORTS += [
     'nsIScriptElement.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'ScriptElement.h',
     'ScriptLoader.h',
-    'ScriptLoadRequest.h',
     'ScriptSettings.h',
 ]
 
 UNIFIED_SOURCES += [
-    'ModuleLoadRequest.cpp',
-    'ModuleScript.cpp',
     'ScriptElement.cpp',
     'ScriptLoader.cpp',
-    'ScriptLoadHandler.cpp',
-    'ScriptLoadRequest.cpp',
     'ScriptSettings.cpp',
-    'ScriptTrace.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/workers',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')