Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/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
0
#define NS_GC_DELAY                 4000 // ms
33
34
1
#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
  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
  {
126
    // Verify that we have a global so that this
127
    // does always return a null when GetGlobalObject() is null.
128
    JSObject* global = GetWindowProxy();
129
    return global ? mGlobalObjectRef.get() : nullptr;
130
  }
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
0
  {}
173
174
  NS_IMETHOD Run() override
175
0
  {
176
0
    mReport->LogToConsole();
177
0
    return NS_OK;
178
0
  }
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 */