1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef nsJSEnvironment_h
6 #define nsJSEnvironment_h
8 #include "nsIScriptContext.h"
9 #include "nsIScriptGlobalObject.h"
11 #include "nsIObserver.h"
13 #include "nsCycleCollectionParticipant.h"
14 #include "nsIXPConnect.h"
16 #include "mozilla/Attributes.h"
17 #include "nsPIDOMWindow.h"
18 #include "nsThreadUtils.h"
19 #include "xpcpublic.h"
21 class nsICycleCollectorListener
;
22 class nsIXPConnectJSObjectHolder
;
23 class nsScriptNameSpaceManager
;
24 class nsCycleCollectionNoteRootCallback
;
27 class AutoValueVector
;
31 template <class> class Maybe
;
32 struct CycleCollectorResults
;
35 // The amount of time we wait between a request to GC (due to leaving
36 // a page) and doing the actual GC.
37 #define NS_GC_DELAY 4000 // ms
39 #define NS_MAJOR_FORGET_SKIPPABLE_CALLS 5
41 class nsJSContext
: public nsIScriptContext
44 nsJSContext(bool aGCOnDestruction
, nsIScriptGlobalObject
* aGlobalObject
);
46 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
47 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSContext
,
50 virtual nsIScriptGlobalObject
*GetGlobalObject() MOZ_OVERRIDE
;
51 inline nsIScriptGlobalObject
*GetGlobalObjectRef() { return mGlobalObjectRef
; }
53 virtual JSContext
* GetNativeContext() MOZ_OVERRIDE
;
54 virtual nsresult
InitContext() MOZ_OVERRIDE
;
55 virtual bool IsContextInitialized() MOZ_OVERRIDE
;
57 virtual nsresult
SetProperty(JS::Handle
<JSObject
*> aTarget
, const char* aPropName
, nsISupports
* aVal
) MOZ_OVERRIDE
;
59 virtual bool GetProcessingScriptTag() MOZ_OVERRIDE
;
60 virtual void SetProcessingScriptTag(bool aResult
) MOZ_OVERRIDE
;
62 virtual nsresult
InitClasses(JS::Handle
<JSObject
*> aGlobalObj
) MOZ_OVERRIDE
;
64 virtual void WillInitializeContext() MOZ_OVERRIDE
;
65 virtual void DidInitializeContext() MOZ_OVERRIDE
;
67 virtual void SetWindowProxy(JS::Handle
<JSObject
*> aWindowProxy
) MOZ_OVERRIDE
;
68 virtual JSObject
* GetWindowProxy() MOZ_OVERRIDE
;
69 virtual JSObject
* GetWindowProxyPreserveColor() MOZ_OVERRIDE
;
71 static void LoadStart();
72 static void LoadEnd();
84 // Setup all the statics etc - safe to call multiple times after Startup().
87 static void GarbageCollectNow(JS::gcreason::Reason reason
,
88 IsIncremental aIncremental
= NonIncrementalGC
,
89 IsShrinking aShrinking
= NonShrinkingGC
,
90 int64_t aSliceMillis
= 0);
91 static void ShrinkGCBuffersNow();
93 // If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
94 // called even if the previous collection was GC.
95 static void CycleCollectNow(nsICycleCollectorListener
*aListener
= nullptr,
96 int32_t aExtraForgetSkippableCalls
= 0);
98 // Run a cycle collector slice, using a heuristic to decide how long to run it.
99 static void RunCycleCollectorSlice();
101 // Run a cycle collector slice, using the given work budget.
102 static void RunCycleCollectorWorkSlice(int64_t aWorkBudget
);
104 static void BeginCycleCollectionCallback();
105 static void EndCycleCollectionCallback(mozilla::CycleCollectorResults
&aResults
);
107 // Return the longest CC slice time since ClearMaxCCSliceTime() was last called.
108 static uint32_t GetMaxCCSliceTimeSinceClear();
109 static void ClearMaxCCSliceTime();
111 static void RunNextCollectorTimer();
113 static void PokeGC(JS::gcreason::Reason aReason
, int aDelay
= 0);
114 static void KillGCTimer();
116 static void PokeShrinkGCBuffers();
117 static void KillShrinkGCBuffersTimer();
119 static void MaybePokeCC();
120 static void KillCCTimer();
121 static void KillICCTimer();
122 static void KillFullGCTimer();
123 static void KillInterSliceGCTimer();
125 // Calling LikelyShortLivingObjectCreated() makes a GC more likely.
126 static void LikelyShortLivingObjectCreated();
128 static uint32_t CleanupsSinceLastGC();
130 nsIScriptGlobalObject
* GetCachedGlobalObject()
132 // Verify that we have a global so that this
133 // does always return a null when GetGlobalObject() is null.
134 JSObject
* global
= GetWindowProxy();
135 return global
? mGlobalObjectRef
.get() : nullptr;
138 static void NotifyDidPaint();
140 virtual ~nsJSContext();
142 // Helper to convert xpcom datatypes to jsvals.
143 nsresult
ConvertSupportsTojsvals(nsISupports
*aArgs
,
144 JS::Handle
<JSObject
*> aScope
,
145 JS::AutoValueVector
&aArgsOut
);
147 nsresult
AddSupportsPrimitiveTojsvals(nsISupports
*aArg
, JS::Value
*aArgv
);
150 void DestroyJSContext();
152 nsrefcnt
GetCCRefcnt();
155 JS::Heap
<JSObject
*> mWindowProxy
;
158 bool mGCOnDestruction
;
159 bool mProcessingScriptTag
;
161 PRTime mModalStateTime
;
162 uint32_t mModalStateDepth
;
164 // mGlobalObjectRef ensures that the outer window stays alive as long as the
165 // context does. It is eventually collected by the cycle collector.
166 nsCOMPtr
<nsIScriptGlobalObject
> mGlobalObjectRef
;
168 static void JSOptionChangedCallback(const char *pref
, void *data
);
170 static bool DOMOperationCallback(JSContext
*cx
);
173 class nsIJSRuntimeService
;
180 void StartupJSEnvironment();
181 void ShutdownJSEnvironment();
183 // Get the NameSpaceManager, creating if necessary
184 nsScriptNameSpaceManager
* GetNameSpaceManager();
186 // Runnable that's used to do async error reporting
187 class AsyncErrorReporter
: public nsRunnable
190 // aWindow may be null if this error report is not associated with a window
191 AsyncErrorReporter(JSRuntime
* aRuntime
, xpc::ErrorReport
* aReport
)
197 mReport
->LogToConsole();
202 nsRefPtr
<xpc::ErrorReport
> mReport
;
206 } // namespace mozilla
208 // An interface for fast and native conversion to/from nsIArray. If an object
209 // supports this interface, JS can reach directly in for the argv, and avoid
210 // nsISupports conversion. If this interface is not supported, the object will
211 // be queried for nsIArray, and everything converted via xpcom objects.
212 #define NS_IJSARGARRAY_IID \
213 { 0xb6acdac8, 0xf5c6, 0x432c, \
214 { 0xa8, 0x6e, 0x33, 0xee, 0xb1, 0xb0, 0xcd, 0xdc } }
216 class nsIJSArgArray
: public nsIArray
219 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSARGARRAY_IID
)
220 // Bug 312003 describes why this must be "void **", but after calling argv
221 // may be cast to JS::Value* and the args found at:
222 // ((JS::Value*)argv)[0], ..., ((JS::Value*)argv)[argc - 1]
223 virtual nsresult
GetArgs(uint32_t *argc
, void **argv
) = 0;
226 NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSArgArray
, NS_IJSARGARRAY_IID
)
228 JSObject
* NS_DOMReadStructuredClone(JSContext
* cx
,
229 JSStructuredCloneReader
* reader
, uint32_t tag
,
230 uint32_t data
, void* closure
);
232 bool NS_DOMWriteStructuredClone(JSContext
* cx
,
233 JSStructuredCloneWriter
* writer
,
234 JS::Handle
<JSObject
*> obj
, void *closure
);
236 void NS_DOMStructuredCloneError(JSContext
* cx
, uint32_t errorid
);
238 #endif /* nsJSEnvironment_h */