Bug 1835710 - Cancel off-thread JIT compilation before changing nursery allocation...
[gecko.git] / dom / base / nsJSEnvironment.h
blob41e7123a62f7e20b604067a37d714f77f833cd9d
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/. */
6 #ifndef nsJSEnvironment_h
7 #define nsJSEnvironment_h
9 #include "nsIScriptContext.h"
10 #include "nsIScriptGlobalObject.h"
11 #include "nsCOMPtr.h"
12 #include "prtime.h"
13 #include "nsCycleCollectionParticipant.h"
14 #include "nsIArray.h"
15 #include "mozilla/Attributes.h"
16 #include "mozilla/TimeStamp.h"
17 #include "nsThreadUtils.h"
18 #include "xpcpublic.h"
20 class nsICycleCollectorListener;
21 class nsIDocShell;
23 namespace mozilla {
25 template <class>
26 class Maybe;
27 struct CycleCollectorResults;
29 static const uint32_t kMajorForgetSkippableCalls = 5;
31 } // namespace mozilla
33 class nsJSContext : public nsIScriptContext {
34 public:
35 nsJSContext(bool aGCOnDestruction, nsIScriptGlobalObject* aGlobalObject);
37 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
38 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSContext,
39 nsIScriptContext)
41 virtual nsIScriptGlobalObject* GetGlobalObject() override;
42 inline nsIScriptGlobalObject* GetGlobalObjectRef() {
43 return mGlobalObjectRef;
46 virtual nsresult SetProperty(JS::Handle<JSObject*> aTarget,
47 const char* aPropName,
48 nsISupports* aVal) override;
50 virtual bool GetProcessingScriptTag() override;
51 virtual void SetProcessingScriptTag(bool aResult) override;
53 virtual nsresult InitClasses(JS::Handle<JSObject*> aGlobalObj) override;
55 virtual void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) override;
56 virtual JSObject* GetWindowProxy() override;
58 enum IsShrinking { ShrinkingGC, NonShrinkingGC };
60 // Setup all the statics etc - safe to call multiple times after Startup().
61 static void EnsureStatics();
63 static void SetLowMemoryState(bool aState);
65 static void GarbageCollectNow(JS::GCReason reason,
66 IsShrinking aShrinking = NonShrinkingGC);
68 static void RunIncrementalGCSlice(JS::GCReason aReason,
69 IsShrinking aShrinking,
70 js::SliceBudget& aBudget);
72 static void CycleCollectNow(mozilla::CCReason aReason,
73 nsICycleCollectorListener* aListener = nullptr);
75 // Finish up any in-progress incremental GC.
76 static void PrepareForCycleCollectionSlice(mozilla::CCReason aReason,
77 mozilla::TimeStamp aDeadline);
79 // Run a cycle collector slice, using a heuristic to decide how long to run
80 // it.
81 static void RunCycleCollectorSlice(mozilla::CCReason aReason,
82 mozilla::TimeStamp aDeadline);
84 // Run a cycle collector slice, using the given work budget.
85 static void RunCycleCollectorWorkSlice(int64_t aWorkBudget);
87 static void BeginCycleCollectionCallback(mozilla::CCReason aReason);
88 static void EndCycleCollectionCallback(
89 const mozilla::CycleCollectorResults& aResults);
91 // Return the longest CC slice time since ClearMaxCCSliceTime() was last
92 // called.
93 static uint32_t GetMaxCCSliceTimeSinceClear();
94 static void ClearMaxCCSliceTime();
96 // If there is some pending CC or GC timer/runner, this will run it.
97 static void RunNextCollectorTimer(
98 JS::GCReason aReason,
99 mozilla::TimeStamp aDeadline = mozilla::TimeStamp());
100 // If user has been idle and aDocShell is for an iframe being loaded in an
101 // already loaded top level docshell, this will run a CC or GC
102 // timer/runner if there is such pending.
103 static void MaybeRunNextCollectorSlice(nsIDocShell* aDocShell,
104 JS::GCReason aReason);
106 // The GC should run soon, in the zone of aObj if given. If aObj is
107 // nullptr, collect all Zones.
108 static void PokeGC(JS::GCReason aReason, JSObject* aObj,
109 mozilla::TimeDuration aDelay = 0);
111 // If usage is nearing a threshold, request idle-only GC work. (This is called
112 // when a collection would be relatively convenient.)
113 static void MaybePokeGC();
115 // Immediately perform a non-incremental shrinking GC and CC.
116 static void DoLowMemoryGC();
118 // Perform a non-incremental shrinking GC and CC according to
119 // IdleScheduler.
120 static void LowMemoryGC();
122 static void MaybePokeCC();
124 // Calling LikelyShortLivingObjectCreated() makes a GC more likely.
125 static void LikelyShortLivingObjectCreated();
127 static bool HasHadCleanupSinceLastGC();
129 nsIScriptGlobalObject* GetCachedGlobalObject() {
130 // Verify that we have a global so that this
131 // does always return a null when GetGlobalObject() is null.
132 JSObject* global = GetWindowProxy();
133 return global ? mGlobalObjectRef.get() : nullptr;
136 protected:
137 virtual ~nsJSContext();
139 // Helper to convert xpcom datatypes to jsvals.
140 nsresult ConvertSupportsTojsvals(JSContext* aCx, nsISupports* aArgs,
141 JS::Handle<JSObject*> aScope,
142 JS::MutableHandleVector<JS::Value> aArgsOut);
144 nsresult AddSupportsPrimitiveTojsvals(JSContext* aCx, nsISupports* aArg,
145 JS::Value* aArgv);
147 private:
148 void Destroy();
150 JS::Heap<JSObject*> mWindowProxy;
152 bool mGCOnDestruction;
153 bool mProcessingScriptTag;
155 // mGlobalObjectRef ensures that the outer window stays alive as long as the
156 // context does. It is eventually collected by the cycle collector.
157 nsCOMPtr<nsIScriptGlobalObject> mGlobalObjectRef;
159 static bool DOMOperationCallback(JSContext* cx);
162 namespace mozilla::dom {
164 class SerializedStackHolder;
166 void StartupJSEnvironment();
167 void ShutdownJSEnvironment();
169 // Runnable that's used to do async error reporting
170 class AsyncErrorReporter final : public mozilla::Runnable {
171 public:
172 explicit AsyncErrorReporter(xpc::ErrorReport* aReport);
173 // SerializeStack is suitable for main or worklet thread use.
174 // Stacks from worker threads are not supported.
175 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1578968
176 void SerializeStack(JSContext* aCx, JS::Handle<JSObject*> aStack);
178 // Set the exception value associated with this error report.
179 // Should only be called from the main thread.
180 void SetException(JSContext* aCx, JS::Handle<JS::Value> aException);
182 protected:
183 NS_IMETHOD Run() override;
185 // This is only used on main thread!
186 JS::PersistentRooted<JS::Value> mException;
187 bool mHasException = false;
189 RefPtr<xpc::ErrorReport> mReport;
190 // This may be used to marshal a stack from an arbitrary thread/runtime into
191 // the main thread/runtime where the console service runs.
192 UniquePtr<SerializedStackHolder> mStackHolder;
195 } // namespace mozilla::dom
197 // An interface for fast and native conversion to/from nsIArray. If an object
198 // supports this interface, JS can reach directly in for the argv, and avoid
199 // nsISupports conversion. If this interface is not supported, the object will
200 // be queried for nsIArray, and everything converted via xpcom objects.
201 #define NS_IJSARGARRAY_IID \
203 0xb6acdac8, 0xf5c6, 0x432c, { \
204 0xa8, 0x6e, 0x33, 0xee, 0xb1, 0xb0, 0xcd, 0xdc \
208 class nsIJSArgArray : public nsIArray {
209 public:
210 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSARGARRAY_IID)
211 // Bug 312003 describes why this must be "void **", but after calling argv
212 // may be cast to JS::Value* and the args found at:
213 // ((JS::Value*)argv)[0], ..., ((JS::Value*)argv)[argc - 1]
214 virtual nsresult GetArgs(uint32_t* argc, void** argv) = 0;
217 NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSArgArray, NS_IJSARGARRAY_IID)
219 #endif /* nsJSEnvironment_h */