Bug 1809861 - Part 1: Simplify and clean up off-main thread script compilation r...
[gecko.git] / dom / script / ScriptLoadContext.h
blob284422373cf18fa9f5f604c7d7edd92ee085d5cb
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_ScriptLoadContext_h
8 #define mozilla_dom_ScriptLoadContext_h
10 #include "js/AllocPolicy.h"
11 #include "js/RootingAPI.h"
12 #include "js/SourceText.h"
13 #include "js/TypeDecls.h"
14 #include "js/loader/LoadContextBase.h"
15 #include "js/loader/ScriptKind.h"
16 #include "mozilla/Atomics.h"
17 #include "mozilla/Assertions.h"
18 #include "mozilla/CORSMode.h"
19 #include "mozilla/dom/SRIMetadata.h"
20 #include "mozilla/LinkedList.h"
21 #include "mozilla/Maybe.h"
22 #include "mozilla/MaybeOneOf.h"
23 #include "mozilla/PreloaderBase.h"
24 #include "mozilla/StaticPrefs_dom.h"
25 #include "mozilla/Utf8.h" // mozilla::Utf8Unit
26 #include "mozilla/Variant.h"
27 #include "mozilla/Vector.h"
28 #include "nsCOMPtr.h"
29 #include "nsCycleCollectionParticipant.h"
30 #include "nsIScriptElement.h"
32 class nsICacheInfoChannel;
34 namespace JS {
35 class OffThreadToken;
36 } // namespace JS
38 namespace mozilla::dom {
40 class Element;
43 * DOM specific ScriptLoadContext.
45 * ScriptLoadContexts augment the loading of a ScriptLoadRequest. They
46 * describe how a ScriptLoadRequests loading and evaluation needs to be
47 * augmented, based on the information provided by the loading context. In
48 * the case of the DOM, the ScriptLoadContext is used to identify how a script
49 * should be loaded according to information found in the HTML document into
50 * which it will be loaded. The following fields describe how the
51 * ScriptLoadRequest will be loaded.
53 * * mScriptMode
54 * stores the mode (Async, Sync, Deferred), and preload, which
55 * allows the ScriptLoader to decide if the script should be pushed
56 * offThread, or if the preloaded request should be used.
57 * * mScriptFromHead
58 * Set when the script tag is in the head, and should be treated as
59 * a blocking script
60 * * mIsInline
61 * Set for scripts whose bodies are inline in the html. In this case,
62 * the script does not need to be fetched first.
63 * * mIsXSLT
64 * Set if we are in an XSLT request.
65 * * TODO: mIsPreload (will be moved from ScriptFetchOptions)
66 * Set for scripts that are preloaded in a
67 * <link rel="preload" as="script"> element.
69 * In addition to describing how the ScriptLoadRequest will be loaded by the
70 * DOM ScriptLoader, the ScriptLoadContext contains fields that facilitate
71 * those custom behaviors, including support for offthread parsing, pointers
72 * to runnables (for cancellation and cleanup if a script is parsed offthread)
73 * and preload element specific controls.
77 class ScriptLoadContext : public JS::loader::LoadContextBase,
78 public PreloaderBase {
79 protected:
80 virtual ~ScriptLoadContext();
82 public:
83 explicit ScriptLoadContext();
85 NS_DECL_ISUPPORTS_INHERITED
86 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ScriptLoadContext,
87 JS::loader::LoadContextBase)
89 // PreloaderBase
90 static void PrioritizeAsPreload(nsIChannel* aChannel);
91 virtual void PrioritizeAsPreload() override;
93 bool IsPreload() const;
95 bool CompileStarted() const;
97 JS::OffThreadToken** OffThreadTokenPtr() {
98 return mOffThreadToken ? &mOffThreadToken : nullptr;
101 bool IsTracking() const { return mIsTracking; }
102 void SetIsTracking() {
103 MOZ_ASSERT(!mIsTracking);
104 mIsTracking = true;
107 void BlockOnload(Document* aDocument);
109 void MaybeUnblockOnload();
111 enum class ScriptMode : uint8_t {
112 eBlocking,
113 eDeferred,
114 eAsync,
115 eLinkPreload // this is a load initiated by <link rel="preload"
116 // as="script"> tag
119 void SetScriptMode(bool aDeferAttr, bool aAsyncAttr, bool aLinkPreload);
121 bool IsLinkPreloadScript() const {
122 return mScriptMode == ScriptMode::eLinkPreload;
125 bool IsBlockingScript() const { return mScriptMode == ScriptMode::eBlocking; }
127 bool IsDeferredScript() const { return mScriptMode == ScriptMode::eDeferred; }
129 bool IsAsyncScript() const { return mScriptMode == ScriptMode::eAsync; }
131 nsIScriptElement* GetScriptElement() const;
133 // Make this request a preload (speculative) request.
134 void SetIsPreloadRequest() {
135 MOZ_ASSERT(!GetScriptElement());
136 MOZ_ASSERT(!IsPreload());
137 mIsPreload = true;
140 // Make a preload request into an actual load request for the given element.
141 void SetIsLoadRequest(nsIScriptElement* aElement);
143 FromParser GetParserCreated() const {
144 nsIScriptElement* element = GetScriptElement();
145 if (!element) {
146 return NOT_FROM_PARSER;
148 return element->GetParserCreated();
151 // Used to output a string for the Gecko Profiler.
152 void GetProfilerLabel(nsACString& aOutString) override;
154 void MaybeCancelOffThreadScript();
156 ScriptMode mScriptMode; // Whether this is a blocking, defer or async script.
157 bool mScriptFromHead; // Synchronous head script block loading of other non
158 // js/css content.
159 bool mIsInline; // Is the script inline or loaded?
160 bool mInDeferList; // True if we live in mDeferRequests.
161 bool mInAsyncList; // True if we live in mLoadingAsyncRequests or
162 // mLoadedAsyncRequests.
163 bool mIsNonAsyncScriptInserted; // True if we live in
164 // mNonAsyncExternalScriptInsertedRequests
165 bool mIsXSLT; // True if we live in mXSLTRequests.
166 bool mInCompilingList; // True if we are in mOffThreadCompilingRequests.
167 bool mIsTracking; // True if the script comes from a source on our
168 // tracking protection list.
169 bool mWasCompiledOMT; // True if the script has been compiled off main
170 // thread.
172 // Off-thread parsing token. Set at the start of off-thread parsing and
173 // cleared when the result of the parse is used.
174 JS::OffThreadToken* mOffThreadToken;
176 // Runnable that is dispatched to the main thread when off-thread compilation
177 // completes.
178 RefPtr<Runnable> mRunnable;
180 int32_t mLineNo;
182 // Set on scripts and top level modules.
183 bool mIsPreload;
185 // Non-null if there is a document that this request is blocking from loading.
186 RefPtr<Document> mLoadBlockedDocument;
188 // For preload requests, we defer reporting errors to the console until the
189 // request is used.
190 nsresult mUnreportedPreloadError;
193 } // namespace mozilla::dom
195 #endif // mozilla_dom_ScriptLoadContext_h