tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsJSEnvironment.h (7681B)


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