/work/obj-fuzz/dist/include/nsJSEnvironment.h
Line | Count | Source (jump to first uncovered line) |
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 |
8 | | |
9 | | #include "nsIScriptContext.h" |
10 | | #include "nsIScriptGlobalObject.h" |
11 | | #include "nsCOMPtr.h" |
12 | | #include "nsIObserver.h" |
13 | | #include "prtime.h" |
14 | | #include "nsCycleCollectionParticipant.h" |
15 | | #include "nsIXPConnect.h" |
16 | | #include "nsIArray.h" |
17 | | #include "mozilla/Attributes.h" |
18 | | #include "mozilla/TimeStamp.h" |
19 | | #include "nsThreadUtils.h" |
20 | | #include "xpcpublic.h" |
21 | | |
22 | | class nsICycleCollectorListener; |
23 | | class nsIDocShell; |
24 | | |
25 | | namespace mozilla { |
26 | | template <class> class Maybe; |
27 | | struct CycleCollectorResults; |
28 | | } // namespace mozilla |
29 | | |
30 | | // The amount of time we wait between a request to GC (due to leaving |
31 | | // a page) and doing the actual GC. |
32 | | #define NS_GC_DELAY 4000 // ms |
33 | | |
34 | | #define NS_MAJOR_FORGET_SKIPPABLE_CALLS 5 |
35 | | |
36 | | class nsJSContext : public nsIScriptContext |
37 | | { |
38 | | public: |
39 | | nsJSContext(bool aGCOnDestruction, nsIScriptGlobalObject* aGlobalObject); |
40 | | |
41 | | NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
42 | | NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSContext, |
43 | | nsIScriptContext) |
44 | | |
45 | | virtual nsIScriptGlobalObject *GetGlobalObject() override; |
46 | 0 | inline nsIScriptGlobalObject *GetGlobalObjectRef() { return mGlobalObjectRef; } |
47 | | |
48 | | virtual nsresult InitContext() override; |
49 | | virtual bool IsContextInitialized() override; |
50 | | |
51 | | virtual nsresult SetProperty(JS::Handle<JSObject*> aTarget, const char* aPropName, nsISupports* aVal) override; |
52 | | |
53 | | virtual bool GetProcessingScriptTag() override; |
54 | | virtual void SetProcessingScriptTag(bool aResult) override; |
55 | | |
56 | | virtual nsresult InitClasses(JS::Handle<JSObject*> aGlobalObj) override; |
57 | | |
58 | | virtual void WillInitializeContext() override; |
59 | | virtual void DidInitializeContext() override; |
60 | | |
61 | | virtual void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) override; |
62 | | virtual JSObject* GetWindowProxy() override; |
63 | | |
64 | | enum IsShrinking { |
65 | | ShrinkingGC, |
66 | | NonShrinkingGC |
67 | | }; |
68 | | |
69 | | enum IsIncremental { |
70 | | IncrementalGC, |
71 | | NonIncrementalGC |
72 | | }; |
73 | | |
74 | | // Setup all the statics etc - safe to call multiple times after Startup(). |
75 | | static void EnsureStatics(); |
76 | | |
77 | | static void GarbageCollectNow(JS::gcreason::Reason reason, |
78 | | IsIncremental aIncremental = NonIncrementalGC, |
79 | | IsShrinking aShrinking = NonShrinkingGC, |
80 | | int64_t aSliceMillis = 0); |
81 | | |
82 | | static void CycleCollectNow(nsICycleCollectorListener *aListener = nullptr); |
83 | | |
84 | | // Run a cycle collector slice, using a heuristic to decide how long to run it. |
85 | | static void RunCycleCollectorSlice(mozilla::TimeStamp aDeadline); |
86 | | |
87 | | // Run a cycle collector slice, using the given work budget. |
88 | | static void RunCycleCollectorWorkSlice(int64_t aWorkBudget); |
89 | | |
90 | | static void BeginCycleCollectionCallback(); |
91 | | static void EndCycleCollectionCallback(mozilla::CycleCollectorResults &aResults); |
92 | | |
93 | | // Return the longest CC slice time since ClearMaxCCSliceTime() was last called. |
94 | | static uint32_t GetMaxCCSliceTimeSinceClear(); |
95 | | static void ClearMaxCCSliceTime(); |
96 | | |
97 | | // If there is some pending CC or GC timer/runner, this will run it. |
98 | | static void RunNextCollectorTimer(JS::gcreason::Reason 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::Reason aReason); |
105 | | |
106 | | // The GC should probably run soon, in the zone of object aObj (if given). |
107 | | static void PokeGC(JS::gcreason::Reason aReason, JSObject* aObj, int aDelay = 0); |
108 | | static void KillGCTimer(); |
109 | | |
110 | | static void PokeShrinkingGC(); |
111 | | static void KillShrinkingGCTimer(); |
112 | | |
113 | | static void MaybePokeCC(); |
114 | | static void KillCCRunner(); |
115 | | static void KillICCRunner(); |
116 | | static void KillFullGCTimer(); |
117 | | static void KillInterSliceGCRunner(); |
118 | | |
119 | | // Calling LikelyShortLivingObjectCreated() makes a GC more likely. |
120 | | static void LikelyShortLivingObjectCreated(); |
121 | | |
122 | | static uint32_t CleanupsSinceLastGC(); |
123 | | |
124 | | nsIScriptGlobalObject* GetCachedGlobalObject() |
125 | 0 | { |
126 | 0 | // Verify that we have a global so that this |
127 | 0 | // does always return a null when GetGlobalObject() is null. |
128 | 0 | JSObject* global = GetWindowProxy(); |
129 | 0 | return global ? mGlobalObjectRef.get() : nullptr; |
130 | 0 | } |
131 | | |
132 | | protected: |
133 | | virtual ~nsJSContext(); |
134 | | |
135 | | // Helper to convert xpcom datatypes to jsvals. |
136 | | nsresult ConvertSupportsTojsvals(nsISupports *aArgs, |
137 | | JS::Handle<JSObject*> aScope, |
138 | | JS::AutoValueVector &aArgsOut); |
139 | | |
140 | | nsresult AddSupportsPrimitiveTojsvals(nsISupports *aArg, JS::Value *aArgv); |
141 | | |
142 | | private: |
143 | | void Destroy(); |
144 | | |
145 | | JS::Heap<JSObject*> mWindowProxy; |
146 | | |
147 | | bool mIsInitialized; |
148 | | bool mGCOnDestruction; |
149 | | bool mProcessingScriptTag; |
150 | | |
151 | | // mGlobalObjectRef ensures that the outer window stays alive as long as the |
152 | | // context does. It is eventually collected by the cycle collector. |
153 | | nsCOMPtr<nsIScriptGlobalObject> mGlobalObjectRef; |
154 | | |
155 | | static bool DOMOperationCallback(JSContext *cx); |
156 | | }; |
157 | | |
158 | | namespace mozilla { |
159 | | namespace dom { |
160 | | |
161 | | void StartupJSEnvironment(); |
162 | | void ShutdownJSEnvironment(); |
163 | | |
164 | | // Runnable that's used to do async error reporting |
165 | | class AsyncErrorReporter final : public mozilla::Runnable |
166 | | { |
167 | | public: |
168 | | // aWindow may be null if this error report is not associated with a window |
169 | | explicit AsyncErrorReporter(xpc::ErrorReport* aReport) |
170 | | : Runnable("dom::AsyncErrorReporter") |
171 | | , mReport(aReport) |
172 | | {} |
173 | | |
174 | | NS_IMETHOD Run() override |
175 | | { |
176 | | mReport->LogToConsole(); |
177 | | return NS_OK; |
178 | | } |
179 | | |
180 | | protected: |
181 | | RefPtr<xpc::ErrorReport> mReport; |
182 | | }; |
183 | | |
184 | | } // namespace dom |
185 | | } // namespace mozilla |
186 | | |
187 | | // An interface for fast and native conversion to/from nsIArray. If an object |
188 | | // supports this interface, JS can reach directly in for the argv, and avoid |
189 | | // nsISupports conversion. If this interface is not supported, the object will |
190 | | // be queried for nsIArray, and everything converted via xpcom objects. |
191 | | #define NS_IJSARGARRAY_IID \ |
192 | | { 0xb6acdac8, 0xf5c6, 0x432c, \ |
193 | | { 0xa8, 0x6e, 0x33, 0xee, 0xb1, 0xb0, 0xcd, 0xdc } } |
194 | | |
195 | | class nsIJSArgArray : public nsIArray |
196 | | { |
197 | | public: |
198 | | NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSARGARRAY_IID) |
199 | | // Bug 312003 describes why this must be "void **", but after calling argv |
200 | | // may be cast to JS::Value* and the args found at: |
201 | | // ((JS::Value*)argv)[0], ..., ((JS::Value*)argv)[argc - 1] |
202 | | virtual nsresult GetArgs(uint32_t *argc, void **argv) = 0; |
203 | | }; |
204 | | |
205 | | NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSArgArray, NS_IJSARGARRAY_IID) |
206 | | |
207 | | #endif /* nsJSEnvironment_h */ |